blob: 35f22a936857c7420b5f07dcfe1768bd8ca295b9 [file] [log] [blame]
Andrew Lunn5f857572019-01-21 19:10:19 +01001// SPDX-License-Identifier: GPL-2.0
Russell King9525ae82017-07-25 15:03:13 +01002/*
3 * phylink models the MAC to optional PHY connection, supporting
4 * technologies such as SFP cages where the PHY is hot-pluggable.
5 *
6 * Copyright (C) 2015 Russell King
Russell King9525ae82017-07-25 15:03:13 +01007 */
Calvin Johnson25396f62021-06-11 13:53:59 +03008#include <linux/acpi.h>
Russell King9525ae82017-07-25 15:03:13 +01009#include <linux/ethtool.h>
10#include <linux/export.h>
11#include <linux/gpio/consumer.h>
12#include <linux/netdevice.h>
13#include <linux/of.h>
14#include <linux/of_mdio.h>
15#include <linux/phy.h>
16#include <linux/phy_fixed.h>
17#include <linux/phylink.h>
18#include <linux/rtnetlink.h>
19#include <linux/spinlock.h>
Russell King9cd00a82018-05-10 13:17:31 -070020#include <linux/timer.h>
Russell King9525ae82017-07-25 15:03:13 +010021#include <linux/workqueue.h>
22
Russell Kingce0aa272017-07-25 15:03:18 +010023#include "sfp.h"
Russell King9525ae82017-07-25 15:03:13 +010024#include "swphy.h"
25
26#define SUPPORTED_INTERFACES \
27 (SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_FIBRE | \
28 SUPPORTED_BNC | SUPPORTED_AUI | SUPPORTED_Backplane)
29#define ADVERTISED_INTERFACES \
30 (ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \
31 ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane)
32
33enum {
34 PHYLINK_DISABLE_STOPPED,
Russell Kingce0aa272017-07-25 15:03:18 +010035 PHYLINK_DISABLE_LINK,
Russell King9525ae82017-07-25 15:03:13 +010036};
37
Russell King8796c892017-12-01 10:24:47 +000038/**
39 * struct phylink - internal data type for phylink
40 */
Russell King9525ae82017-07-25 15:03:13 +010041struct phylink {
Russell King8796c892017-12-01 10:24:47 +000042 /* private: */
Russell King9525ae82017-07-25 15:03:13 +010043 struct net_device *netdev;
Russell Kinge7765d62020-03-30 18:44:50 +010044 const struct phylink_mac_ops *mac_ops;
Russell King4c0d6d32020-03-30 18:44:55 +010045 const struct phylink_pcs_ops *pcs_ops;
Ioana Ciornei44cc27e2019-05-28 20:38:12 +030046 struct phylink_config *config;
Russell King7137e182020-07-21 12:04:46 +010047 struct phylink_pcs *pcs;
Ioana Ciornei43de6192019-05-28 20:38:13 +030048 struct device *dev;
49 unsigned int old_link_state:1;
Russell King9525ae82017-07-25 15:03:13 +010050
51 unsigned long phylink_disable_state; /* bitmask of disables */
52 struct phy_device *phydev;
53 phy_interface_t link_interface; /* PHY_INTERFACE_xxx */
Russell King24cf0e62019-12-11 10:56:35 +000054 u8 cfg_link_an_mode; /* MLO_AN_xxx */
55 u8 cur_link_an_mode;
Russell King9525ae82017-07-25 15:03:13 +010056 u8 link_port; /* The current non-phy ethtool port */
57 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
58
59 /* The link configuration settings */
60 struct phylink_link_state link_config;
Russell Kingc6787262019-05-28 10:27:21 +010061
62 /* The current settings */
63 phy_interface_t cur_interface;
64
Russell King9525ae82017-07-25 15:03:13 +010065 struct gpio_desc *link_gpio;
Russell King7b3b0e82019-05-28 10:57:23 +010066 unsigned int link_irq;
Russell King9cd00a82018-05-10 13:17:31 -070067 struct timer_list link_poll;
Florian Fainelli1ac63e32017-12-12 16:00:28 -080068 void (*get_fixed_state)(struct net_device *dev,
69 struct phylink_link_state *s);
Russell King9525ae82017-07-25 15:03:13 +010070
71 struct mutex state_mutex;
72 struct phylink_link_state phy_state;
73 struct work_struct resolve;
74
75 bool mac_link_dropped;
Russell Kingce0aa272017-07-25 15:03:18 +010076
77 struct sfp_bus *sfp_bus;
Russell King52c95602019-12-11 10:56:45 +000078 bool sfp_may_have_phy;
79 __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
80 u8 sfp_port;
Russell King9525ae82017-07-25 15:03:13 +010081};
82
Ioana Ciornei170911802019-05-28 20:38:14 +030083#define phylink_printk(level, pl, fmt, ...) \
84 do { \
85 if ((pl)->config->type == PHYLINK_NETDEV) \
86 netdev_printk(level, (pl)->netdev, fmt, ##__VA_ARGS__); \
87 else if ((pl)->config->type == PHYLINK_DEV) \
88 dev_printk(level, (pl)->dev, fmt, ##__VA_ARGS__); \
89 } while (0)
90
91#define phylink_err(pl, fmt, ...) \
92 phylink_printk(KERN_ERR, pl, fmt, ##__VA_ARGS__)
93#define phylink_warn(pl, fmt, ...) \
94 phylink_printk(KERN_WARNING, pl, fmt, ##__VA_ARGS__)
95#define phylink_info(pl, fmt, ...) \
96 phylink_printk(KERN_INFO, pl, fmt, ##__VA_ARGS__)
Florian Fainelli9d68db52019-10-31 15:42:26 -070097#if defined(CONFIG_DYNAMIC_DEBUG)
Ioana Ciornei170911802019-05-28 20:38:14 +030098#define phylink_dbg(pl, fmt, ...) \
Florian Fainelli9d68db52019-10-31 15:42:26 -070099do { \
100 if ((pl)->config->type == PHYLINK_NETDEV) \
101 netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \
102 else if ((pl)->config->type == PHYLINK_DEV) \
103 dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \
104} while (0)
105#elif defined(DEBUG)
106#define phylink_dbg(pl, fmt, ...) \
Ioana Ciornei170911802019-05-28 20:38:14 +0300107 phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__)
Florian Fainelli9d68db52019-10-31 15:42:26 -0700108#else
109#define phylink_dbg(pl, fmt, ...) \
110({ \
111 if (0) \
112 phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__); \
113})
114#endif
Ioana Ciornei170911802019-05-28 20:38:14 +0300115
Russell King8796c892017-12-01 10:24:47 +0000116/**
117 * phylink_set_port_modes() - set the port type modes in the ethtool mask
118 * @mask: ethtool link mode mask
119 *
120 * Sets all the port type modes in the ethtool mask. MAC drivers should
121 * use this in their 'validate' callback.
122 */
Russell King9525ae82017-07-25 15:03:13 +0100123void phylink_set_port_modes(unsigned long *mask)
124{
125 phylink_set(mask, TP);
126 phylink_set(mask, AUI);
127 phylink_set(mask, MII);
128 phylink_set(mask, FIBRE);
129 phylink_set(mask, BNC);
130 phylink_set(mask, Backplane);
131}
132EXPORT_SYMBOL_GPL(phylink_set_port_modes);
133
134static int phylink_is_empty_linkmode(const unsigned long *linkmode)
135{
136 __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp) = { 0, };
137
138 phylink_set_port_modes(tmp);
139 phylink_set(tmp, Autoneg);
140 phylink_set(tmp, Pause);
141 phylink_set(tmp, Asym_Pause);
142
Russell King554032c2019-10-15 11:28:46 +0100143 return linkmode_subset(linkmode, tmp);
Russell King9525ae82017-07-25 15:03:13 +0100144}
145
146static const char *phylink_an_mode_str(unsigned int mode)
147{
148 static const char *modestr[] = {
149 [MLO_AN_PHY] = "phy",
150 [MLO_AN_FIXED] = "fixed",
Russell King86a362c2017-12-01 10:24:26 +0000151 [MLO_AN_INBAND] = "inband",
Russell King9525ae82017-07-25 15:03:13 +0100152 };
153
154 return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
155}
156
157static int phylink_validate(struct phylink *pl, unsigned long *supported,
158 struct phylink_link_state *state)
159{
Russell Kinge7765d62020-03-30 18:44:50 +0100160 pl->mac_ops->validate(pl->config, supported, state);
Russell King9525ae82017-07-25 15:03:13 +0100161
162 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
163}
164
Russell King8fa7b9b2017-12-01 10:25:09 +0000165static int phylink_parse_fixedlink(struct phylink *pl,
166 struct fwnode_handle *fwnode)
Russell King9525ae82017-07-25 15:03:13 +0100167{
Russell King8fa7b9b2017-12-01 10:25:09 +0000168 struct fwnode_handle *fixed_node;
Russell King9525ae82017-07-25 15:03:13 +0100169 const struct phy_setting *s;
170 struct gpio_desc *desc;
Russell King9525ae82017-07-25 15:03:13 +0100171 u32 speed;
Russell King8fa7b9b2017-12-01 10:25:09 +0000172 int ret;
Russell King9525ae82017-07-25 15:03:13 +0100173
Russell King8fa7b9b2017-12-01 10:25:09 +0000174 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
Russell King9525ae82017-07-25 15:03:13 +0100175 if (fixed_node) {
Russell King8fa7b9b2017-12-01 10:25:09 +0000176 ret = fwnode_property_read_u32(fixed_node, "speed", &speed);
Russell King9525ae82017-07-25 15:03:13 +0100177
178 pl->link_config.speed = speed;
179 pl->link_config.duplex = DUPLEX_HALF;
180
Russell King8fa7b9b2017-12-01 10:25:09 +0000181 if (fwnode_property_read_bool(fixed_node, "full-duplex"))
Russell King9525ae82017-07-25 15:03:13 +0100182 pl->link_config.duplex = DUPLEX_FULL;
183
184 /* We treat the "pause" and "asym-pause" terminology as
Wenpeng Liang1953feb2021-06-16 18:01:20 +0800185 * defining the link partner's ability.
186 */
Russell King8fa7b9b2017-12-01 10:25:09 +0000187 if (fwnode_property_read_bool(fixed_node, "pause"))
Russell King4e5aeb42020-02-15 15:49:53 +0000188 __set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
189 pl->link_config.lp_advertising);
Russell King8fa7b9b2017-12-01 10:25:09 +0000190 if (fwnode_property_read_bool(fixed_node, "asym-pause"))
Russell King4e5aeb42020-02-15 15:49:53 +0000191 __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
192 pl->link_config.lp_advertising);
Russell King9525ae82017-07-25 15:03:13 +0100193
194 if (ret == 0) {
Dmitry Torokhovb605c9a2020-01-02 17:03:18 -0800195 desc = fwnode_gpiod_get_index(fixed_node, "link", 0,
196 GPIOD_IN, "?");
Russell King9525ae82017-07-25 15:03:13 +0100197
198 if (!IS_ERR(desc))
199 pl->link_gpio = desc;
200 else if (desc == ERR_PTR(-EPROBE_DEFER))
201 ret = -EPROBE_DEFER;
202 }
Russell King8fa7b9b2017-12-01 10:25:09 +0000203 fwnode_handle_put(fixed_node);
Russell King9525ae82017-07-25 15:03:13 +0100204
205 if (ret)
206 return ret;
207 } else {
Russell King8fa7b9b2017-12-01 10:25:09 +0000208 u32 prop[5];
209
210 ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
211 NULL, 0);
212 if (ret != ARRAY_SIZE(prop)) {
Ioana Ciornei170911802019-05-28 20:38:14 +0300213 phylink_err(pl, "broken fixed-link?\n");
Russell King9525ae82017-07-25 15:03:13 +0100214 return -EINVAL;
215 }
Russell King8fa7b9b2017-12-01 10:25:09 +0000216
217 ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
218 prop, ARRAY_SIZE(prop));
219 if (!ret) {
220 pl->link_config.duplex = prop[1] ?
Russell King9525ae82017-07-25 15:03:13 +0100221 DUPLEX_FULL : DUPLEX_HALF;
Russell King8fa7b9b2017-12-01 10:25:09 +0000222 pl->link_config.speed = prop[2];
223 if (prop[3])
Russell King4e5aeb42020-02-15 15:49:53 +0000224 __set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
225 pl->link_config.lp_advertising);
Russell King8fa7b9b2017-12-01 10:25:09 +0000226 if (prop[4])
Russell King4e5aeb42020-02-15 15:49:53 +0000227 __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
228 pl->link_config.lp_advertising);
Russell King9525ae82017-07-25 15:03:13 +0100229 }
230 }
231
232 if (pl->link_config.speed > SPEED_1000 &&
233 pl->link_config.duplex != DUPLEX_FULL)
Ioana Ciornei170911802019-05-28 20:38:14 +0300234 phylink_warn(pl, "fixed link specifies half duplex for %dMbps link?\n",
235 pl->link_config.speed);
Russell King9525ae82017-07-25 15:03:13 +0100236
237 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
238 linkmode_copy(pl->link_config.advertising, pl->supported);
239 phylink_validate(pl, pl->supported, &pl->link_config);
240
241 s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
Andrew Lunn3c1bcc82018-11-10 23:43:33 +0100242 pl->supported, true);
Russell King9525ae82017-07-25 15:03:13 +0100243 linkmode_zero(pl->supported);
244 phylink_set(pl->supported, MII);
René van Dorst8aace4f2019-07-27 11:40:11 +0200245 phylink_set(pl->supported, Pause);
246 phylink_set(pl->supported, Asym_Pause);
Russell King1ceb7ee2020-07-21 12:03:45 +0100247 phylink_set(pl->supported, Autoneg);
Russell King9525ae82017-07-25 15:03:13 +0100248 if (s) {
249 __set_bit(s->bit, pl->supported);
Russell King1ceb7ee2020-07-21 12:03:45 +0100250 __set_bit(s->bit, pl->link_config.lp_advertising);
Russell King9525ae82017-07-25 15:03:13 +0100251 } else {
Ioana Ciornei170911802019-05-28 20:38:14 +0300252 phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n",
253 pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
254 pl->link_config.speed);
Russell King9525ae82017-07-25 15:03:13 +0100255 }
256
257 linkmode_and(pl->link_config.advertising, pl->link_config.advertising,
258 pl->supported);
259
260 pl->link_config.link = 1;
261 pl->link_config.an_complete = 1;
262
263 return 0;
264}
265
Russell King8fa7b9b2017-12-01 10:25:09 +0000266static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
Russell King9525ae82017-07-25 15:03:13 +0100267{
Russell King8fa7b9b2017-12-01 10:25:09 +0000268 struct fwnode_handle *dn;
Russell King9525ae82017-07-25 15:03:13 +0100269 const char *managed;
270
Russell King8fa7b9b2017-12-01 10:25:09 +0000271 dn = fwnode_get_named_child_node(fwnode, "fixed-link");
272 if (dn || fwnode_property_present(fwnode, "fixed-link"))
Russell King24cf0e62019-12-11 10:56:35 +0000273 pl->cfg_link_an_mode = MLO_AN_FIXED;
Russell King8fa7b9b2017-12-01 10:25:09 +0000274 fwnode_handle_put(dn);
Russell King9525ae82017-07-25 15:03:13 +0100275
Ong Boon Leongab393852021-03-15 13:27:08 +0800276 if ((fwnode_property_read_string(fwnode, "managed", &managed) == 0 &&
277 strcmp(managed, "in-band-status") == 0) ||
278 pl->config->ovr_an_inband) {
Russell King24cf0e62019-12-11 10:56:35 +0000279 if (pl->cfg_link_an_mode == MLO_AN_FIXED) {
Ioana Ciornei170911802019-05-28 20:38:14 +0300280 phylink_err(pl,
281 "can't use both fixed-link and in-band-status\n");
Russell King9525ae82017-07-25 15:03:13 +0100282 return -EINVAL;
283 }
284
285 linkmode_zero(pl->supported);
286 phylink_set(pl->supported, MII);
287 phylink_set(pl->supported, Autoneg);
288 phylink_set(pl->supported, Asym_Pause);
289 phylink_set(pl->supported, Pause);
290 pl->link_config.an_enabled = true;
Russell King24cf0e62019-12-11 10:56:35 +0000291 pl->cfg_link_an_mode = MLO_AN_INBAND;
Russell King9525ae82017-07-25 15:03:13 +0100292
293 switch (pl->link_config.interface) {
294 case PHY_INTERFACE_MODE_SGMII:
Vladimir Oltean3a68ba62020-01-06 03:34:10 +0200295 case PHY_INTERFACE_MODE_QSGMII:
Russell King9525ae82017-07-25 15:03:13 +0100296 phylink_set(pl->supported, 10baseT_Half);
297 phylink_set(pl->supported, 10baseT_Full);
298 phylink_set(pl->supported, 100baseT_Half);
299 phylink_set(pl->supported, 100baseT_Full);
300 phylink_set(pl->supported, 1000baseT_Half);
301 phylink_set(pl->supported, 1000baseT_Full);
Russell King9525ae82017-07-25 15:03:13 +0100302 break;
303
304 case PHY_INTERFACE_MODE_1000BASEX:
305 phylink_set(pl->supported, 1000baseX_Full);
Russell King9525ae82017-07-25 15:03:13 +0100306 break;
307
308 case PHY_INTERFACE_MODE_2500BASEX:
309 phylink_set(pl->supported, 2500baseX_Full);
Russell King9525ae82017-07-25 15:03:13 +0100310 break;
311
Marek Behúnf6813bd2021-02-16 20:20:54 +0100312 case PHY_INTERFACE_MODE_5GBASER:
313 phylink_set(pl->supported, 5000baseT_Full);
314 break;
315
Steen Hegelund21e0c592021-06-11 14:54:53 +0200316 case PHY_INTERFACE_MODE_25GBASER:
317 phylink_set(pl->supported, 25000baseCR_Full);
318 phylink_set(pl->supported, 25000baseKR_Full);
319 phylink_set(pl->supported, 25000baseSR_Full);
320 fallthrough;
Alex Marginean04e22462020-01-18 14:19:15 +0200321 case PHY_INTERFACE_MODE_USXGMII:
Russell Kingda7c1862017-07-25 15:03:34 +0100322 case PHY_INTERFACE_MODE_10GKR:
Russell Kinge0f909b2020-01-03 20:43:23 +0000323 case PHY_INTERFACE_MODE_10GBASER:
Russell Kingda7c1862017-07-25 15:03:34 +0100324 phylink_set(pl->supported, 10baseT_Half);
325 phylink_set(pl->supported, 10baseT_Full);
326 phylink_set(pl->supported, 100baseT_Half);
327 phylink_set(pl->supported, 100baseT_Full);
328 phylink_set(pl->supported, 1000baseT_Half);
329 phylink_set(pl->supported, 1000baseT_Full);
330 phylink_set(pl->supported, 1000baseX_Full);
Jose Abreuc5801652020-03-09 09:36:24 +0100331 phylink_set(pl->supported, 1000baseKX_Full);
Vladimir Oltean6cbdcf22020-01-16 19:36:56 +0200332 phylink_set(pl->supported, 2500baseT_Full);
333 phylink_set(pl->supported, 2500baseX_Full);
334 phylink_set(pl->supported, 5000baseT_Full);
335 phylink_set(pl->supported, 10000baseT_Full);
Russell Kingda7c1862017-07-25 15:03:34 +0100336 phylink_set(pl->supported, 10000baseKR_Full);
Jose Abreuc5801652020-03-09 09:36:24 +0100337 phylink_set(pl->supported, 10000baseKX4_Full);
Russell Kingda7c1862017-07-25 15:03:34 +0100338 phylink_set(pl->supported, 10000baseCR_Full);
339 phylink_set(pl->supported, 10000baseSR_Full);
340 phylink_set(pl->supported, 10000baseLR_Full);
341 phylink_set(pl->supported, 10000baseLRM_Full);
342 phylink_set(pl->supported, 10000baseER_Full);
Russell Kingda7c1862017-07-25 15:03:34 +0100343 break;
344
Jose Abreu1671c422020-03-12 18:10:10 +0100345 case PHY_INTERFACE_MODE_XLGMII:
346 phylink_set(pl->supported, 25000baseCR_Full);
347 phylink_set(pl->supported, 25000baseKR_Full);
348 phylink_set(pl->supported, 25000baseSR_Full);
349 phylink_set(pl->supported, 40000baseKR4_Full);
350 phylink_set(pl->supported, 40000baseCR4_Full);
351 phylink_set(pl->supported, 40000baseSR4_Full);
352 phylink_set(pl->supported, 40000baseLR4_Full);
353 phylink_set(pl->supported, 50000baseCR2_Full);
354 phylink_set(pl->supported, 50000baseKR2_Full);
355 phylink_set(pl->supported, 50000baseSR2_Full);
356 phylink_set(pl->supported, 50000baseKR_Full);
357 phylink_set(pl->supported, 50000baseSR_Full);
358 phylink_set(pl->supported, 50000baseCR_Full);
359 phylink_set(pl->supported, 50000baseLR_ER_FR_Full);
360 phylink_set(pl->supported, 50000baseDR_Full);
361 phylink_set(pl->supported, 100000baseKR4_Full);
362 phylink_set(pl->supported, 100000baseSR4_Full);
363 phylink_set(pl->supported, 100000baseCR4_Full);
364 phylink_set(pl->supported, 100000baseLR4_ER4_Full);
365 phylink_set(pl->supported, 100000baseKR2_Full);
366 phylink_set(pl->supported, 100000baseSR2_Full);
367 phylink_set(pl->supported, 100000baseCR2_Full);
368 phylink_set(pl->supported, 100000baseLR2_ER2_FR2_Full);
369 phylink_set(pl->supported, 100000baseDR2_Full);
370 break;
371
Russell King9525ae82017-07-25 15:03:13 +0100372 default:
Ioana Ciornei170911802019-05-28 20:38:14 +0300373 phylink_err(pl,
374 "incorrect link mode %s for in-band status\n",
375 phy_modes(pl->link_config.interface));
Russell King9525ae82017-07-25 15:03:13 +0100376 return -EINVAL;
377 }
378
379 linkmode_copy(pl->link_config.advertising, pl->supported);
380
381 if (phylink_validate(pl, pl->supported, &pl->link_config)) {
Ioana Ciornei170911802019-05-28 20:38:14 +0300382 phylink_err(pl,
383 "failed to validate link configuration for in-band status\n");
Russell King9525ae82017-07-25 15:03:13 +0100384 return -EINVAL;
385 }
Jose Abreu94148192020-03-09 09:36:25 +0100386
387 /* Check if MAC/PCS also supports Autoneg. */
388 pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
Russell King9525ae82017-07-25 15:03:13 +0100389 }
390
391 return 0;
392}
393
Russell King2d5fbef2020-02-15 15:49:43 +0000394static void phylink_apply_manual_flow(struct phylink *pl,
395 struct phylink_link_state *state)
396{
397 /* If autoneg is disabled, pause AN is also disabled */
398 if (!state->an_enabled)
399 state->pause &= ~MLO_PAUSE_AN;
400
401 /* Manual configuration of pause modes */
402 if (!(pl->link_config.pause & MLO_PAUSE_AN))
403 state->pause = pl->link_config.pause;
404}
405
Russell King4e5aeb42020-02-15 15:49:53 +0000406static void phylink_resolve_flow(struct phylink_link_state *state)
407{
408 bool tx_pause, rx_pause;
409
410 state->pause = MLO_PAUSE_NONE;
411 if (state->duplex == DUPLEX_FULL) {
412 linkmode_resolve_pause(state->advertising,
413 state->lp_advertising,
414 &tx_pause, &rx_pause);
415 if (tx_pause)
416 state->pause |= MLO_PAUSE_TX;
417 if (rx_pause)
418 state->pause |= MLO_PAUSE_RX;
419 }
420}
421
Russell King9525ae82017-07-25 15:03:13 +0100422static void phylink_mac_config(struct phylink *pl,
423 const struct phylink_link_state *state)
424{
Ioana Ciornei170911802019-05-28 20:38:14 +0300425 phylink_dbg(pl,
426 "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
Russell King24cf0e62019-12-11 10:56:35 +0000427 __func__, phylink_an_mode_str(pl->cur_link_an_mode),
Ioana Ciornei170911802019-05-28 20:38:14 +0300428 phy_modes(state->interface),
429 phy_speed_to_str(state->speed),
430 phy_duplex_to_str(state->duplex),
431 __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
432 state->pause, state->link, state->an_enabled);
Russell King9525ae82017-07-25 15:03:13 +0100433
Russell Kinge7765d62020-03-30 18:44:50 +0100434 pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state);
Russell King9525ae82017-07-25 15:03:13 +0100435}
436
Russell King4c0d6d32020-03-30 18:44:55 +0100437static void phylink_mac_pcs_an_restart(struct phylink *pl)
Russell King9525ae82017-07-25 15:03:13 +0100438{
439 if (pl->link_config.an_enabled &&
Russell King575691b2020-06-24 12:30:04 +0100440 phy_interface_mode_is_8023z(pl->link_config.interface) &&
441 phylink_autoneg_inband(pl->cur_link_an_mode)) {
Russell King4c0d6d32020-03-30 18:44:55 +0100442 if (pl->pcs_ops)
Russell King7137e182020-07-21 12:04:46 +0100443 pl->pcs_ops->pcs_an_restart(pl->pcs);
Russell King4c0d6d32020-03-30 18:44:55 +0100444 else
445 pl->mac_ops->mac_an_restart(pl->config);
446 }
447}
448
Russell Kingb7ad14c2020-07-21 12:04:41 +0100449static void phylink_major_config(struct phylink *pl, bool restart,
450 const struct phylink_link_state *state)
Russell King4c0d6d32020-03-30 18:44:55 +0100451{
Russell Kingb7ad14c2020-07-21 12:04:41 +0100452 int err;
Russell King4c0d6d32020-03-30 18:44:55 +0100453
Russell Kingb7ad14c2020-07-21 12:04:41 +0100454 phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
455
456 if (pl->mac_ops->mac_prepare) {
457 err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
458 state->interface);
459 if (err < 0) {
460 phylink_err(pl, "mac_prepare failed: %pe\n",
461 ERR_PTR(err));
462 return;
463 }
464 }
Russell King4c0d6d32020-03-30 18:44:55 +0100465
466 phylink_mac_config(pl, state);
467
Russell Kingb7ad14c2020-07-21 12:04:41 +0100468 if (pl->pcs_ops) {
Russell King7137e182020-07-21 12:04:46 +0100469 err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
Russell Kingb7ad14c2020-07-21 12:04:41 +0100470 state->interface,
471 state->advertising,
472 !!(pl->link_config.pause &
473 MLO_PAUSE_AN));
474 if (err < 0)
475 phylink_err(pl, "pcs_config failed: %pe\n",
476 ERR_PTR(err));
477 if (err > 0)
478 restart = true;
479 }
Russell King4c0d6d32020-03-30 18:44:55 +0100480 if (restart)
481 phylink_mac_pcs_an_restart(pl);
Russell Kingb7ad14c2020-07-21 12:04:41 +0100482
483 if (pl->mac_ops->mac_finish) {
484 err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
485 state->interface);
486 if (err < 0)
Ong Boon Leongd82c6c12021-03-15 12:33:42 +0800487 phylink_err(pl, "mac_finish failed: %pe\n",
Russell Kingb7ad14c2020-07-21 12:04:41 +0100488 ERR_PTR(err));
489 }
Russell King9525ae82017-07-25 15:03:13 +0100490}
491
Russell King1571e702020-07-21 12:04:36 +0100492/*
493 * Reconfigure for a change of inband advertisement.
494 * If we have a separate PCS, we only need to call its pcs_config() method,
495 * and then restart AN if it indicates something changed. Otherwise, we do
496 * the full MAC reconfiguration.
497 */
498static int phylink_change_inband_advert(struct phylink *pl)
499{
500 int ret;
501
502 if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
503 return 0;
504
505 if (!pl->pcs_ops) {
506 /* Legacy method */
507 phylink_mac_config(pl, &pl->link_config);
508 phylink_mac_pcs_an_restart(pl);
509 return 0;
510 }
511
512 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
513 phylink_an_mode_str(pl->cur_link_an_mode),
514 phy_modes(pl->link_config.interface),
515 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
516 pl->link_config.pause);
517
518 /* Modern PCS-based method; update the advert at the PCS, and
519 * restart negotiation if the pcs_config() helper indicates that
520 * the programmed advertisement has changed.
521 */
Russell King7137e182020-07-21 12:04:46 +0100522 ret = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
Russell King1571e702020-07-21 12:04:36 +0100523 pl->link_config.interface,
524 pl->link_config.advertising,
525 !!(pl->link_config.pause & MLO_PAUSE_AN));
526 if (ret < 0)
527 return ret;
528
529 if (ret > 0)
530 phylink_mac_pcs_an_restart(pl);
531
532 return 0;
533}
534
Russell Kingd46b7e42019-11-21 00:36:22 +0000535static void phylink_mac_pcs_get_state(struct phylink *pl,
536 struct phylink_link_state *state)
Russell King9525ae82017-07-25 15:03:13 +0100537{
Russell King9525ae82017-07-25 15:03:13 +0100538 linkmode_copy(state->advertising, pl->link_config.advertising);
539 linkmode_zero(state->lp_advertising);
540 state->interface = pl->link_config.interface;
541 state->an_enabled = pl->link_config.an_enabled;
Heiner Kallweitd25ed412019-02-26 19:29:22 +0100542 state->speed = SPEED_UNKNOWN;
543 state->duplex = DUPLEX_UNKNOWN;
544 state->pause = MLO_PAUSE_NONE;
545 state->an_complete = 0;
Russell King9525ae82017-07-25 15:03:13 +0100546 state->link = 1;
547
Russell King4c0d6d32020-03-30 18:44:55 +0100548 if (pl->pcs_ops)
Russell King7137e182020-07-21 12:04:46 +0100549 pl->pcs_ops->pcs_get_state(pl->pcs, state);
Russell Kinge859a602020-08-28 11:53:53 +0100550 else if (pl->mac_ops->mac_pcs_get_state)
Russell King4c0d6d32020-03-30 18:44:55 +0100551 pl->mac_ops->mac_pcs_get_state(pl->config, state);
Russell Kinge859a602020-08-28 11:53:53 +0100552 else
553 state->link = 0;
Russell King9525ae82017-07-25 15:03:13 +0100554}
555
556/* The fixed state is... fixed except for the link state,
Florian Fainelli1ac63e32017-12-12 16:00:28 -0800557 * which may be determined by a GPIO or a callback.
Russell King9525ae82017-07-25 15:03:13 +0100558 */
Russell King4e5aeb42020-02-15 15:49:53 +0000559static void phylink_get_fixed_state(struct phylink *pl,
560 struct phylink_link_state *state)
Russell King9525ae82017-07-25 15:03:13 +0100561{
562 *state = pl->link_config;
Russell King5c05c1d2020-04-23 17:02:56 +0100563 if (pl->config->get_fixed_state)
564 pl->config->get_fixed_state(pl->config, state);
Florian Fainelli1ac63e32017-12-12 16:00:28 -0800565 else if (pl->link_gpio)
Florian Fainellibb322a92018-05-10 13:17:29 -0700566 state->link = !!gpiod_get_value_cansleep(pl->link_gpio);
Russell King9525ae82017-07-25 15:03:13 +0100567
Russell King4e5aeb42020-02-15 15:49:53 +0000568 phylink_resolve_flow(state);
Russell King9525ae82017-07-25 15:03:13 +0100569}
570
Russell King4c0d6d32020-03-30 18:44:55 +0100571static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
Russell King97fec512020-02-15 15:50:03 +0000572{
573 struct phylink_link_state link_state;
574
575 switch (pl->cur_link_an_mode) {
576 case MLO_AN_PHY:
577 link_state = pl->phy_state;
578 break;
579
580 case MLO_AN_FIXED:
581 phylink_get_fixed_state(pl, &link_state);
582 break;
583
584 case MLO_AN_INBAND:
585 link_state = pl->link_config;
586 if (link_state.interface == PHY_INTERFACE_MODE_SGMII)
587 link_state.pause = MLO_PAUSE_NONE;
588 break;
589
590 default: /* can't happen */
591 return;
592 }
593
594 link_state.link = false;
595
596 phylink_apply_manual_flow(pl, &link_state);
Russell Kingb7ad14c2020-07-21 12:04:41 +0100597 phylink_major_config(pl, force_restart, &link_state);
Russell King97fec512020-02-15 15:50:03 +0000598}
599
Russell King9525ae82017-07-25 15:03:13 +0100600static const char *phylink_pause_to_str(int pause)
601{
602 switch (pause & MLO_PAUSE_TXRX_MASK) {
603 case MLO_PAUSE_TX | MLO_PAUSE_RX:
604 return "rx/tx";
605 case MLO_PAUSE_TX:
606 return "tx";
607 case MLO_PAUSE_RX:
608 return "rx";
609 default:
610 return "off";
611 }
612}
613
Russell King4c0d6d32020-03-30 18:44:55 +0100614static void phylink_link_up(struct phylink *pl,
615 struct phylink_link_state link_state)
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300616{
617 struct net_device *ndev = pl->netdev;
618
David S. Millerb4b12b02019-05-31 10:49:43 -0700619 pl->cur_interface = link_state.interface;
Russell King4c0d6d32020-03-30 18:44:55 +0100620
621 if (pl->pcs_ops && pl->pcs_ops->pcs_link_up)
Russell King7137e182020-07-21 12:04:46 +0100622 pl->pcs_ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
Russell King4c0d6d32020-03-30 18:44:55 +0100623 pl->cur_interface,
624 link_state.speed, link_state.duplex);
625
Russell Kinge7765d62020-03-30 18:44:50 +0100626 pl->mac_ops->mac_link_up(pl->config, pl->phydev,
627 pl->cur_link_an_mode, pl->cur_interface,
628 link_state.speed, link_state.duplex,
629 !!(link_state.pause & MLO_PAUSE_TX),
630 !!(link_state.pause & MLO_PAUSE_RX));
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300631
Ioana Ciornei43de6192019-05-28 20:38:13 +0300632 if (ndev)
633 netif_carrier_on(ndev);
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300634
Ioana Ciornei170911802019-05-28 20:38:14 +0300635 phylink_info(pl,
636 "Link is Up - %s/%s - flow control %s\n",
637 phy_speed_to_str(link_state.speed),
638 phy_duplex_to_str(link_state.duplex),
639 phylink_pause_to_str(link_state.pause));
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300640}
641
Russell King4c0d6d32020-03-30 18:44:55 +0100642static void phylink_link_down(struct phylink *pl)
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300643{
644 struct net_device *ndev = pl->netdev;
645
Ioana Ciornei43de6192019-05-28 20:38:13 +0300646 if (ndev)
647 netif_carrier_off(ndev);
Russell Kinge7765d62020-03-30 18:44:50 +0100648 pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
649 pl->cur_interface);
Ioana Ciornei170911802019-05-28 20:38:14 +0300650 phylink_info(pl, "Link is Down\n");
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300651}
652
Russell King9525ae82017-07-25 15:03:13 +0100653static void phylink_resolve(struct work_struct *w)
654{
655 struct phylink *pl = container_of(w, struct phylink, resolve);
656 struct phylink_link_state link_state;
657 struct net_device *ndev = pl->netdev;
Russell King319bfaf2020-07-21 12:03:55 +0100658 bool mac_config = false;
Russell Kingb06e5ca2020-07-21 12:03:50 +0100659 bool cur_link_state;
Russell King9525ae82017-07-25 15:03:13 +0100660
661 mutex_lock(&pl->state_mutex);
Russell Kingb06e5ca2020-07-21 12:03:50 +0100662 if (pl->netdev)
663 cur_link_state = netif_carrier_ok(ndev);
664 else
665 cur_link_state = pl->old_link_state;
666
Russell King9525ae82017-07-25 15:03:13 +0100667 if (pl->phylink_disable_state) {
668 pl->mac_link_dropped = false;
669 link_state.link = false;
670 } else if (pl->mac_link_dropped) {
671 link_state.link = false;
672 } else {
Russell King24cf0e62019-12-11 10:56:35 +0000673 switch (pl->cur_link_an_mode) {
Russell King9525ae82017-07-25 15:03:13 +0100674 case MLO_AN_PHY:
675 link_state = pl->phy_state;
Russell King2d5fbef2020-02-15 15:49:43 +0000676 phylink_apply_manual_flow(pl, &link_state);
Russell King319bfaf2020-07-21 12:03:55 +0100677 mac_config = link_state.link;
Russell King9525ae82017-07-25 15:03:13 +0100678 break;
679
680 case MLO_AN_FIXED:
681 phylink_get_fixed_state(pl, &link_state);
Russell King319bfaf2020-07-21 12:03:55 +0100682 mac_config = link_state.link;
Russell King9525ae82017-07-25 15:03:13 +0100683 break;
684
Russell King86a362c2017-12-01 10:24:26 +0000685 case MLO_AN_INBAND:
Russell Kingd46b7e42019-11-21 00:36:22 +0000686 phylink_mac_pcs_get_state(pl, &link_state);
Russell King9525ae82017-07-25 15:03:13 +0100687
Russell King406cb0c2019-05-20 16:07:20 +0100688 /* If we have a phy, the "up" state is the union of
Wenpeng Liang1953feb2021-06-16 18:01:20 +0800689 * both the PHY and the MAC
690 */
Russell King406cb0c2019-05-20 16:07:20 +0100691 if (pl->phydev)
692 link_state.link &= pl->phy_state.link;
Russell King9525ae82017-07-25 15:03:13 +0100693
Russell King406cb0c2019-05-20 16:07:20 +0100694 /* Only update if the PHY link is up */
695 if (pl->phydev && pl->phy_state.link) {
696 link_state.interface = pl->phy_state.interface;
Russell King9525ae82017-07-25 15:03:13 +0100697
Russell King406cb0c2019-05-20 16:07:20 +0100698 /* If we have a PHY, we need to update with
Wenpeng Liang1953feb2021-06-16 18:01:20 +0800699 * the PHY flow control bits.
700 */
Russell King33faac82020-02-15 15:49:48 +0000701 link_state.pause = pl->phy_state.pause;
Russell King319bfaf2020-07-21 12:03:55 +0100702 mac_config = true;
Russell King9525ae82017-07-25 15:03:13 +0100703 }
Russell King319bfaf2020-07-21 12:03:55 +0100704 phylink_apply_manual_flow(pl, &link_state);
Russell King9525ae82017-07-25 15:03:13 +0100705 break;
Russell King9525ae82017-07-25 15:03:13 +0100706 }
707 }
708
Russell King16319a72020-07-21 12:04:00 +0100709 if (mac_config) {
710 if (link_state.interface != pl->link_config.interface) {
711 /* The interface has changed, force the link down and
712 * then reconfigure.
713 */
714 if (cur_link_state) {
715 phylink_link_down(pl);
716 cur_link_state = false;
717 }
Russell Kingb7ad14c2020-07-21 12:04:41 +0100718 phylink_major_config(pl, false, &link_state);
Russell King5005b162020-07-21 12:04:05 +0100719 pl->link_config.interface = link_state.interface;
Russell King7cceb592020-07-21 12:04:10 +0100720 } else if (!pl->pcs_ops) {
Russell King5005b162020-07-21 12:04:05 +0100721 /* The interface remains unchanged, only the speed,
722 * duplex or pause settings have changed. Call the
Russell King7cceb592020-07-21 12:04:10 +0100723 * old mac_config() method to configure the MAC/PCS
724 * only if we do not have a PCS installed (an
725 * unconverted user.)
Russell King5005b162020-07-21 12:04:05 +0100726 */
727 phylink_mac_config(pl, &link_state);
Russell King16319a72020-07-21 12:04:00 +0100728 }
Russell King16319a72020-07-21 12:04:00 +0100729 }
Russell King319bfaf2020-07-21 12:03:55 +0100730
Russell Kingb06e5ca2020-07-21 12:03:50 +0100731 if (link_state.link != cur_link_state) {
Ioana Ciornei43de6192019-05-28 20:38:13 +0300732 pl->old_link_state = link_state.link;
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300733 if (!link_state.link)
Russell King4c0d6d32020-03-30 18:44:55 +0100734 phylink_link_down(pl);
Ioana Ciornei27755ff2019-05-28 20:38:11 +0300735 else
Russell King4c0d6d32020-03-30 18:44:55 +0100736 phylink_link_up(pl, link_state);
Russell King9525ae82017-07-25 15:03:13 +0100737 }
738 if (!link_state.link && pl->mac_link_dropped) {
739 pl->mac_link_dropped = false;
740 queue_work(system_power_efficient_wq, &pl->resolve);
741 }
742 mutex_unlock(&pl->state_mutex);
743}
744
745static void phylink_run_resolve(struct phylink *pl)
746{
747 if (!pl->phylink_disable_state)
748 queue_work(system_power_efficient_wq, &pl->resolve);
749}
750
Russell King87454b62019-02-11 15:04:24 +0000751static void phylink_run_resolve_and_disable(struct phylink *pl, int bit)
752{
753 unsigned long state = pl->phylink_disable_state;
754
755 set_bit(bit, &pl->phylink_disable_state);
756 if (state == 0) {
757 queue_work(system_power_efficient_wq, &pl->resolve);
758 flush_work(&pl->resolve);
759 }
760}
761
Russell King9cd00a82018-05-10 13:17:31 -0700762static void phylink_fixed_poll(struct timer_list *t)
763{
764 struct phylink *pl = container_of(t, struct phylink, link_poll);
765
766 mod_timer(t, jiffies + HZ);
767
768 phylink_run_resolve(pl);
769}
770
Russell Kingce0aa272017-07-25 15:03:18 +0100771static const struct sfp_upstream_ops sfp_phylink_ops;
772
Russell King8fa7b9b2017-12-01 10:25:09 +0000773static int phylink_register_sfp(struct phylink *pl,
774 struct fwnode_handle *fwnode)
Russell Kingce0aa272017-07-25 15:03:18 +0100775{
Russell King2203cbf2019-10-15 11:38:39 +0100776 struct sfp_bus *bus;
Russell King8fa7b9b2017-12-01 10:25:09 +0000777 int ret;
Russell Kingce0aa272017-07-25 15:03:18 +0100778
Russell Kingeed70fd2020-01-03 15:13:56 +0000779 if (!fwnode)
780 return 0;
781
Russell King727b3662019-11-08 17:39:29 +0000782 bus = sfp_bus_find_fwnode(fwnode);
Russell King2203cbf2019-10-15 11:38:39 +0100783 if (IS_ERR(bus)) {
784 ret = PTR_ERR(bus);
785 phylink_err(pl, "unable to attach SFP bus: %d\n", ret);
Russell King8fa7b9b2017-12-01 10:25:09 +0000786 return ret;
787 }
788
Russell King2203cbf2019-10-15 11:38:39 +0100789 pl->sfp_bus = bus;
Russell Kingce0aa272017-07-25 15:03:18 +0100790
Russell King727b3662019-11-08 17:39:29 +0000791 ret = sfp_bus_add_upstream(bus, pl, &sfp_phylink_ops);
792 sfp_bus_put(bus);
793
794 return ret;
Russell Kingce0aa272017-07-25 15:03:18 +0100795}
796
Russell King8796c892017-12-01 10:24:47 +0000797/**
798 * phylink_create() - create a phylink instance
Randy Dunlap9db74e52019-10-08 08:39:04 -0700799 * @config: a pointer to the target &struct phylink_config
Russell King8fa7b9b2017-12-01 10:25:09 +0000800 * @fwnode: a pointer to a &struct fwnode_handle describing the network
801 * interface
Russell King8796c892017-12-01 10:24:47 +0000802 * @iface: the desired link mode defined by &typedef phy_interface_t
Russell Kinge7765d62020-03-30 18:44:50 +0100803 * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC.
Russell King8796c892017-12-01 10:24:47 +0000804 *
805 * Create a new phylink instance, and parse the link parameters found in @np.
806 * This will parse in-band modes, fixed-link or SFP configuration.
807 *
Russell King269a6b52019-11-19 17:18:52 +0000808 * Note: the rtnl lock must not be held when calling this function.
809 *
Russell King8796c892017-12-01 10:24:47 +0000810 * Returns a pointer to a &struct phylink, or an error-pointer value. Users
811 * must use IS_ERR() to check for errors from this function.
812 */
Ioana Ciornei44cc27e2019-05-28 20:38:12 +0300813struct phylink *phylink_create(struct phylink_config *config,
Russell King8fa7b9b2017-12-01 10:25:09 +0000814 struct fwnode_handle *fwnode,
Florian Fainelli516b29e2017-10-30 21:42:57 -0700815 phy_interface_t iface,
Russell Kinge7765d62020-03-30 18:44:50 +0100816 const struct phylink_mac_ops *mac_ops)
Russell King9525ae82017-07-25 15:03:13 +0100817{
818 struct phylink *pl;
819 int ret;
820
821 pl = kzalloc(sizeof(*pl), GFP_KERNEL);
822 if (!pl)
823 return ERR_PTR(-ENOMEM);
824
825 mutex_init(&pl->state_mutex);
826 INIT_WORK(&pl->resolve, phylink_resolve);
Ioana Ciornei44cc27e2019-05-28 20:38:12 +0300827
828 pl->config = config;
829 if (config->type == PHYLINK_NETDEV) {
830 pl->netdev = to_net_dev(config->dev);
Ioana Ciornei43de6192019-05-28 20:38:13 +0300831 } else if (config->type == PHYLINK_DEV) {
832 pl->dev = config->dev;
Ioana Ciornei44cc27e2019-05-28 20:38:12 +0300833 } else {
834 kfree(pl);
835 return ERR_PTR(-EINVAL);
836 }
837
Russell King9525ae82017-07-25 15:03:13 +0100838 pl->phy_state.interface = iface;
839 pl->link_interface = iface;
Florian Fainelli4be11ef2017-12-12 16:00:29 -0800840 if (iface == PHY_INTERFACE_MODE_MOCA)
841 pl->link_port = PORT_BNC;
842 else
843 pl->link_port = PORT_MII;
Russell King9525ae82017-07-25 15:03:13 +0100844 pl->link_config.interface = iface;
845 pl->link_config.pause = MLO_PAUSE_AN;
846 pl->link_config.speed = SPEED_UNKNOWN;
847 pl->link_config.duplex = DUPLEX_UNKNOWN;
Russell King74ee0e82017-12-20 23:21:34 +0000848 pl->link_config.an_enabled = true;
Russell Kinge7765d62020-03-30 18:44:50 +0100849 pl->mac_ops = mac_ops;
Russell King9525ae82017-07-25 15:03:13 +0100850 __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
Russell King9cd00a82018-05-10 13:17:31 -0700851 timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
Russell King9525ae82017-07-25 15:03:13 +0100852
853 bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
854 linkmode_copy(pl->link_config.advertising, pl->supported);
855 phylink_validate(pl, pl->supported, &pl->link_config);
856
Russell King8fa7b9b2017-12-01 10:25:09 +0000857 ret = phylink_parse_mode(pl, fwnode);
Russell King9525ae82017-07-25 15:03:13 +0100858 if (ret < 0) {
859 kfree(pl);
860 return ERR_PTR(ret);
861 }
862
Russell King24cf0e62019-12-11 10:56:35 +0000863 if (pl->cfg_link_an_mode == MLO_AN_FIXED) {
Russell King8fa7b9b2017-12-01 10:25:09 +0000864 ret = phylink_parse_fixedlink(pl, fwnode);
Russell King9525ae82017-07-25 15:03:13 +0100865 if (ret < 0) {
866 kfree(pl);
867 return ERR_PTR(ret);
868 }
869 }
870
Russell King24cf0e62019-12-11 10:56:35 +0000871 pl->cur_link_an_mode = pl->cfg_link_an_mode;
872
Russell King8fa7b9b2017-12-01 10:25:09 +0000873 ret = phylink_register_sfp(pl, fwnode);
Russell Kingce0aa272017-07-25 15:03:18 +0100874 if (ret < 0) {
875 kfree(pl);
876 return ERR_PTR(ret);
877 }
878
Russell King9525ae82017-07-25 15:03:13 +0100879 return pl;
880}
881EXPORT_SYMBOL_GPL(phylink_create);
882
Russell King7137e182020-07-21 12:04:46 +0100883/**
884 * phylink_set_pcs() - set the current PCS for phylink to use
885 * @pl: a pointer to a &struct phylink returned from phylink_create()
886 * @pcs: a pointer to the &struct phylink_pcs
887 *
888 * Bind the MAC PCS to phylink. This may be called after phylink_create(),
889 * in mac_prepare() or mac_config() methods if it is desired to dynamically
890 * change the PCS.
891 *
892 * Please note that there are behavioural changes with the mac_config()
893 * callback if a PCS is present (denoting a newer setup) so removing a PCS
894 * is not supported, and if a PCS is going to be used, it must be registered
895 * by calling phylink_set_pcs() at the latest in the first mac_config() call.
896 */
897void phylink_set_pcs(struct phylink *pl, struct phylink_pcs *pcs)
Russell King4c0d6d32020-03-30 18:44:55 +0100898{
Russell King7137e182020-07-21 12:04:46 +0100899 pl->pcs = pcs;
900 pl->pcs_ops = pcs->ops;
Russell King4c0d6d32020-03-30 18:44:55 +0100901}
Russell King7137e182020-07-21 12:04:46 +0100902EXPORT_SYMBOL_GPL(phylink_set_pcs);
Russell King4c0d6d32020-03-30 18:44:55 +0100903
Russell King8796c892017-12-01 10:24:47 +0000904/**
905 * phylink_destroy() - cleanup and destroy the phylink instance
906 * @pl: a pointer to a &struct phylink returned from phylink_create()
907 *
908 * Destroy a phylink instance. Any PHY that has been attached must have been
909 * cleaned up via phylink_disconnect_phy() prior to calling this function.
Russell King269a6b52019-11-19 17:18:52 +0000910 *
911 * Note: the rtnl lock must not be held when calling this function.
Russell King8796c892017-12-01 10:24:47 +0000912 */
Russell King9525ae82017-07-25 15:03:13 +0100913void phylink_destroy(struct phylink *pl)
914{
Russell King727b3662019-11-08 17:39:29 +0000915 sfp_bus_del_upstream(pl->sfp_bus);
Russell King7b3b0e82019-05-28 10:57:23 +0100916 if (pl->link_gpio)
Florian Fainellidaab3342018-05-10 13:17:30 -0700917 gpiod_put(pl->link_gpio);
Russell Kingce0aa272017-07-25 15:03:18 +0100918
Russell King9525ae82017-07-25 15:03:13 +0100919 cancel_work_sync(&pl->resolve);
920 kfree(pl);
921}
922EXPORT_SYMBOL_GPL(phylink_destroy);
923
Doug Bergera3075932020-05-18 15:23:59 -0700924static void phylink_phy_change(struct phy_device *phydev, bool up)
Russell King9525ae82017-07-25 15:03:13 +0100925{
926 struct phylink *pl = phydev->phylink;
Russell King33faac82020-02-15 15:49:48 +0000927 bool tx_pause, rx_pause;
928
929 phy_get_pause(phydev, &tx_pause, &rx_pause);
Russell King9525ae82017-07-25 15:03:13 +0100930
931 mutex_lock(&pl->state_mutex);
932 pl->phy_state.speed = phydev->speed;
933 pl->phy_state.duplex = phydev->duplex;
934 pl->phy_state.pause = MLO_PAUSE_NONE;
Russell King33faac82020-02-15 15:49:48 +0000935 if (tx_pause)
936 pl->phy_state.pause |= MLO_PAUSE_TX;
937 if (rx_pause)
938 pl->phy_state.pause |= MLO_PAUSE_RX;
Russell King9525ae82017-07-25 15:03:13 +0100939 pl->phy_state.interface = phydev->interface;
940 pl->phy_state.link = up;
941 mutex_unlock(&pl->state_mutex);
942
943 phylink_run_resolve(pl);
944
Ioana Ciornei170911802019-05-28 20:38:14 +0300945 phylink_dbg(pl, "phy link %s %s/%s/%s\n", up ? "up" : "down",
946 phy_modes(phydev->interface),
947 phy_speed_to_str(phydev->speed),
948 phy_duplex_to_str(phydev->duplex));
Russell King9525ae82017-07-25 15:03:13 +0100949}
950
Russell Kinge45d1f52019-12-11 10:56:30 +0000951static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
952 phy_interface_t interface)
Russell King9525ae82017-07-25 15:03:13 +0100953{
954 struct phylink_link_state config;
955 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
Florian Fainellie27f1782020-01-12 09:35:38 -0800956 char *irq_str;
Russell King9525ae82017-07-25 15:03:13 +0100957 int ret;
958
Russell King9525ae82017-07-25 15:03:13 +0100959 /*
960 * This is the new way of dealing with flow control for PHYs,
961 * as described by Timur Tabi in commit 529ed1275263 ("net: phy:
962 * phy drivers should not set SUPPORTED_[Asym_]Pause") except
963 * using our validate call to the MAC, we rely upon the MAC
964 * clearing the bits from both supported and advertising fields.
965 */
Russell King725ea4b2019-11-15 20:05:45 +0000966 phy_support_asym_pause(phy);
967
968 memset(&config, 0, sizeof(config));
969 linkmode_copy(supported, phy->supported);
970 linkmode_copy(config.advertising, phy->advertising);
Russell Kingdf3f57a2019-12-13 18:22:07 +0000971
972 /* Clause 45 PHYs switch their Serdes lane between several different
973 * modes, normally 10GBASE-R, SGMII. Some use 2500BASE-X for 2.5G
974 * speeds. We really need to know which interface modes the PHY and
975 * MAC supports to properly work out which linkmodes can be supported.
976 */
977 if (phy->is_c45 &&
978 interface != PHY_INTERFACE_MODE_RXAUI &&
979 interface != PHY_INTERFACE_MODE_XAUI &&
980 interface != PHY_INTERFACE_MODE_USXGMII)
981 config.interface = PHY_INTERFACE_MODE_NA;
982 else
983 config.interface = interface;
Russell King9525ae82017-07-25 15:03:13 +0100984
985 ret = phylink_validate(pl, supported, &config);
Hauke Mehrtens20d8bb02020-03-02 00:55:02 +0100986 if (ret) {
987 phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %d\n",
988 phy_modes(config.interface),
989 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported,
990 __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising,
991 ret);
Russell King9525ae82017-07-25 15:03:13 +0100992 return ret;
Hauke Mehrtens20d8bb02020-03-02 00:55:02 +0100993 }
Russell King9525ae82017-07-25 15:03:13 +0100994
995 phy->phylink = pl;
996 phy->phy_link_change = phylink_phy_change;
997
Florian Fainellie27f1782020-01-12 09:35:38 -0800998 irq_str = phy_attached_info_irq(phy);
Ioana Ciornei170911802019-05-28 20:38:14 +0300999 phylink_info(pl,
Florian Fainellie27f1782020-01-12 09:35:38 -08001000 "PHY [%s] driver [%s] (irq=%s)\n",
1001 dev_name(&phy->mdio.dev), phy->drv->name, irq_str);
1002 kfree(irq_str);
Russell King9525ae82017-07-25 15:03:13 +01001003
1004 mutex_lock(&phy->lock);
1005 mutex_lock(&pl->state_mutex);
Russell King9525ae82017-07-25 15:03:13 +01001006 pl->phydev = phy;
Russell Kinge45d1f52019-12-11 10:56:30 +00001007 pl->phy_state.interface = interface;
Russell King97fec512020-02-15 15:50:03 +00001008 pl->phy_state.pause = MLO_PAUSE_NONE;
1009 pl->phy_state.speed = SPEED_UNKNOWN;
1010 pl->phy_state.duplex = DUPLEX_UNKNOWN;
Russell King9525ae82017-07-25 15:03:13 +01001011 linkmode_copy(pl->supported, supported);
1012 linkmode_copy(pl->link_config.advertising, config.advertising);
1013
Colin Ian Kingcc1122b2018-03-01 10:23:03 +00001014 /* Restrict the phy advertisement according to the MAC support. */
Andrew Lunn3c1bcc82018-11-10 23:43:33 +01001015 linkmode_copy(phy->advertising, config.advertising);
Russell King9525ae82017-07-25 15:03:13 +01001016 mutex_unlock(&pl->state_mutex);
1017 mutex_unlock(&phy->lock);
1018
Ioana Ciornei170911802019-05-28 20:38:14 +03001019 phylink_dbg(pl,
1020 "phy: setting supported %*pb advertising %*pb\n",
1021 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
1022 __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising);
Russell King9525ae82017-07-25 15:03:13 +01001023
Heiner Kallweit434a4312019-01-23 07:31:58 +01001024 if (phy_interrupt_is_valid(phy))
1025 phy_request_interrupt(phy);
Russell King9525ae82017-07-25 15:03:13 +01001026
1027 return 0;
1028}
1029
Russell King938d44c2019-12-11 10:56:25 +00001030static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
1031 phy_interface_t interface)
Baruch Siach7e418372018-10-03 19:04:49 +03001032{
Russell King24cf0e62019-12-11 10:56:35 +00001033 if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
1034 (pl->cfg_link_an_mode == MLO_AN_INBAND &&
Baruch Siach7e418372018-10-03 19:04:49 +03001035 phy_interface_mode_is_8023z(interface))))
1036 return -EINVAL;
1037
1038 if (pl->phydev)
1039 return -EBUSY;
1040
Russell King938d44c2019-12-11 10:56:25 +00001041 return phy_attach_direct(pl->netdev, phy, 0, interface);
Baruch Siach7e418372018-10-03 19:04:49 +03001042}
1043
Russell King8796c892017-12-01 10:24:47 +00001044/**
1045 * phylink_connect_phy() - connect a PHY to the phylink instance
1046 * @pl: a pointer to a &struct phylink returned from phylink_create()
1047 * @phy: a pointer to a &struct phy_device.
1048 *
1049 * Connect @phy to the phylink instance specified by @pl by calling
1050 * phy_attach_direct(). Configure the @phy according to the MAC driver's
1051 * capabilities, start the PHYLIB state machine and enable any interrupts
1052 * that the PHY supports.
1053 *
1054 * This updates the phylink's ethtool supported and advertising link mode
1055 * masks.
1056 *
1057 * Returns 0 on success or a negative errno.
1058 */
Russell King9525ae82017-07-25 15:03:13 +01001059int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
1060{
Russell King938d44c2019-12-11 10:56:25 +00001061 int ret;
1062
Florian Fainelli4904b6e2017-12-12 16:00:26 -08001063 /* Use PHY device/driver interface */
1064 if (pl->link_interface == PHY_INTERFACE_MODE_NA) {
1065 pl->link_interface = phy->interface;
1066 pl->link_config.interface = pl->link_interface;
1067 }
1068
Russell King938d44c2019-12-11 10:56:25 +00001069 ret = phylink_attach_phy(pl, phy, pl->link_interface);
1070 if (ret < 0)
1071 return ret;
1072
Russell Kinge45d1f52019-12-11 10:56:30 +00001073 ret = phylink_bringup_phy(pl, phy, pl->link_config.interface);
Russell King938d44c2019-12-11 10:56:25 +00001074 if (ret)
1075 phy_detach(phy);
1076
1077 return ret;
Russell King9525ae82017-07-25 15:03:13 +01001078}
1079EXPORT_SYMBOL_GPL(phylink_connect_phy);
1080
Russell King8796c892017-12-01 10:24:47 +00001081/**
1082 * phylink_of_phy_connect() - connect the PHY specified in the DT mode.
1083 * @pl: a pointer to a &struct phylink returned from phylink_create()
1084 * @dn: a pointer to a &struct device_node.
Florian Fainelli0a629642017-12-12 16:00:25 -08001085 * @flags: PHY-specific flags to communicate to the PHY device driver
Russell King8796c892017-12-01 10:24:47 +00001086 *
1087 * Connect the phy specified in the device node @dn to the phylink instance
1088 * specified by @pl. Actions specified in phylink_connect_phy() will be
1089 * performed.
1090 *
1091 * Returns 0 on success or a negative errno.
1092 */
Florian Fainelli0a629642017-12-12 16:00:25 -08001093int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn,
1094 u32 flags)
Russell King9525ae82017-07-25 15:03:13 +01001095{
Calvin Johnson423e6e82021-06-11 13:54:00 +03001096 return phylink_fwnode_phy_connect(pl, of_fwnode_handle(dn), flags);
Russell King9525ae82017-07-25 15:03:13 +01001097}
1098EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
1099
Russell King8796c892017-12-01 10:24:47 +00001100/**
Calvin Johnson25396f62021-06-11 13:53:59 +03001101 * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode.
1102 * @pl: a pointer to a &struct phylink returned from phylink_create()
1103 * @fwnode: a pointer to a &struct fwnode_handle.
1104 * @flags: PHY-specific flags to communicate to the PHY device driver
1105 *
1106 * Connect the phy specified @fwnode to the phylink instance specified
1107 * by @pl.
1108 *
1109 * Returns 0 on success or a negative errno.
1110 */
1111int phylink_fwnode_phy_connect(struct phylink *pl,
1112 struct fwnode_handle *fwnode,
1113 u32 flags)
1114{
1115 struct fwnode_handle *phy_fwnode;
1116 struct phy_device *phy_dev;
1117 int ret;
1118
1119 /* Fixed links and 802.3z are handled without needing a PHY */
1120 if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
1121 (pl->cfg_link_an_mode == MLO_AN_INBAND &&
1122 phy_interface_mode_is_8023z(pl->link_interface)))
1123 return 0;
1124
1125 phy_fwnode = fwnode_get_phy_node(fwnode);
1126 if (IS_ERR(phy_fwnode)) {
1127 if (pl->cfg_link_an_mode == MLO_AN_PHY)
1128 return -ENODEV;
1129 return 0;
1130 }
1131
1132 phy_dev = fwnode_phy_find_device(phy_fwnode);
1133 /* We're done with the phy_node handle */
1134 fwnode_handle_put(phy_fwnode);
1135 if (!phy_dev)
1136 return -ENODEV;
1137
1138 ret = phy_attach_direct(pl->netdev, phy_dev, flags,
1139 pl->link_interface);
1140 if (ret) {
1141 phy_device_free(phy_dev);
1142 return ret;
1143 }
1144
1145 ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface);
1146 if (ret)
1147 phy_detach(phy_dev);
1148
1149 return ret;
1150}
1151EXPORT_SYMBOL_GPL(phylink_fwnode_phy_connect);
1152
1153/**
Russell King8796c892017-12-01 10:24:47 +00001154 * phylink_disconnect_phy() - disconnect any PHY attached to the phylink
1155 * instance.
1156 * @pl: a pointer to a &struct phylink returned from phylink_create()
1157 *
1158 * Disconnect any current PHY from the phylink instance described by @pl.
1159 */
Russell King9525ae82017-07-25 15:03:13 +01001160void phylink_disconnect_phy(struct phylink *pl)
1161{
1162 struct phy_device *phy;
1163
Russell King8b874512017-12-15 16:09:47 +00001164 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001165
1166 phy = pl->phydev;
1167 if (phy) {
1168 mutex_lock(&phy->lock);
1169 mutex_lock(&pl->state_mutex);
Russell King9525ae82017-07-25 15:03:13 +01001170 pl->phydev = NULL;
1171 mutex_unlock(&pl->state_mutex);
1172 mutex_unlock(&phy->lock);
1173 flush_work(&pl->resolve);
1174
1175 phy_disconnect(phy);
1176 }
1177}
1178EXPORT_SYMBOL_GPL(phylink_disconnect_phy);
1179
Russell King8796c892017-12-01 10:24:47 +00001180/**
1181 * phylink_mac_change() - notify phylink of a change in MAC state
1182 * @pl: a pointer to a &struct phylink returned from phylink_create()
1183 * @up: indicates whether the link is currently up.
1184 *
1185 * The MAC driver should call this driver when the state of its link
1186 * changes (eg, link failure, new negotiation results, etc.)
1187 */
Russell King9525ae82017-07-25 15:03:13 +01001188void phylink_mac_change(struct phylink *pl, bool up)
1189{
1190 if (!up)
1191 pl->mac_link_dropped = true;
1192 phylink_run_resolve(pl);
Ioana Ciornei170911802019-05-28 20:38:14 +03001193 phylink_dbg(pl, "mac link %s\n", up ? "up" : "down");
Russell King9525ae82017-07-25 15:03:13 +01001194}
1195EXPORT_SYMBOL_GPL(phylink_mac_change);
1196
Russell King7b3b0e82019-05-28 10:57:23 +01001197static irqreturn_t phylink_link_handler(int irq, void *data)
1198{
1199 struct phylink *pl = data;
1200
1201 phylink_run_resolve(pl);
1202
1203 return IRQ_HANDLED;
1204}
1205
Russell King8796c892017-12-01 10:24:47 +00001206/**
1207 * phylink_start() - start a phylink instance
1208 * @pl: a pointer to a &struct phylink returned from phylink_create()
1209 *
1210 * Start the phylink instance specified by @pl, configuring the MAC for the
1211 * desired link mode(s) and negotiation style. This should be called from the
1212 * network device driver's &struct net_device_ops ndo_open() method.
1213 */
Russell King9525ae82017-07-25 15:03:13 +01001214void phylink_start(struct phylink *pl)
1215{
Russell King5c05c1d2020-04-23 17:02:56 +01001216 bool poll = false;
1217
Russell King8b874512017-12-15 16:09:47 +00001218 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001219
Ioana Ciornei170911802019-05-28 20:38:14 +03001220 phylink_info(pl, "configuring for %s/%s link mode\n",
Russell King24cf0e62019-12-11 10:56:35 +00001221 phylink_an_mode_str(pl->cur_link_an_mode),
Ioana Ciornei170911802019-05-28 20:38:14 +03001222 phy_modes(pl->link_config.interface));
Russell King9525ae82017-07-25 15:03:13 +01001223
Antoine Tenartaeeb2e82018-09-19 11:39:31 +02001224 /* Always set the carrier off */
Ioana Ciornei43de6192019-05-28 20:38:13 +03001225 if (pl->netdev)
1226 netif_carrier_off(pl->netdev);
Antoine Tenartaeeb2e82018-09-19 11:39:31 +02001227
Russell King9525ae82017-07-25 15:03:13 +01001228 /* Apply the link configuration to the MAC when starting. This allows
1229 * a fixed-link to start with the correct parameters, and also
Colin Ian Kingcc1122b2018-03-01 10:23:03 +00001230 * ensures that we set the appropriate advertisement for Serdes links.
Russell King4c0d6d32020-03-30 18:44:55 +01001231 *
1232 * Restart autonegotiation if using 802.3z to ensure that the link
Russell King85b43942017-12-01 10:24:42 +00001233 * parameters are properly negotiated. This is necessary for DSA
1234 * switches using 802.3z negotiation to ensure they see our modes.
1235 */
Russell King4c0d6d32020-03-30 18:44:55 +01001236 phylink_mac_initial_config(pl, true);
Russell King85b43942017-12-01 10:24:42 +00001237
Russell King9525ae82017-07-25 15:03:13 +01001238 clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
1239 phylink_run_resolve(pl);
1240
Russell King24cf0e62019-12-11 10:56:35 +00001241 if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
Russell King7b3b0e82019-05-28 10:57:23 +01001242 int irq = gpiod_to_irq(pl->link_gpio);
1243
1244 if (irq > 0) {
1245 if (!request_irq(irq, phylink_link_handler,
1246 IRQF_TRIGGER_RISING |
1247 IRQF_TRIGGER_FALLING,
1248 "netdev link", pl))
1249 pl->link_irq = irq;
1250 else
1251 irq = 0;
1252 }
1253 if (irq <= 0)
Russell King5c05c1d2020-04-23 17:02:56 +01001254 poll = true;
Russell King7b3b0e82019-05-28 10:57:23 +01001255 }
Russell King5c05c1d2020-04-23 17:02:56 +01001256
1257 switch (pl->cfg_link_an_mode) {
1258 case MLO_AN_FIXED:
1259 poll |= pl->config->poll_fixed_state;
1260 break;
1261 case MLO_AN_INBAND:
1262 poll |= pl->config->pcs_poll;
Russell King7137e182020-07-21 12:04:46 +01001263 if (pl->pcs)
1264 poll |= pl->pcs->poll;
Russell King5c05c1d2020-04-23 17:02:56 +01001265 break;
1266 }
1267 if (poll)
Russell King9cd00a82018-05-10 13:17:31 -07001268 mod_timer(&pl->link_poll, jiffies + HZ);
Russell King9525ae82017-07-25 15:03:13 +01001269 if (pl->phydev)
1270 phy_start(pl->phydev);
Arseny Solokhac7fa7f52019-07-24 20:31:39 +07001271 if (pl->sfp_bus)
1272 sfp_upstream_start(pl->sfp_bus);
Russell King9525ae82017-07-25 15:03:13 +01001273}
1274EXPORT_SYMBOL_GPL(phylink_start);
1275
Russell King8796c892017-12-01 10:24:47 +00001276/**
1277 * phylink_stop() - stop a phylink instance
1278 * @pl: a pointer to a &struct phylink returned from phylink_create()
1279 *
1280 * Stop the phylink instance specified by @pl. This should be called from the
1281 * network device driver's &struct net_device_ops ndo_stop() method. The
1282 * network device's carrier state should not be changed prior to calling this
1283 * function.
1284 */
Russell King9525ae82017-07-25 15:03:13 +01001285void phylink_stop(struct phylink *pl)
1286{
Russell King8b874512017-12-15 16:09:47 +00001287 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001288
Russell Kingce0aa272017-07-25 15:03:18 +01001289 if (pl->sfp_bus)
1290 sfp_upstream_stop(pl->sfp_bus);
Arseny Solokhac7fa7f52019-07-24 20:31:39 +07001291 if (pl->phydev)
1292 phy_stop(pl->phydev);
Russell King7b3b0e82019-05-28 10:57:23 +01001293 del_timer_sync(&pl->link_poll);
1294 if (pl->link_irq) {
1295 free_irq(pl->link_irq, pl);
1296 pl->link_irq = 0;
1297 }
Russell King9525ae82017-07-25 15:03:13 +01001298
Russell King87454b62019-02-11 15:04:24 +00001299 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
Russell King9525ae82017-07-25 15:03:13 +01001300}
1301EXPORT_SYMBOL_GPL(phylink_stop);
1302
Russell King8796c892017-12-01 10:24:47 +00001303/**
1304 * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
1305 * @pl: a pointer to a &struct phylink returned from phylink_create()
1306 * @wol: a pointer to &struct ethtool_wolinfo to hold the read parameters
1307 *
1308 * Read the wake on lan parameters from the PHY attached to the phylink
1309 * instance specified by @pl. If no PHY is currently attached, report no
1310 * support for wake on lan.
1311 */
Russell King9525ae82017-07-25 15:03:13 +01001312void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
1313{
Russell King8b874512017-12-15 16:09:47 +00001314 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001315
1316 wol->supported = 0;
1317 wol->wolopts = 0;
1318
1319 if (pl->phydev)
1320 phy_ethtool_get_wol(pl->phydev, wol);
1321}
1322EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol);
1323
Russell King8796c892017-12-01 10:24:47 +00001324/**
1325 * phylink_ethtool_set_wol() - set wake on lan parameters
1326 * @pl: a pointer to a &struct phylink returned from phylink_create()
1327 * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters
1328 *
1329 * Set the wake on lan parameters for the PHY attached to the phylink
1330 * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP
1331 * error.
1332 *
1333 * Returns zero on success or negative errno code.
1334 */
Russell King9525ae82017-07-25 15:03:13 +01001335int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
1336{
1337 int ret = -EOPNOTSUPP;
1338
Russell King8b874512017-12-15 16:09:47 +00001339 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001340
1341 if (pl->phydev)
1342 ret = phy_ethtool_set_wol(pl->phydev, wol);
1343
1344 return ret;
1345}
1346EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol);
1347
1348static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b)
1349{
1350 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
1351
1352 linkmode_zero(mask);
1353 phylink_set_port_modes(mask);
1354
1355 linkmode_and(dst, dst, mask);
1356 linkmode_or(dst, dst, b);
1357}
1358
1359static void phylink_get_ksettings(const struct phylink_link_state *state,
1360 struct ethtool_link_ksettings *kset)
1361{
1362 phylink_merge_link_mode(kset->link_modes.advertising, state->advertising);
1363 linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising);
1364 kset->base.speed = state->speed;
1365 kset->base.duplex = state->duplex;
1366 kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE :
1367 AUTONEG_DISABLE;
1368}
1369
Russell King8796c892017-12-01 10:24:47 +00001370/**
1371 * phylink_ethtool_ksettings_get() - get the current link settings
1372 * @pl: a pointer to a &struct phylink returned from phylink_create()
1373 * @kset: a pointer to a &struct ethtool_link_ksettings to hold link settings
1374 *
1375 * Read the current link settings for the phylink instance specified by @pl.
1376 * This will be the link settings read from the MAC, PHY or fixed link
1377 * settings depending on the current negotiation mode.
1378 */
Russell King9525ae82017-07-25 15:03:13 +01001379int phylink_ethtool_ksettings_get(struct phylink *pl,
Florian Fainelli516b29e2017-10-30 21:42:57 -07001380 struct ethtool_link_ksettings *kset)
Russell King9525ae82017-07-25 15:03:13 +01001381{
1382 struct phylink_link_state link_state;
1383
Russell King8b874512017-12-15 16:09:47 +00001384 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001385
1386 if (pl->phydev) {
1387 phy_ethtool_ksettings_get(pl->phydev, kset);
1388 } else {
1389 kset->base.port = pl->link_port;
1390 }
1391
1392 linkmode_copy(kset->link_modes.supported, pl->supported);
1393
Russell King24cf0e62019-12-11 10:56:35 +00001394 switch (pl->cur_link_an_mode) {
Russell King9525ae82017-07-25 15:03:13 +01001395 case MLO_AN_FIXED:
1396 /* We are using fixed settings. Report these as the
1397 * current link settings - and note that these also
1398 * represent the supported speeds/duplex/pause modes.
1399 */
1400 phylink_get_fixed_state(pl, &link_state);
1401 phylink_get_ksettings(&link_state, kset);
1402 break;
1403
Russell King86a362c2017-12-01 10:24:26 +00001404 case MLO_AN_INBAND:
Russell King9525ae82017-07-25 15:03:13 +01001405 /* If there is a phy attached, then use the reported
1406 * settings from the phy with no modification.
1407 */
1408 if (pl->phydev)
1409 break;
1410
Russell Kingd46b7e42019-11-21 00:36:22 +00001411 phylink_mac_pcs_get_state(pl, &link_state);
Russell King9525ae82017-07-25 15:03:13 +01001412
1413 /* The MAC is reporting the link results from its own PCS
1414 * layer via in-band status. Report these as the current
1415 * link settings.
1416 */
1417 phylink_get_ksettings(&link_state, kset);
1418 break;
1419 }
1420
1421 return 0;
1422}
1423EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
1424
Russell King8796c892017-12-01 10:24:47 +00001425/**
1426 * phylink_ethtool_ksettings_set() - set the link settings
1427 * @pl: a pointer to a &struct phylink returned from phylink_create()
1428 * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes
1429 */
Russell King9525ae82017-07-25 15:03:13 +01001430int phylink_ethtool_ksettings_set(struct phylink *pl,
Florian Fainelli516b29e2017-10-30 21:42:57 -07001431 const struct ethtool_link_ksettings *kset)
Russell King9525ae82017-07-25 15:03:13 +01001432{
Russell King77316762019-06-02 15:12:54 +01001433 __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
Russell King9525ae82017-07-25 15:03:13 +01001434 struct phylink_link_state config;
Russell Kingc8cab712020-07-21 12:04:16 +01001435 const struct phy_setting *s;
Russell King9525ae82017-07-25 15:03:13 +01001436
Russell King8b874512017-12-15 16:09:47 +00001437 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001438
Russell Kingcbc1bb12020-07-21 12:04:21 +01001439 if (pl->phydev) {
1440 /* We can rely on phylib for this update; we also do not need
1441 * to update the pl->link_config settings:
1442 * - the configuration returned via ksettings_get() will come
1443 * from phylib whenever a PHY is present.
1444 * - link_config.interface will be updated by the PHY calling
1445 * back via phylink_phy_change() and a subsequent resolve.
1446 * - initial link configuration for PHY mode comes from the
1447 * last phy state updated via phylink_phy_change().
1448 * - other configuration changes (e.g. pause modes) are
1449 * performed directly via phylib.
1450 * - if in in-band mode with a PHY, the link configuration
1451 * is passed on the link from the PHY, and all of
1452 * link_config.{speed,duplex,an_enabled,pause} are not used.
1453 * - the only possible use would be link_config.advertising
1454 * pause modes when in 1000base-X mode with a PHY, but in
1455 * the presence of a PHY, this should not be changed as that
1456 * should be determined from the media side advertisement.
1457 */
1458 return phy_ethtool_ksettings_set(pl->phydev, kset);
1459 }
1460
Russell King77316762019-06-02 15:12:54 +01001461 linkmode_copy(support, pl->supported);
Russell King9525ae82017-07-25 15:03:13 +01001462 config = pl->link_config;
Russell Kingc8cab712020-07-21 12:04:16 +01001463 config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE;
Russell King9525ae82017-07-25 15:03:13 +01001464
Russell Kingc8cab712020-07-21 12:04:16 +01001465 /* Mask out unsupported advertisements, and force the autoneg bit */
Russell King9525ae82017-07-25 15:03:13 +01001466 linkmode_and(config.advertising, kset->link_modes.advertising,
Russell King77316762019-06-02 15:12:54 +01001467 support);
Russell Kingc8cab712020-07-21 12:04:16 +01001468 linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising,
1469 config.an_enabled);
Russell King9525ae82017-07-25 15:03:13 +01001470
1471 /* FIXME: should we reject autoneg if phy/mac does not support it? */
Russell Kingc8cab712020-07-21 12:04:16 +01001472 switch (kset->base.autoneg) {
1473 case AUTONEG_DISABLE:
Russell King9525ae82017-07-25 15:03:13 +01001474 /* Autonegotiation disabled, select a suitable speed and
1475 * duplex.
1476 */
1477 s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
Russell King77316762019-06-02 15:12:54 +01001478 support, false);
Russell King9525ae82017-07-25 15:03:13 +01001479 if (!s)
1480 return -EINVAL;
1481
Russell King1e1bf142020-07-21 12:04:31 +01001482 /* If we have a fixed link, refuse to change link parameters.
1483 * If the link parameters match, accept them but do nothing.
Russell King9525ae82017-07-25 15:03:13 +01001484 */
Russell King1e1bf142020-07-21 12:04:31 +01001485 if (pl->cur_link_an_mode == MLO_AN_FIXED) {
1486 if (s->speed != pl->link_config.speed ||
1487 s->duplex != pl->link_config.duplex)
1488 return -EINVAL;
1489 return 0;
1490 }
Russell King9525ae82017-07-25 15:03:13 +01001491
1492 config.speed = s->speed;
1493 config.duplex = s->duplex;
Russell Kingc8cab712020-07-21 12:04:16 +01001494 break;
Russell King9525ae82017-07-25 15:03:13 +01001495
Russell Kingc8cab712020-07-21 12:04:16 +01001496 case AUTONEG_ENABLE:
Russell King1e1bf142020-07-21 12:04:31 +01001497 /* If we have a fixed link, allow autonegotiation (since that
1498 * is our default case) but do not allow the advertisement to
1499 * be changed. If the advertisement matches, simply return.
1500 */
1501 if (pl->cur_link_an_mode == MLO_AN_FIXED) {
1502 if (!linkmode_equal(config.advertising,
1503 pl->link_config.advertising))
1504 return -EINVAL;
1505 return 0;
1506 }
Russell King9525ae82017-07-25 15:03:13 +01001507
1508 config.speed = SPEED_UNKNOWN;
1509 config.duplex = DUPLEX_UNKNOWN;
Russell Kingc8cab712020-07-21 12:04:16 +01001510 break;
Russell King9525ae82017-07-25 15:03:13 +01001511
Russell Kingc8cab712020-07-21 12:04:16 +01001512 default:
1513 return -EINVAL;
Russell King9525ae82017-07-25 15:03:13 +01001514 }
1515
Russell King1e1bf142020-07-21 12:04:31 +01001516 /* We have ruled out the case with a PHY attached, and the
1517 * fixed-link cases. All that is left are in-band links.
Russell Kingcbc1bb12020-07-21 12:04:21 +01001518 */
1519 if (phylink_validate(pl, support, &config))
1520 return -EINVAL;
1521
1522 /* If autonegotiation is enabled, we must have an advertisement */
1523 if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
1524 return -EINVAL;
1525
1526 mutex_lock(&pl->state_mutex);
Russell Kingcbc1bb12020-07-21 12:04:21 +01001527 pl->link_config.speed = config.speed;
1528 pl->link_config.duplex = config.duplex;
Russell Kinga83c8822020-07-21 12:04:26 +01001529 pl->link_config.an_enabled = config.an_enabled;
Russell Kingcbc1bb12020-07-21 12:04:21 +01001530
Russell Kingb7ad14c2020-07-21 12:04:41 +01001531 if (pl->link_config.interface != config.interface) {
1532 /* The interface changed, e.g. 1000base-X <-> 2500base-X */
1533 /* We need to force the link down, then change the interface */
1534 if (pl->old_link_state) {
1535 phylink_link_down(pl);
1536 pl->old_link_state = false;
1537 }
1538 if (!test_bit(PHYLINK_DISABLE_STOPPED,
1539 &pl->phylink_disable_state))
1540 phylink_major_config(pl, false, &config);
1541 pl->link_config.interface = config.interface;
1542 linkmode_copy(pl->link_config.advertising, config.advertising);
1543 } else if (!linkmode_equal(pl->link_config.advertising,
1544 config.advertising)) {
1545 linkmode_copy(pl->link_config.advertising, config.advertising);
1546 phylink_change_inband_advert(pl);
Russell King9525ae82017-07-25 15:03:13 +01001547 }
Russell Kingcbc1bb12020-07-21 12:04:21 +01001548 mutex_unlock(&pl->state_mutex);
Russell King9525ae82017-07-25 15:03:13 +01001549
Dan Carpenterd18c2a12017-08-10 00:35:50 +03001550 return 0;
Russell King9525ae82017-07-25 15:03:13 +01001551}
1552EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_set);
1553
Russell King8796c892017-12-01 10:24:47 +00001554/**
1555 * phylink_ethtool_nway_reset() - restart negotiation
1556 * @pl: a pointer to a &struct phylink returned from phylink_create()
1557 *
1558 * Restart negotiation for the phylink instance specified by @pl. This will
1559 * cause any attached phy to restart negotiation with the link partner, and
1560 * if the MAC is in a BaseX mode, the MAC will also be requested to restart
1561 * negotiation.
1562 *
1563 * Returns zero on success, or negative error code.
1564 */
Russell King9525ae82017-07-25 15:03:13 +01001565int phylink_ethtool_nway_reset(struct phylink *pl)
1566{
1567 int ret = 0;
1568
Russell King8b874512017-12-15 16:09:47 +00001569 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001570
1571 if (pl->phydev)
1572 ret = phy_restart_aneg(pl->phydev);
Russell King4c0d6d32020-03-30 18:44:55 +01001573 phylink_mac_pcs_an_restart(pl);
Russell King9525ae82017-07-25 15:03:13 +01001574
1575 return ret;
1576}
1577EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset);
1578
Russell King8796c892017-12-01 10:24:47 +00001579/**
1580 * phylink_ethtool_get_pauseparam() - get the current pause parameters
1581 * @pl: a pointer to a &struct phylink returned from phylink_create()
1582 * @pause: a pointer to a &struct ethtool_pauseparam
1583 */
Russell King9525ae82017-07-25 15:03:13 +01001584void phylink_ethtool_get_pauseparam(struct phylink *pl,
1585 struct ethtool_pauseparam *pause)
1586{
Russell King8b874512017-12-15 16:09:47 +00001587 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001588
1589 pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN);
1590 pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX);
1591 pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX);
1592}
1593EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam);
1594
Russell King8796c892017-12-01 10:24:47 +00001595/**
1596 * phylink_ethtool_set_pauseparam() - set the current pause parameters
1597 * @pl: a pointer to a &struct phylink returned from phylink_create()
1598 * @pause: a pointer to a &struct ethtool_pauseparam
1599 */
Russell King9525ae82017-07-25 15:03:13 +01001600int phylink_ethtool_set_pauseparam(struct phylink *pl,
1601 struct ethtool_pauseparam *pause)
1602{
1603 struct phylink_link_state *config = &pl->link_config;
Russell King2e919bc2020-06-23 17:47:29 +01001604 bool manual_changed;
1605 int pause_state;
Russell King9525ae82017-07-25 15:03:13 +01001606
Russell King8b874512017-12-15 16:09:47 +00001607 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001608
Russell King8cdfa252020-02-15 15:49:37 +00001609 if (pl->cur_link_an_mode == MLO_AN_FIXED)
1610 return -EOPNOTSUPP;
1611
Russell King9525ae82017-07-25 15:03:13 +01001612 if (!phylink_test(pl->supported, Pause) &&
1613 !phylink_test(pl->supported, Asym_Pause))
1614 return -EOPNOTSUPP;
1615
1616 if (!phylink_test(pl->supported, Asym_Pause) &&
1617 !pause->autoneg && pause->rx_pause != pause->tx_pause)
1618 return -EINVAL;
1619
Russell King2e919bc2020-06-23 17:47:29 +01001620 pause_state = 0;
Russell King9525ae82017-07-25 15:03:13 +01001621 if (pause->autoneg)
Russell King2e919bc2020-06-23 17:47:29 +01001622 pause_state |= MLO_PAUSE_AN;
Russell King9525ae82017-07-25 15:03:13 +01001623 if (pause->rx_pause)
Russell King2e919bc2020-06-23 17:47:29 +01001624 pause_state |= MLO_PAUSE_RX;
Russell King9525ae82017-07-25 15:03:13 +01001625 if (pause->tx_pause)
Russell King2e919bc2020-06-23 17:47:29 +01001626 pause_state |= MLO_PAUSE_TX;
Russell King9525ae82017-07-25 15:03:13 +01001627
Russell King2e919bc2020-06-23 17:47:29 +01001628 mutex_lock(&pl->state_mutex);
Russell Kingf904f152020-02-15 15:49:58 +00001629 /*
1630 * See the comments for linkmode_set_pause(), wrt the deficiencies
1631 * with the current implementation. A solution to this issue would
1632 * be:
1633 * ethtool Local device
1634 * rx tx Pause AsymDir
1635 * 0 0 0 0
1636 * 1 0 1 1
1637 * 0 1 0 1
1638 * 1 1 1 1
1639 * and then use the ethtool rx/tx enablement status to mask the
1640 * rx/tx pause resolution.
1641 */
1642 linkmode_set_pause(config->advertising, pause->tx_pause,
1643 pause->rx_pause);
1644
Russell King2e919bc2020-06-23 17:47:29 +01001645 manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN ||
1646 (!(pause_state & MLO_PAUSE_AN) &&
1647 (config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK);
1648
1649 config->pause = pause_state;
1650
Russell King1571e702020-07-21 12:04:36 +01001651 /* Update our in-band advertisement, triggering a renegotiation if
1652 * the advertisement changed.
1653 */
1654 if (!pl->phydev)
1655 phylink_change_inband_advert(pl);
Russell Kingc718af22020-06-23 17:47:23 +01001656
1657 mutex_unlock(&pl->state_mutex);
1658
1659 /* If we have a PHY, a change of the pause frame advertisement will
1660 * cause phylib to renegotiate (if AN is enabled) which will in turn
1661 * call our phylink_phy_change() and trigger a resolve. Note that
1662 * we can't hold our state mutex while calling phy_set_asym_pause().
Russell Kingd9922c02019-11-19 17:28:14 +00001663 */
Russell Kingc718af22020-06-23 17:47:23 +01001664 if (pl->phydev)
Russell Kingd9922c02019-11-19 17:28:14 +00001665 phy_set_asym_pause(pl->phydev, pause->rx_pause,
1666 pause->tx_pause);
Russell King9525ae82017-07-25 15:03:13 +01001667
Russell King2e919bc2020-06-23 17:47:29 +01001668 /* If the manual pause settings changed, make sure we trigger a
1669 * resolve to update their state; we can not guarantee that the
1670 * link will cycle.
1671 */
1672 if (manual_changed) {
1673 pl->mac_link_dropped = true;
1674 phylink_run_resolve(pl);
Russell King9525ae82017-07-25 15:03:13 +01001675 }
Russell King9525ae82017-07-25 15:03:13 +01001676
1677 return 0;
1678}
1679EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);
1680
1681/**
Mauro Carvalho Chehab69280222020-11-16 11:17:57 +01001682 * phylink_get_eee_err() - read the energy efficient ethernet error
Russell King9525ae82017-07-25 15:03:13 +01001683 * counter
1684 * @pl: a pointer to a &struct phylink returned from phylink_create().
1685 *
1686 * Read the Energy Efficient Ethernet error counter from the PHY associated
1687 * with the phylink instance specified by @pl.
1688 *
1689 * Returns positive error counter value, or negative error code.
1690 */
1691int phylink_get_eee_err(struct phylink *pl)
1692{
1693 int ret = 0;
1694
Russell King8b874512017-12-15 16:09:47 +00001695 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001696
1697 if (pl->phydev)
1698 ret = phy_get_eee_err(pl->phydev);
1699
1700 return ret;
1701}
1702EXPORT_SYMBOL_GPL(phylink_get_eee_err);
1703
Russell King8796c892017-12-01 10:24:47 +00001704/**
Russell King86e58132019-02-11 11:46:06 +00001705 * phylink_init_eee() - init and check the EEE features
1706 * @pl: a pointer to a &struct phylink returned from phylink_create()
1707 * @clk_stop_enable: allow PHY to stop receive clock
1708 *
1709 * Must be called either with RTNL held or within mac_link_up()
1710 */
1711int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
1712{
1713 int ret = -EOPNOTSUPP;
1714
1715 if (pl->phydev)
1716 ret = phy_init_eee(pl->phydev, clk_stop_enable);
1717
1718 return ret;
1719}
1720EXPORT_SYMBOL_GPL(phylink_init_eee);
1721
1722/**
Russell King8796c892017-12-01 10:24:47 +00001723 * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
1724 * @pl: a pointer to a &struct phylink returned from phylink_create()
1725 * @eee: a pointer to a &struct ethtool_eee for the read parameters
1726 */
Russell King9525ae82017-07-25 15:03:13 +01001727int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_eee *eee)
1728{
1729 int ret = -EOPNOTSUPP;
1730
Russell King8b874512017-12-15 16:09:47 +00001731 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001732
1733 if (pl->phydev)
1734 ret = phy_ethtool_get_eee(pl->phydev, eee);
1735
1736 return ret;
1737}
1738EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee);
1739
Russell King8796c892017-12-01 10:24:47 +00001740/**
1741 * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters
1742 * @pl: a pointer to a &struct phylink returned from phylink_create()
1743 * @eee: a pointer to a &struct ethtool_eee for the desired parameters
1744 */
Russell King9525ae82017-07-25 15:03:13 +01001745int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_eee *eee)
1746{
1747 int ret = -EOPNOTSUPP;
1748
Russell King8b874512017-12-15 16:09:47 +00001749 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001750
1751 if (pl->phydev)
1752 ret = phy_ethtool_set_eee(pl->phydev, eee);
1753
1754 return ret;
1755}
1756EXPORT_SYMBOL_GPL(phylink_ethtool_set_eee);
1757
1758/* This emulates MII registers for a fixed-mode phy operating as per the
1759 * passed in state. "aneg" defines if we report negotiation is possible.
1760 *
1761 * FIXME: should deal with negotiation state too.
1762 */
Russell King7fdc4552019-05-28 10:57:18 +01001763static int phylink_mii_emul_read(unsigned int reg,
1764 struct phylink_link_state *state)
Russell King9525ae82017-07-25 15:03:13 +01001765{
1766 struct fixed_phy_status fs;
Russell King4e5aeb42020-02-15 15:49:53 +00001767 unsigned long *lpa = state->lp_advertising;
Russell King9525ae82017-07-25 15:03:13 +01001768 int val;
1769
1770 fs.link = state->link;
1771 fs.speed = state->speed;
1772 fs.duplex = state->duplex;
Russell King4e5aeb42020-02-15 15:49:53 +00001773 fs.pause = test_bit(ETHTOOL_LINK_MODE_Pause_BIT, lpa);
1774 fs.asym_pause = test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, lpa);
Russell King9525ae82017-07-25 15:03:13 +01001775
1776 val = swphy_read_reg(reg, &fs);
1777 if (reg == MII_BMSR) {
1778 if (!state->an_complete)
1779 val &= ~BMSR_ANEGCOMPLETE;
Russell King9525ae82017-07-25 15:03:13 +01001780 }
1781 return val;
1782}
1783
Russell Kingecbd87b2017-07-25 15:03:28 +01001784static int phylink_phy_read(struct phylink *pl, unsigned int phy_id,
1785 unsigned int reg)
1786{
1787 struct phy_device *phydev = pl->phydev;
1788 int prtad, devad;
1789
1790 if (mdio_phy_id_is_c45(phy_id)) {
1791 prtad = mdio_phy_id_prtad(phy_id);
1792 devad = mdio_phy_id_devad(phy_id);
Russell King90ce6652020-05-26 16:29:36 +01001793 devad = mdiobus_c45_addr(devad, reg);
Russell Kingecbd87b2017-07-25 15:03:28 +01001794 } else if (phydev->is_c45) {
1795 switch (reg) {
1796 case MII_BMCR:
1797 case MII_BMSR:
1798 case MII_PHYSID1:
1799 case MII_PHYSID2:
Russell King320ed3b2020-06-18 14:46:08 +01001800 devad = __ffs(phydev->c45_ids.mmds_present);
Russell Kingecbd87b2017-07-25 15:03:28 +01001801 break;
1802 case MII_ADVERTISE:
1803 case MII_LPA:
Russell King320ed3b2020-06-18 14:46:08 +01001804 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
Russell Kingecbd87b2017-07-25 15:03:28 +01001805 return -EINVAL;
1806 devad = MDIO_MMD_AN;
1807 if (reg == MII_ADVERTISE)
1808 reg = MDIO_AN_ADVERTISE;
1809 else
1810 reg = MDIO_AN_LPA;
1811 break;
1812 default:
1813 return -EINVAL;
1814 }
1815 prtad = phy_id;
Russell King90ce6652020-05-26 16:29:36 +01001816 devad = mdiobus_c45_addr(devad, reg);
Russell Kingecbd87b2017-07-25 15:03:28 +01001817 } else {
1818 prtad = phy_id;
1819 devad = reg;
1820 }
1821 return mdiobus_read(pl->phydev->mdio.bus, prtad, devad);
1822}
1823
1824static int phylink_phy_write(struct phylink *pl, unsigned int phy_id,
1825 unsigned int reg, unsigned int val)
1826{
1827 struct phy_device *phydev = pl->phydev;
1828 int prtad, devad;
1829
1830 if (mdio_phy_id_is_c45(phy_id)) {
1831 prtad = mdio_phy_id_prtad(phy_id);
1832 devad = mdio_phy_id_devad(phy_id);
Russell King90ce6652020-05-26 16:29:36 +01001833 devad = mdiobus_c45_addr(devad, reg);
Russell Kingecbd87b2017-07-25 15:03:28 +01001834 } else if (phydev->is_c45) {
1835 switch (reg) {
1836 case MII_BMCR:
1837 case MII_BMSR:
1838 case MII_PHYSID1:
1839 case MII_PHYSID2:
Russell King320ed3b2020-06-18 14:46:08 +01001840 devad = __ffs(phydev->c45_ids.mmds_present);
Russell Kingecbd87b2017-07-25 15:03:28 +01001841 break;
1842 case MII_ADVERTISE:
1843 case MII_LPA:
Russell King320ed3b2020-06-18 14:46:08 +01001844 if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
Russell Kingecbd87b2017-07-25 15:03:28 +01001845 return -EINVAL;
1846 devad = MDIO_MMD_AN;
1847 if (reg == MII_ADVERTISE)
1848 reg = MDIO_AN_ADVERTISE;
1849 else
1850 reg = MDIO_AN_LPA;
1851 break;
1852 default:
1853 return -EINVAL;
1854 }
1855 prtad = phy_id;
Russell King90ce6652020-05-26 16:29:36 +01001856 devad = mdiobus_c45_addr(devad, reg);
Russell Kingecbd87b2017-07-25 15:03:28 +01001857 } else {
1858 prtad = phy_id;
1859 devad = reg;
1860 }
1861
1862 return mdiobus_write(phydev->mdio.bus, prtad, devad, val);
1863}
1864
Russell King9525ae82017-07-25 15:03:13 +01001865static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
1866 unsigned int reg)
1867{
1868 struct phylink_link_state state;
1869 int val = 0xffff;
1870
Russell King24cf0e62019-12-11 10:56:35 +00001871 switch (pl->cur_link_an_mode) {
Russell King9525ae82017-07-25 15:03:13 +01001872 case MLO_AN_FIXED:
1873 if (phy_id == 0) {
1874 phylink_get_fixed_state(pl, &state);
Russell King7fdc4552019-05-28 10:57:18 +01001875 val = phylink_mii_emul_read(reg, &state);
Russell King9525ae82017-07-25 15:03:13 +01001876 }
1877 break;
1878
1879 case MLO_AN_PHY:
1880 return -EOPNOTSUPP;
1881
Russell King86a362c2017-12-01 10:24:26 +00001882 case MLO_AN_INBAND:
Russell King9525ae82017-07-25 15:03:13 +01001883 if (phy_id == 0) {
Russell Kingd46b7e42019-11-21 00:36:22 +00001884 phylink_mac_pcs_get_state(pl, &state);
Russell King7fdc4552019-05-28 10:57:18 +01001885 val = phylink_mii_emul_read(reg, &state);
Russell King9525ae82017-07-25 15:03:13 +01001886 }
1887 break;
1888 }
1889
1890 return val & 0xffff;
1891}
1892
1893static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
1894 unsigned int reg, unsigned int val)
1895{
Russell King24cf0e62019-12-11 10:56:35 +00001896 switch (pl->cur_link_an_mode) {
Russell King9525ae82017-07-25 15:03:13 +01001897 case MLO_AN_FIXED:
1898 break;
1899
1900 case MLO_AN_PHY:
1901 return -EOPNOTSUPP;
1902
Russell King86a362c2017-12-01 10:24:26 +00001903 case MLO_AN_INBAND:
Russell King9525ae82017-07-25 15:03:13 +01001904 break;
1905 }
1906
1907 return 0;
1908}
1909
Russell King8796c892017-12-01 10:24:47 +00001910/**
1911 * phylink_mii_ioctl() - generic mii ioctl interface
1912 * @pl: a pointer to a &struct phylink returned from phylink_create()
1913 * @ifr: a pointer to a &struct ifreq for socket ioctls
1914 * @cmd: ioctl cmd to execute
1915 *
1916 * Perform the specified MII ioctl on the PHY attached to the phylink instance
1917 * specified by @pl. If no PHY is attached, emulate the presence of the PHY.
1918 *
1919 * Returns: zero on success or negative error code.
1920 *
1921 * %SIOCGMIIPHY:
1922 * read register from the current PHY.
1923 * %SIOCGMIIREG:
1924 * read register from the specified PHY.
1925 * %SIOCSMIIREG:
1926 * set a register on the specified PHY.
1927 */
Russell King9525ae82017-07-25 15:03:13 +01001928int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd)
1929{
Russell Kingecbd87b2017-07-25 15:03:28 +01001930 struct mii_ioctl_data *mii = if_mii(ifr);
1931 int ret;
Russell King9525ae82017-07-25 15:03:13 +01001932
Russell King8b874512017-12-15 16:09:47 +00001933 ASSERT_RTNL();
Russell King9525ae82017-07-25 15:03:13 +01001934
Russell Kingecbd87b2017-07-25 15:03:28 +01001935 if (pl->phydev) {
Russell King86a362c2017-12-01 10:24:26 +00001936 /* PHYs only exist for MLO_AN_PHY and SGMII */
Russell Kingecbd87b2017-07-25 15:03:28 +01001937 switch (cmd) {
1938 case SIOCGMIIPHY:
1939 mii->phy_id = pl->phydev->mdio.addr;
Gustavo A. R. Silvadf561f662020-08-23 17:36:59 -05001940 fallthrough;
Russell King9525ae82017-07-25 15:03:13 +01001941
Russell Kingecbd87b2017-07-25 15:03:28 +01001942 case SIOCGMIIREG:
1943 ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num);
1944 if (ret >= 0) {
1945 mii->val_out = ret;
1946 ret = 0;
1947 }
1948 break;
Russell King9525ae82017-07-25 15:03:13 +01001949
Russell Kingecbd87b2017-07-25 15:03:28 +01001950 case SIOCSMIIREG:
1951 ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num,
1952 mii->val_in);
1953 break;
Russell King9525ae82017-07-25 15:03:13 +01001954
Russell Kingecbd87b2017-07-25 15:03:28 +01001955 default:
Russell King9525ae82017-07-25 15:03:13 +01001956 ret = phy_mii_ioctl(pl->phydev, ifr, cmd);
Russell Kingecbd87b2017-07-25 15:03:28 +01001957 break;
1958 }
1959 } else {
1960 switch (cmd) {
1961 case SIOCGMIIPHY:
1962 mii->phy_id = 0;
Gustavo A. R. Silvadf561f662020-08-23 17:36:59 -05001963 fallthrough;
Russell Kingecbd87b2017-07-25 15:03:28 +01001964
1965 case SIOCGMIIREG:
1966 ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num);
1967 if (ret >= 0) {
1968 mii->val_out = ret;
1969 ret = 0;
1970 }
1971 break;
1972
1973 case SIOCSMIIREG:
1974 ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num,
1975 mii->val_in);
1976 break;
1977
1978 default:
1979 ret = -EOPNOTSUPP;
1980 break;
1981 }
Russell King9525ae82017-07-25 15:03:13 +01001982 }
1983
1984 return ret;
1985}
1986EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
1987
Russell Kingc6d5d842020-06-24 11:06:54 +01001988/**
1989 * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
1990 * link partners
1991 * @pl: a pointer to a &struct phylink returned from phylink_create()
1992 * @sync: perform action synchronously
1993 *
1994 * If we have a PHY that is not part of a SFP module, then set the speed
1995 * as described in the phy_speed_down() function. Please see this function
1996 * for a description of the @sync parameter.
1997 *
1998 * Returns zero if there is no PHY, otherwise as per phy_speed_down().
1999 */
2000int phylink_speed_down(struct phylink *pl, bool sync)
2001{
2002 int ret = 0;
2003
2004 ASSERT_RTNL();
2005
2006 if (!pl->sfp_bus && pl->phydev)
2007 ret = phy_speed_down(pl->phydev, sync);
2008
2009 return ret;
2010}
2011EXPORT_SYMBOL_GPL(phylink_speed_down);
2012
2013/**
2014 * phylink_speed_up() - restore the advertised speeds prior to the call to
2015 * phylink_speed_down()
2016 * @pl: a pointer to a &struct phylink returned from phylink_create()
2017 *
2018 * If we have a PHY that is not part of a SFP module, then restore the
2019 * PHY speeds as per phy_speed_up().
2020 *
2021 * Returns zero if there is no PHY, otherwise as per phy_speed_up().
2022 */
2023int phylink_speed_up(struct phylink *pl)
2024{
2025 int ret = 0;
2026
2027 ASSERT_RTNL();
2028
2029 if (!pl->sfp_bus && pl->phydev)
2030 ret = phy_speed_up(pl->phydev);
2031
2032 return ret;
2033}
2034EXPORT_SYMBOL_GPL(phylink_speed_up);
2035
Russell King320587e62019-05-28 10:57:34 +01002036static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus)
2037{
2038 struct phylink *pl = upstream;
2039
2040 pl->netdev->sfp_bus = bus;
2041}
2042
2043static void phylink_sfp_detach(void *upstream, struct sfp_bus *bus)
2044{
2045 struct phylink *pl = upstream;
2046
2047 pl->netdev->sfp_bus = NULL;
2048}
2049
Russell King52c95602019-12-11 10:56:45 +00002050static int phylink_sfp_config(struct phylink *pl, u8 mode,
Russell Kingc0de2f42019-12-11 10:56:40 +00002051 const unsigned long *supported,
2052 const unsigned long *advertising)
Russell Kingce0aa272017-07-25 15:03:18 +01002053{
Russell King77316762019-06-02 15:12:54 +01002054 __ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
Russell Kingc0de2f42019-12-11 10:56:40 +00002055 __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
Russell Kingce0aa272017-07-25 15:03:18 +01002056 struct phylink_link_state config;
2057 phy_interface_t iface;
Russell Kingce0aa272017-07-25 15:03:18 +01002058 bool changed;
Russell Kingc0de2f42019-12-11 10:56:40 +00002059 int ret;
Russell Kingce0aa272017-07-25 15:03:18 +01002060
Russell Kingc0de2f42019-12-11 10:56:40 +00002061 linkmode_copy(support, supported);
Russell Kingce0aa272017-07-25 15:03:18 +01002062
2063 memset(&config, 0, sizeof(config));
Russell Kingc0de2f42019-12-11 10:56:40 +00002064 linkmode_copy(config.advertising, advertising);
Russell Kinga9c79362018-02-27 15:53:02 +00002065 config.interface = PHY_INTERFACE_MODE_NA;
Russell Kingce0aa272017-07-25 15:03:18 +01002066 config.speed = SPEED_UNKNOWN;
2067 config.duplex = DUPLEX_UNKNOWN;
2068 config.pause = MLO_PAUSE_AN;
2069 config.an_enabled = pl->link_config.an_enabled;
2070
2071 /* Ignore errors if we're expecting a PHY to attach later */
2072 ret = phylink_validate(pl, support, &config);
2073 if (ret) {
Ioana Ciornei170911802019-05-28 20:38:14 +03002074 phylink_err(pl, "validation with support %*pb failed: %d\n",
2075 __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
Russell Kinga9c79362018-02-27 15:53:02 +00002076 return ret;
2077 }
2078
Russell Kinga4516c72019-12-11 10:55:59 +00002079 iface = sfp_select_interface(pl->sfp_bus, config.advertising);
Russell Kinga9c79362018-02-27 15:53:02 +00002080 if (iface == PHY_INTERFACE_MODE_NA) {
Ioana Ciornei170911802019-05-28 20:38:14 +03002081 phylink_err(pl,
2082 "selection of interface failed, advertisement %*pb\n",
2083 __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
Russell Kinga9c79362018-02-27 15:53:02 +00002084 return -EINVAL;
2085 }
2086
2087 config.interface = iface;
Russell Kingc0de2f42019-12-11 10:56:40 +00002088 linkmode_copy(support1, support);
Russell King77316762019-06-02 15:12:54 +01002089 ret = phylink_validate(pl, support1, &config);
Russell Kinga9c79362018-02-27 15:53:02 +00002090 if (ret) {
Ioana Ciornei170911802019-05-28 20:38:14 +03002091 phylink_err(pl, "validation of %s/%s with support %*pb failed: %d\n",
Russell Kingc0de2f42019-12-11 10:56:40 +00002092 phylink_an_mode_str(mode),
Ioana Ciornei170911802019-05-28 20:38:14 +03002093 phy_modes(config.interface),
2094 __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
Russell Kingce0aa272017-07-25 15:03:18 +01002095 return ret;
2096 }
2097
Ioana Ciornei170911802019-05-28 20:38:14 +03002098 phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n",
Russell Kingc0de2f42019-12-11 10:56:40 +00002099 phylink_an_mode_str(mode), phy_modes(config.interface),
Ioana Ciornei170911802019-05-28 20:38:14 +03002100 __ETHTOOL_LINK_MODE_MASK_NBITS, support);
Russell Kingce0aa272017-07-25 15:03:18 +01002101
Russell King86a362c2017-12-01 10:24:26 +00002102 if (phy_interface_mode_is_8023z(iface) && pl->phydev)
Russell Kingce0aa272017-07-25 15:03:18 +01002103 return -EINVAL;
2104
Russell King554032c2019-10-15 11:28:46 +01002105 changed = !linkmode_equal(pl->supported, support);
Russell Kingce0aa272017-07-25 15:03:18 +01002106 if (changed) {
2107 linkmode_copy(pl->supported, support);
2108 linkmode_copy(pl->link_config.advertising, config.advertising);
2109 }
2110
Russell Kingc0de2f42019-12-11 10:56:40 +00002111 if (pl->cur_link_an_mode != mode ||
Russell Kingce0aa272017-07-25 15:03:18 +01002112 pl->link_config.interface != config.interface) {
2113 pl->link_config.interface = config.interface;
Russell Kingc0de2f42019-12-11 10:56:40 +00002114 pl->cur_link_an_mode = mode;
Russell Kingce0aa272017-07-25 15:03:18 +01002115
2116 changed = true;
2117
Ioana Ciornei170911802019-05-28 20:38:14 +03002118 phylink_info(pl, "switched to %s/%s link mode\n",
Russell Kingc0de2f42019-12-11 10:56:40 +00002119 phylink_an_mode_str(mode),
Ioana Ciornei170911802019-05-28 20:38:14 +03002120 phy_modes(config.interface));
Russell Kingce0aa272017-07-25 15:03:18 +01002121 }
2122
Russell King52c95602019-12-11 10:56:45 +00002123 pl->link_port = pl->sfp_port;
Russell Kingce0aa272017-07-25 15:03:18 +01002124
2125 if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
2126 &pl->phylink_disable_state))
Russell King4c0d6d32020-03-30 18:44:55 +01002127 phylink_mac_initial_config(pl, false);
Russell Kingce0aa272017-07-25 15:03:18 +01002128
2129 return ret;
2130}
2131
Russell Kingc0de2f42019-12-11 10:56:40 +00002132static int phylink_sfp_module_insert(void *upstream,
2133 const struct sfp_eeprom_id *id)
2134{
2135 struct phylink *pl = upstream;
Russell King52c95602019-12-11 10:56:45 +00002136 unsigned long *support = pl->sfp_support;
Russell Kingc0de2f42019-12-11 10:56:40 +00002137
2138 ASSERT_RTNL();
2139
Russell King52c95602019-12-11 10:56:45 +00002140 linkmode_zero(support);
Russell Kingc0de2f42019-12-11 10:56:40 +00002141 sfp_parse_support(pl->sfp_bus, id, support);
Russell King52c95602019-12-11 10:56:45 +00002142 pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, support);
Russell Kingc0de2f42019-12-11 10:56:40 +00002143
Russell King52c95602019-12-11 10:56:45 +00002144 /* If this module may have a PHY connecting later, defer until later */
2145 pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id);
2146 if (pl->sfp_may_have_phy)
2147 return 0;
2148
2149 return phylink_sfp_config(pl, MLO_AN_INBAND, support, support);
Russell Kingc0de2f42019-12-11 10:56:40 +00002150}
2151
Russell King48820572019-12-11 10:56:14 +00002152static int phylink_sfp_module_start(void *upstream)
2153{
2154 struct phylink *pl = upstream;
2155
2156 /* If this SFP module has a PHY, start the PHY now. */
Russell King52c95602019-12-11 10:56:45 +00002157 if (pl->phydev) {
Russell King48820572019-12-11 10:56:14 +00002158 phy_start(pl->phydev);
Russell King52c95602019-12-11 10:56:45 +00002159 return 0;
2160 }
Russell King48820572019-12-11 10:56:14 +00002161
Russell King52c95602019-12-11 10:56:45 +00002162 /* If the module may have a PHY but we didn't detect one we
2163 * need to configure the MAC here.
2164 */
2165 if (!pl->sfp_may_have_phy)
2166 return 0;
2167
2168 return phylink_sfp_config(pl, MLO_AN_INBAND,
2169 pl->sfp_support, pl->sfp_support);
Russell King48820572019-12-11 10:56:14 +00002170}
2171
2172static void phylink_sfp_module_stop(void *upstream)
2173{
2174 struct phylink *pl = upstream;
2175
2176 /* If this SFP module has a PHY, stop it. */
2177 if (pl->phydev)
2178 phy_stop(pl->phydev);
2179}
2180
Russell Kingce0aa272017-07-25 15:03:18 +01002181static void phylink_sfp_link_down(void *upstream)
2182{
2183 struct phylink *pl = upstream;
2184
Russell King8b874512017-12-15 16:09:47 +00002185 ASSERT_RTNL();
Russell Kingce0aa272017-07-25 15:03:18 +01002186
Russell King87454b62019-02-11 15:04:24 +00002187 phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_LINK);
Russell Kingce0aa272017-07-25 15:03:18 +01002188}
2189
2190static void phylink_sfp_link_up(void *upstream)
2191{
2192 struct phylink *pl = upstream;
2193
Russell King8b874512017-12-15 16:09:47 +00002194 ASSERT_RTNL();
Russell Kingce0aa272017-07-25 15:03:18 +01002195
2196 clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
2197 phylink_run_resolve(pl);
2198}
2199
Russell King7adb5b22019-12-11 10:56:50 +00002200/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
2201 * or 802.3z control word, so inband will not work.
2202 */
2203static bool phylink_phy_no_inband(struct phy_device *phy)
2204{
2205 return phy->is_c45 &&
2206 (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
2207}
2208
Russell Kingce0aa272017-07-25 15:03:18 +01002209static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
2210{
Baruch Siach7e418372018-10-03 19:04:49 +03002211 struct phylink *pl = upstream;
Russell King52c95602019-12-11 10:56:45 +00002212 phy_interface_t interface;
Russell King7adb5b22019-12-11 10:56:50 +00002213 u8 mode;
Russell King938d44c2019-12-11 10:56:25 +00002214 int ret;
Baruch Siach7e418372018-10-03 19:04:49 +03002215
Russell King52c95602019-12-11 10:56:45 +00002216 /*
2217 * This is the new way of dealing with flow control for PHYs,
2218 * as described by Timur Tabi in commit 529ed1275263 ("net: phy:
2219 * phy drivers should not set SUPPORTED_[Asym_]Pause") except
2220 * using our validate call to the MAC, we rely upon the MAC
2221 * clearing the bits from both supported and advertising fields.
2222 */
2223 phy_support_asym_pause(phy);
2224
Russell King7adb5b22019-12-11 10:56:50 +00002225 if (phylink_phy_no_inband(phy))
2226 mode = MLO_AN_PHY;
2227 else
2228 mode = MLO_AN_INBAND;
2229
Russell King52c95602019-12-11 10:56:45 +00002230 /* Do the initial configuration */
Russell King7adb5b22019-12-11 10:56:50 +00002231 ret = phylink_sfp_config(pl, mode, phy->supported, phy->advertising);
Russell King52c95602019-12-11 10:56:45 +00002232 if (ret < 0)
2233 return ret;
2234
2235 interface = pl->link_config.interface;
2236 ret = phylink_attach_phy(pl, phy, interface);
Russell King938d44c2019-12-11 10:56:25 +00002237 if (ret < 0)
2238 return ret;
2239
Russell Kinge45d1f52019-12-11 10:56:30 +00002240 ret = phylink_bringup_phy(pl, phy, interface);
Russell King938d44c2019-12-11 10:56:25 +00002241 if (ret)
2242 phy_detach(phy);
2243
2244 return ret;
Russell Kingce0aa272017-07-25 15:03:18 +01002245}
2246
2247static void phylink_sfp_disconnect_phy(void *upstream)
2248{
2249 phylink_disconnect_phy(upstream);
2250}
2251
2252static const struct sfp_upstream_ops sfp_phylink_ops = {
Russell King320587e62019-05-28 10:57:34 +01002253 .attach = phylink_sfp_attach,
2254 .detach = phylink_sfp_detach,
Russell Kingce0aa272017-07-25 15:03:18 +01002255 .module_insert = phylink_sfp_module_insert,
Russell King48820572019-12-11 10:56:14 +00002256 .module_start = phylink_sfp_module_start,
2257 .module_stop = phylink_sfp_module_stop,
Russell Kingce0aa272017-07-25 15:03:18 +01002258 .link_up = phylink_sfp_link_up,
2259 .link_down = phylink_sfp_link_down,
2260 .connect_phy = phylink_sfp_connect_phy,
2261 .disconnect_phy = phylink_sfp_disconnect_phy,
2262};
2263
Russell King624c0f02018-08-09 15:38:38 +02002264/* Helpers for MAC drivers */
2265
2266/**
2267 * phylink_helper_basex_speed() - 1000BaseX/2500BaseX helper
2268 * @state: a pointer to a &struct phylink_link_state
2269 *
2270 * Inspect the interface mode, advertising mask or forced speed and
2271 * decide whether to run at 2.5Gbit or 1Gbit appropriately, switching
2272 * the interface mode to suit. @state->interface is appropriately
2273 * updated, and the advertising mask has the "other" baseX_Full flag
2274 * cleared.
2275 */
2276void phylink_helper_basex_speed(struct phylink_link_state *state)
2277{
2278 if (phy_interface_mode_is_8023z(state->interface)) {
2279 bool want_2500 = state->an_enabled ?
2280 phylink_test(state->advertising, 2500baseX_Full) :
2281 state->speed == SPEED_2500;
2282
2283 if (want_2500) {
2284 phylink_clear(state->advertising, 1000baseX_Full);
2285 state->interface = PHY_INTERFACE_MODE_2500BASEX;
2286 } else {
2287 phylink_clear(state->advertising, 2500baseX_Full);
2288 state->interface = PHY_INTERFACE_MODE_1000BASEX;
2289 }
2290 }
2291}
2292EXPORT_SYMBOL_GPL(phylink_helper_basex_speed);
2293
Russell King74db1c12020-03-17 14:52:36 +00002294static void phylink_decode_c37_word(struct phylink_link_state *state,
2295 uint16_t config_reg, int speed)
2296{
2297 bool tx_pause, rx_pause;
2298 int fd_bit;
2299
2300 if (speed == SPEED_2500)
2301 fd_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT;
2302 else
2303 fd_bit = ETHTOOL_LINK_MODE_1000baseX_Full_BIT;
2304
2305 mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit);
2306
2307 if (linkmode_test_bit(fd_bit, state->advertising) &&
2308 linkmode_test_bit(fd_bit, state->lp_advertising)) {
2309 state->speed = speed;
2310 state->duplex = DUPLEX_FULL;
2311 } else {
2312 /* negotiation failure */
2313 state->link = false;
2314 }
2315
2316 linkmode_resolve_pause(state->advertising, state->lp_advertising,
2317 &tx_pause, &rx_pause);
2318
2319 if (tx_pause)
2320 state->pause |= MLO_PAUSE_TX;
2321 if (rx_pause)
2322 state->pause |= MLO_PAUSE_RX;
2323}
2324
2325static void phylink_decode_sgmii_word(struct phylink_link_state *state,
2326 uint16_t config_reg)
2327{
2328 if (!(config_reg & LPA_SGMII_LINK)) {
2329 state->link = false;
2330 return;
2331 }
2332
2333 switch (config_reg & LPA_SGMII_SPD_MASK) {
2334 case LPA_SGMII_10:
2335 state->speed = SPEED_10;
2336 break;
2337 case LPA_SGMII_100:
2338 state->speed = SPEED_100;
2339 break;
2340 case LPA_SGMII_1000:
2341 state->speed = SPEED_1000;
2342 break;
2343 default:
2344 state->link = false;
2345 return;
2346 }
2347 if (config_reg & LPA_SGMII_FULL_DUPLEX)
2348 state->duplex = DUPLEX_FULL;
2349 else
2350 state->duplex = DUPLEX_HALF;
2351}
2352
2353/**
Ioana Ciorneiafd62202020-08-30 11:33:58 +03002354 * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
2355 * @state: a pointer to a struct phylink_link_state.
2356 * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
2357 *
2358 * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
2359 * code word. Decode the USXGMII code word and populate the corresponding fields
2360 * (speed, duplex) into the phylink_link_state structure.
2361 */
2362void phylink_decode_usxgmii_word(struct phylink_link_state *state,
2363 uint16_t lpa)
2364{
2365 switch (lpa & MDIO_USXGMII_SPD_MASK) {
2366 case MDIO_USXGMII_10:
2367 state->speed = SPEED_10;
2368 break;
2369 case MDIO_USXGMII_100:
2370 state->speed = SPEED_100;
2371 break;
2372 case MDIO_USXGMII_1000:
2373 state->speed = SPEED_1000;
2374 break;
2375 case MDIO_USXGMII_2500:
2376 state->speed = SPEED_2500;
2377 break;
2378 case MDIO_USXGMII_5000:
2379 state->speed = SPEED_5000;
2380 break;
2381 case MDIO_USXGMII_10G:
2382 state->speed = SPEED_10000;
2383 break;
2384 default:
2385 state->link = false;
2386 return;
2387 }
2388
2389 if (lpa & MDIO_USXGMII_FULL_DUPLEX)
2390 state->duplex = DUPLEX_FULL;
2391 else
2392 state->duplex = DUPLEX_HALF;
2393}
2394EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word);
2395
2396/**
Russell King74db1c12020-03-17 14:52:36 +00002397 * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
2398 * @pcs: a pointer to a &struct mdio_device.
2399 * @state: a pointer to a &struct phylink_link_state.
2400 *
2401 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2402 * clause 37 negotiation and/or SGMII control.
2403 *
2404 * Read the MAC PCS state from the MII device configured in @config and
2405 * parse the Clause 37 or Cisco SGMII link partner negotiation word into
2406 * the phylink @state structure. This is suitable to be directly plugged
2407 * into the mac_pcs_get_state() member of the struct phylink_mac_ops
2408 * structure.
2409 */
2410void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
2411 struct phylink_link_state *state)
2412{
2413 struct mii_bus *bus = pcs->bus;
2414 int addr = pcs->addr;
2415 int bmsr, lpa;
2416
2417 bmsr = mdiobus_read(bus, addr, MII_BMSR);
2418 lpa = mdiobus_read(bus, addr, MII_LPA);
2419 if (bmsr < 0 || lpa < 0) {
2420 state->link = false;
2421 return;
2422 }
2423
2424 state->link = !!(bmsr & BMSR_LSTATUS);
2425 state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
2426 if (!state->link)
2427 return;
2428
2429 switch (state->interface) {
2430 case PHY_INTERFACE_MODE_1000BASEX:
2431 phylink_decode_c37_word(state, lpa, SPEED_1000);
2432 break;
2433
2434 case PHY_INTERFACE_MODE_2500BASEX:
2435 phylink_decode_c37_word(state, lpa, SPEED_2500);
2436 break;
2437
2438 case PHY_INTERFACE_MODE_SGMII:
Ioana Ciornei29f02ee2020-08-30 11:33:59 +03002439 case PHY_INTERFACE_MODE_QSGMII:
Russell King74db1c12020-03-17 14:52:36 +00002440 phylink_decode_sgmii_word(state, lpa);
2441 break;
2442
2443 default:
2444 state->link = false;
2445 break;
2446 }
2447}
2448EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
2449
2450/**
2451 * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
2452 * advertisement
2453 * @pcs: a pointer to a &struct mdio_device.
Russell King0bd27402020-03-30 18:44:44 +01002454 * @interface: the PHY interface mode being configured
2455 * @advertising: the ethtool advertisement mask
Russell King74db1c12020-03-17 14:52:36 +00002456 *
2457 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2458 * clause 37 negotiation and/or SGMII control.
2459 *
2460 * Configure the clause 37 PCS advertisement as specified by @state. This
2461 * does not trigger a renegotiation; phylink will do that via the
2462 * mac_an_restart() method of the struct phylink_mac_ops structure.
2463 *
2464 * Returns negative error code on failure to configure the advertisement,
2465 * zero if no change has been made, or one if the advertisement has changed.
2466 */
2467int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
Russell King0bd27402020-03-30 18:44:44 +01002468 phy_interface_t interface,
2469 const unsigned long *advertising)
Russell King74db1c12020-03-17 14:52:36 +00002470{
2471 struct mii_bus *bus = pcs->bus;
2472 int addr = pcs->addr;
2473 int val, ret;
2474 u16 adv;
2475
Russell King0bd27402020-03-30 18:44:44 +01002476 switch (interface) {
Russell King74db1c12020-03-17 14:52:36 +00002477 case PHY_INTERFACE_MODE_1000BASEX:
2478 case PHY_INTERFACE_MODE_2500BASEX:
2479 adv = ADVERTISE_1000XFULL;
2480 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
Russell King0bd27402020-03-30 18:44:44 +01002481 advertising))
Russell King74db1c12020-03-17 14:52:36 +00002482 adv |= ADVERTISE_1000XPAUSE;
2483 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
Russell King0bd27402020-03-30 18:44:44 +01002484 advertising))
Russell King74db1c12020-03-17 14:52:36 +00002485 adv |= ADVERTISE_1000XPSE_ASYM;
2486
2487 val = mdiobus_read(bus, addr, MII_ADVERTISE);
2488 if (val < 0)
2489 return val;
2490
2491 if (val == adv)
2492 return 0;
2493
2494 ret = mdiobus_write(bus, addr, MII_ADVERTISE, adv);
2495 if (ret < 0)
2496 return ret;
2497
2498 return 1;
2499
2500 case PHY_INTERFACE_MODE_SGMII:
2501 val = mdiobus_read(bus, addr, MII_ADVERTISE);
2502 if (val < 0)
2503 return val;
2504
2505 if (val == 0x0001)
2506 return 0;
2507
2508 ret = mdiobus_write(bus, addr, MII_ADVERTISE, 0x0001);
2509 if (ret < 0)
2510 return ret;
2511
2512 return 1;
2513
2514 default:
2515 /* Nothing to do for other modes */
2516 return 0;
2517 }
2518}
2519EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
2520
2521/**
Russell King93eaceb2020-07-21 12:04:51 +01002522 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
2523 * @pcs: a pointer to a &struct mdio_device.
2524 * @mode: link autonegotiation mode
2525 * @interface: the PHY interface mode being configured
2526 * @advertising: the ethtool advertisement mask
2527 *
2528 * Configure a Clause 22 PCS PHY with the appropriate negotiation
2529 * parameters for the @mode, @interface and @advertising parameters.
2530 * Returns negative error number on failure, zero if the advertisement
2531 * has not changed, or positive if there is a change.
2532 */
2533int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
2534 phy_interface_t interface,
2535 const unsigned long *advertising)
2536{
2537 bool changed;
2538 u16 bmcr;
2539 int ret;
2540
2541 ret = phylink_mii_c22_pcs_set_advertisement(pcs, interface,
2542 advertising);
2543 if (ret < 0)
2544 return ret;
2545
2546 changed = ret > 0;
2547
Robert Hancockcd292962020-10-26 11:58:02 -06002548 /* Ensure ISOLATE bit is disabled */
Russell King93eaceb2020-07-21 12:04:51 +01002549 bmcr = mode == MLO_AN_INBAND ? BMCR_ANENABLE : 0;
2550 ret = mdiobus_modify(pcs->bus, pcs->addr, MII_BMCR,
Robert Hancockcd292962020-10-26 11:58:02 -06002551 BMCR_ANENABLE | BMCR_ISOLATE, bmcr);
Russell King93eaceb2020-07-21 12:04:51 +01002552 if (ret < 0)
2553 return ret;
2554
2555 return changed ? 1 : 0;
2556}
2557EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_config);
2558
2559/**
Russell King74db1c12020-03-17 14:52:36 +00002560 * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
2561 * @pcs: a pointer to a &struct mdio_device.
2562 *
2563 * Helper for MAC PCS supporting the 802.3 clause 22 register set for
2564 * clause 37 negotiation.
2565 *
2566 * Restart the clause 37 negotiation with the link partner. This is
2567 * suitable to be directly plugged into the mac_pcs_get_state() member
2568 * of the struct phylink_mac_ops structure.
2569 */
2570void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs)
2571{
2572 struct mii_bus *bus = pcs->bus;
2573 int val, addr = pcs->addr;
2574
2575 val = mdiobus_read(bus, addr, MII_BMCR);
2576 if (val >= 0) {
2577 val |= BMCR_ANRESTART;
2578
2579 mdiobus_write(bus, addr, MII_BMCR, val);
2580 }
2581}
2582EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_an_restart);
2583
Russell Kingb8679ef2020-03-17 14:52:41 +00002584void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
2585 struct phylink_link_state *state)
2586{
2587 struct mii_bus *bus = pcs->bus;
2588 int addr = pcs->addr;
2589 int stat;
2590
Russell King90ce6652020-05-26 16:29:36 +01002591 stat = mdiobus_c45_read(bus, addr, MDIO_MMD_PCS, MDIO_STAT1);
Russell Kingb8679ef2020-03-17 14:52:41 +00002592 if (stat < 0) {
2593 state->link = false;
2594 return;
2595 }
2596
2597 state->link = !!(stat & MDIO_STAT1_LSTATUS);
2598 if (!state->link)
2599 return;
2600
2601 switch (state->interface) {
2602 case PHY_INTERFACE_MODE_10GBASER:
2603 state->speed = SPEED_10000;
2604 state->duplex = DUPLEX_FULL;
2605 break;
2606
2607 default:
2608 break;
2609 }
2610}
2611EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state);
2612
Andrew Lunn5f857572019-01-21 19:10:19 +01002613MODULE_LICENSE("GPL v2");