1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* Framework for configuring and reading PHY devices |
3 | * Based on code in sungem_phy.c and gianfar_phy.c |
4 | * |
5 | * Author: Andy Fleming |
6 | * |
7 | * Copyright (c) 2004 Freescale Semiconductor, Inc. |
8 | * Copyright (c) 2006, 2007 Maciej W. Rozycki |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/string.h> |
13 | #include <linux/errno.h> |
14 | #include <linux/unistd.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/netdevice.h> |
18 | #include <linux/netlink.h> |
19 | #include <linux/etherdevice.h> |
20 | #include <linux/skbuff.h> |
21 | #include <linux/mm.h> |
22 | #include <linux/module.h> |
23 | #include <linux/mii.h> |
24 | #include <linux/ethtool.h> |
25 | #include <linux/ethtool_netlink.h> |
26 | #include <linux/phy.h> |
27 | #include <linux/phy_led_triggers.h> |
28 | #include <linux/sfp.h> |
29 | #include <linux/workqueue.h> |
30 | #include <linux/mdio.h> |
31 | #include <linux/io.h> |
32 | #include <linux/uaccess.h> |
33 | #include <linux/atomic.h> |
34 | #include <linux/suspend.h> |
35 | #include <net/netlink.h> |
36 | #include <net/genetlink.h> |
37 | #include <net/sock.h> |
38 | |
39 | #define PHY_STATE_TIME HZ |
40 | |
41 | #define PHY_STATE_STR(_state) \ |
42 | case PHY_##_state: \ |
43 | return __stringify(_state); \ |
44 | |
45 | static const char *phy_state_to_str(enum phy_state st) |
46 | { |
47 | switch (st) { |
48 | PHY_STATE_STR(DOWN) |
49 | PHY_STATE_STR(READY) |
50 | PHY_STATE_STR(UP) |
51 | PHY_STATE_STR(RUNNING) |
52 | PHY_STATE_STR(NOLINK) |
53 | PHY_STATE_STR(CABLETEST) |
54 | PHY_STATE_STR(HALTED) |
55 | PHY_STATE_STR(ERROR) |
56 | } |
57 | |
58 | return NULL; |
59 | } |
60 | |
61 | static void phy_process_state_change(struct phy_device *phydev, |
62 | enum phy_state old_state) |
63 | { |
64 | if (old_state != phydev->state) { |
65 | phydev_dbg(phydev, "PHY state change %s -> %s\n" , |
66 | phy_state_to_str(old_state), |
67 | phy_state_to_str(phydev->state)); |
68 | if (phydev->drv && phydev->drv->link_change_notify) |
69 | phydev->drv->link_change_notify(phydev); |
70 | } |
71 | } |
72 | |
73 | static void phy_link_up(struct phy_device *phydev) |
74 | { |
75 | phydev->phy_link_change(phydev, true); |
76 | phy_led_trigger_change_speed(phy: phydev); |
77 | } |
78 | |
79 | static void phy_link_down(struct phy_device *phydev) |
80 | { |
81 | phydev->phy_link_change(phydev, false); |
82 | phy_led_trigger_change_speed(phy: phydev); |
83 | WRITE_ONCE(phydev->link_down_events, phydev->link_down_events + 1); |
84 | } |
85 | |
86 | static const char *phy_pause_str(struct phy_device *phydev) |
87 | { |
88 | bool local_pause, local_asym_pause; |
89 | |
90 | if (phydev->autoneg == AUTONEG_DISABLE) |
91 | goto no_pause; |
92 | |
93 | local_pause = linkmode_test_bit(nr: ETHTOOL_LINK_MODE_Pause_BIT, |
94 | addr: phydev->advertising); |
95 | local_asym_pause = linkmode_test_bit(nr: ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
96 | addr: phydev->advertising); |
97 | |
98 | if (local_pause && phydev->pause) |
99 | return "rx/tx" ; |
100 | |
101 | if (local_asym_pause && phydev->asym_pause) { |
102 | if (local_pause) |
103 | return "rx" ; |
104 | if (phydev->pause) |
105 | return "tx" ; |
106 | } |
107 | |
108 | no_pause: |
109 | return "off" ; |
110 | } |
111 | |
112 | /** |
113 | * phy_print_status - Convenience function to print out the current phy status |
114 | * @phydev: the phy_device struct |
115 | */ |
116 | void phy_print_status(struct phy_device *phydev) |
117 | { |
118 | if (phydev->link) { |
119 | netdev_info(dev: phydev->attached_dev, |
120 | format: "Link is Up - %s/%s %s- flow control %s\n" , |
121 | phy_speed_to_str(speed: phydev->speed), |
122 | phy_duplex_to_str(duplex: phydev->duplex), |
123 | phydev->downshifted_rate ? "(downshifted) " : "" , |
124 | phy_pause_str(phydev)); |
125 | } else { |
126 | netdev_info(dev: phydev->attached_dev, format: "Link is Down\n" ); |
127 | } |
128 | } |
129 | EXPORT_SYMBOL(phy_print_status); |
130 | |
131 | /** |
132 | * phy_get_rate_matching - determine if rate matching is supported |
133 | * @phydev: The phy device to return rate matching for |
134 | * @iface: The interface mode to use |
135 | * |
136 | * This determines the type of rate matching (if any) that @phy supports |
137 | * using @iface. @iface may be %PHY_INTERFACE_MODE_NA to determine if any |
138 | * interface supports rate matching. |
139 | * |
140 | * Return: The type of rate matching @phy supports for @iface, or |
141 | * %RATE_MATCH_NONE. |
142 | */ |
143 | int phy_get_rate_matching(struct phy_device *phydev, |
144 | phy_interface_t iface) |
145 | { |
146 | int ret = RATE_MATCH_NONE; |
147 | |
148 | if (phydev->drv->get_rate_matching) { |
149 | mutex_lock(&phydev->lock); |
150 | ret = phydev->drv->get_rate_matching(phydev, iface); |
151 | mutex_unlock(lock: &phydev->lock); |
152 | } |
153 | |
154 | return ret; |
155 | } |
156 | EXPORT_SYMBOL_GPL(phy_get_rate_matching); |
157 | |
158 | /** |
159 | * phy_config_interrupt - configure the PHY device for the requested interrupts |
160 | * @phydev: the phy_device struct |
161 | * @interrupts: interrupt flags to configure for this @phydev |
162 | * |
163 | * Returns 0 on success or < 0 on error. |
164 | */ |
165 | static int phy_config_interrupt(struct phy_device *phydev, bool interrupts) |
166 | { |
167 | phydev->interrupts = interrupts ? 1 : 0; |
168 | if (phydev->drv->config_intr) |
169 | return phydev->drv->config_intr(phydev); |
170 | |
171 | return 0; |
172 | } |
173 | |
174 | /** |
175 | * phy_restart_aneg - restart auto-negotiation |
176 | * @phydev: target phy_device struct |
177 | * |
178 | * Restart the autonegotiation on @phydev. Returns >= 0 on success or |
179 | * negative errno on error. |
180 | */ |
181 | int phy_restart_aneg(struct phy_device *phydev) |
182 | { |
183 | int ret; |
184 | |
185 | if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) |
186 | ret = genphy_c45_restart_aneg(phydev); |
187 | else |
188 | ret = genphy_restart_aneg(phydev); |
189 | |
190 | return ret; |
191 | } |
192 | EXPORT_SYMBOL_GPL(phy_restart_aneg); |
193 | |
194 | /** |
195 | * phy_aneg_done - return auto-negotiation status |
196 | * @phydev: target phy_device struct |
197 | * |
198 | * Description: Return the auto-negotiation status from this @phydev |
199 | * Returns > 0 on success or < 0 on error. 0 means that auto-negotiation |
200 | * is still pending. |
201 | */ |
202 | int phy_aneg_done(struct phy_device *phydev) |
203 | { |
204 | if (phydev->drv && phydev->drv->aneg_done) |
205 | return phydev->drv->aneg_done(phydev); |
206 | else if (phydev->is_c45) |
207 | return genphy_c45_aneg_done(phydev); |
208 | else |
209 | return genphy_aneg_done(phydev); |
210 | } |
211 | EXPORT_SYMBOL(phy_aneg_done); |
212 | |
213 | /** |
214 | * phy_find_valid - find a PHY setting that matches the requested parameters |
215 | * @speed: desired speed |
216 | * @duplex: desired duplex |
217 | * @supported: mask of supported link modes |
218 | * |
219 | * Locate a supported phy setting that is, in priority order: |
220 | * - an exact match for the specified speed and duplex mode |
221 | * - a match for the specified speed, or slower speed |
222 | * - the slowest supported speed |
223 | * Returns the matched phy_setting entry, or %NULL if no supported phy |
224 | * settings were found. |
225 | */ |
226 | static const struct phy_setting * |
227 | phy_find_valid(int speed, int duplex, unsigned long *supported) |
228 | { |
229 | return phy_lookup_setting(speed, duplex, mask: supported, exact: false); |
230 | } |
231 | |
232 | /** |
233 | * phy_supported_speeds - return all speeds currently supported by a phy device |
234 | * @phy: The phy device to return supported speeds of. |
235 | * @speeds: buffer to store supported speeds in. |
236 | * @size: size of speeds buffer. |
237 | * |
238 | * Description: Returns the number of supported speeds, and fills the speeds |
239 | * buffer with the supported speeds. If speeds buffer is too small to contain |
240 | * all currently supported speeds, will return as many speeds as can fit. |
241 | */ |
242 | unsigned int phy_supported_speeds(struct phy_device *phy, |
243 | unsigned int *speeds, |
244 | unsigned int size) |
245 | { |
246 | return phy_speeds(speeds, size, mask: phy->supported); |
247 | } |
248 | |
249 | /** |
250 | * phy_check_valid - check if there is a valid PHY setting which matches |
251 | * speed, duplex, and feature mask |
252 | * @speed: speed to match |
253 | * @duplex: duplex to match |
254 | * @features: A mask of the valid settings |
255 | * |
256 | * Description: Returns true if there is a valid setting, false otherwise. |
257 | */ |
258 | bool phy_check_valid(int speed, int duplex, unsigned long *features) |
259 | { |
260 | return !!phy_lookup_setting(speed, duplex, mask: features, exact: true); |
261 | } |
262 | EXPORT_SYMBOL(phy_check_valid); |
263 | |
264 | /** |
265 | * phy_sanitize_settings - make sure the PHY is set to supported speed and duplex |
266 | * @phydev: the target phy_device struct |
267 | * |
268 | * Description: Make sure the PHY is set to supported speeds and |
269 | * duplexes. Drop down by one in this order: 1000/FULL, |
270 | * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF. |
271 | */ |
272 | static void phy_sanitize_settings(struct phy_device *phydev) |
273 | { |
274 | const struct phy_setting *setting; |
275 | |
276 | setting = phy_find_valid(speed: phydev->speed, duplex: phydev->duplex, |
277 | supported: phydev->supported); |
278 | if (setting) { |
279 | phydev->speed = setting->speed; |
280 | phydev->duplex = setting->duplex; |
281 | } else { |
282 | /* We failed to find anything (no supported speeds?) */ |
283 | phydev->speed = SPEED_UNKNOWN; |
284 | phydev->duplex = DUPLEX_UNKNOWN; |
285 | } |
286 | } |
287 | |
288 | void phy_ethtool_ksettings_get(struct phy_device *phydev, |
289 | struct ethtool_link_ksettings *cmd) |
290 | { |
291 | mutex_lock(&phydev->lock); |
292 | linkmode_copy(dst: cmd->link_modes.supported, src: phydev->supported); |
293 | linkmode_copy(dst: cmd->link_modes.advertising, src: phydev->advertising); |
294 | linkmode_copy(dst: cmd->link_modes.lp_advertising, src: phydev->lp_advertising); |
295 | |
296 | cmd->base.speed = phydev->speed; |
297 | cmd->base.duplex = phydev->duplex; |
298 | cmd->base.master_slave_cfg = phydev->master_slave_get; |
299 | cmd->base.master_slave_state = phydev->master_slave_state; |
300 | cmd->base.rate_matching = phydev->rate_matching; |
301 | if (phydev->interface == PHY_INTERFACE_MODE_MOCA) |
302 | cmd->base.port = PORT_BNC; |
303 | else |
304 | cmd->base.port = phydev->port; |
305 | cmd->base.transceiver = phy_is_internal(phydev) ? |
306 | XCVR_INTERNAL : XCVR_EXTERNAL; |
307 | cmd->base.phy_address = phydev->mdio.addr; |
308 | cmd->base.autoneg = phydev->autoneg; |
309 | cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl; |
310 | cmd->base.eth_tp_mdix = phydev->mdix; |
311 | mutex_unlock(lock: &phydev->lock); |
312 | } |
313 | EXPORT_SYMBOL(phy_ethtool_ksettings_get); |
314 | |
315 | /** |
316 | * phy_mii_ioctl - generic PHY MII ioctl interface |
317 | * @phydev: the phy_device struct |
318 | * @ifr: &struct ifreq for socket ioctl's |
319 | * @cmd: ioctl cmd to execute |
320 | * |
321 | * Note that this function is currently incompatible with the |
322 | * PHYCONTROL layer. It changes registers without regard to |
323 | * current state. Use at own risk. |
324 | */ |
325 | int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) |
326 | { |
327 | struct mii_ioctl_data *mii_data = if_mii(rq: ifr); |
328 | struct kernel_hwtstamp_config kernel_cfg; |
329 | struct netlink_ext_ack extack = {}; |
330 | u16 val = mii_data->val_in; |
331 | bool change_autoneg = false; |
332 | struct hwtstamp_config cfg; |
333 | int prtad, devad; |
334 | int ret; |
335 | |
336 | switch (cmd) { |
337 | case SIOCGMIIPHY: |
338 | mii_data->phy_id = phydev->mdio.addr; |
339 | fallthrough; |
340 | |
341 | case SIOCGMIIREG: |
342 | if (mdio_phy_id_is_c45(phy_id: mii_data->phy_id)) { |
343 | prtad = mdio_phy_id_prtad(phy_id: mii_data->phy_id); |
344 | devad = mdio_phy_id_devad(phy_id: mii_data->phy_id); |
345 | mii_data->val_out = mdiobus_c45_read( |
346 | bus: phydev->mdio.bus, addr: prtad, devad, |
347 | regnum: mii_data->reg_num); |
348 | } else { |
349 | mii_data->val_out = mdiobus_read( |
350 | bus: phydev->mdio.bus, addr: mii_data->phy_id, |
351 | regnum: mii_data->reg_num); |
352 | } |
353 | return 0; |
354 | |
355 | case SIOCSMIIREG: |
356 | if (mdio_phy_id_is_c45(phy_id: mii_data->phy_id)) { |
357 | prtad = mdio_phy_id_prtad(phy_id: mii_data->phy_id); |
358 | devad = mdio_phy_id_devad(phy_id: mii_data->phy_id); |
359 | } else { |
360 | prtad = mii_data->phy_id; |
361 | devad = mii_data->reg_num; |
362 | } |
363 | if (prtad == phydev->mdio.addr) { |
364 | switch (devad) { |
365 | case MII_BMCR: |
366 | if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) { |
367 | if (phydev->autoneg == AUTONEG_ENABLE) |
368 | change_autoneg = true; |
369 | phydev->autoneg = AUTONEG_DISABLE; |
370 | if (val & BMCR_FULLDPLX) |
371 | phydev->duplex = DUPLEX_FULL; |
372 | else |
373 | phydev->duplex = DUPLEX_HALF; |
374 | if (val & BMCR_SPEED1000) |
375 | phydev->speed = SPEED_1000; |
376 | else if (val & BMCR_SPEED100) |
377 | phydev->speed = SPEED_100; |
378 | else phydev->speed = SPEED_10; |
379 | } else { |
380 | if (phydev->autoneg == AUTONEG_DISABLE) |
381 | change_autoneg = true; |
382 | phydev->autoneg = AUTONEG_ENABLE; |
383 | } |
384 | break; |
385 | case MII_ADVERTISE: |
386 | mii_adv_mod_linkmode_adv_t(advertising: phydev->advertising, |
387 | adv: val); |
388 | change_autoneg = true; |
389 | break; |
390 | case MII_CTRL1000: |
391 | mii_ctrl1000_mod_linkmode_adv_t(advertising: phydev->advertising, |
392 | ctrl1000: val); |
393 | change_autoneg = true; |
394 | break; |
395 | default: |
396 | /* do nothing */ |
397 | break; |
398 | } |
399 | } |
400 | |
401 | if (mdio_phy_id_is_c45(phy_id: mii_data->phy_id)) |
402 | mdiobus_c45_write(bus: phydev->mdio.bus, addr: prtad, devad, |
403 | regnum: mii_data->reg_num, val); |
404 | else |
405 | mdiobus_write(bus: phydev->mdio.bus, addr: prtad, regnum: devad, val); |
406 | |
407 | if (prtad == phydev->mdio.addr && |
408 | devad == MII_BMCR && |
409 | val & BMCR_RESET) |
410 | return phy_init_hw(phydev); |
411 | |
412 | if (change_autoneg) |
413 | return phy_start_aneg(phydev); |
414 | |
415 | return 0; |
416 | |
417 | case SIOCSHWTSTAMP: |
418 | if (phydev->mii_ts && phydev->mii_ts->hwtstamp) { |
419 | if (copy_from_user(to: &cfg, from: ifr->ifr_data, n: sizeof(cfg))) |
420 | return -EFAULT; |
421 | |
422 | hwtstamp_config_to_kernel(kernel_cfg: &kernel_cfg, cfg: &cfg); |
423 | ret = phydev->mii_ts->hwtstamp(phydev->mii_ts, &kernel_cfg, &extack); |
424 | if (ret) |
425 | return ret; |
426 | |
427 | hwtstamp_config_from_kernel(cfg: &cfg, kernel_cfg: &kernel_cfg); |
428 | if (copy_to_user(to: ifr->ifr_data, from: &cfg, n: sizeof(cfg))) |
429 | return -EFAULT; |
430 | |
431 | return 0; |
432 | } |
433 | fallthrough; |
434 | |
435 | default: |
436 | return -EOPNOTSUPP; |
437 | } |
438 | } |
439 | EXPORT_SYMBOL(phy_mii_ioctl); |
440 | |
441 | /** |
442 | * phy_do_ioctl - generic ndo_eth_ioctl implementation |
443 | * @dev: the net_device struct |
444 | * @ifr: &struct ifreq for socket ioctl's |
445 | * @cmd: ioctl cmd to execute |
446 | */ |
447 | int phy_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
448 | { |
449 | if (!dev->phydev) |
450 | return -ENODEV; |
451 | |
452 | return phy_mii_ioctl(dev->phydev, ifr, cmd); |
453 | } |
454 | EXPORT_SYMBOL(phy_do_ioctl); |
455 | |
456 | /** |
457 | * phy_do_ioctl_running - generic ndo_eth_ioctl implementation but test first |
458 | * |
459 | * @dev: the net_device struct |
460 | * @ifr: &struct ifreq for socket ioctl's |
461 | * @cmd: ioctl cmd to execute |
462 | * |
463 | * Same as phy_do_ioctl, but ensures that net_device is running before |
464 | * handling the ioctl. |
465 | */ |
466 | int phy_do_ioctl_running(struct net_device *dev, struct ifreq *ifr, int cmd) |
467 | { |
468 | if (!netif_running(dev)) |
469 | return -ENODEV; |
470 | |
471 | return phy_do_ioctl(dev, ifr, cmd); |
472 | } |
473 | EXPORT_SYMBOL(phy_do_ioctl_running); |
474 | |
475 | /** |
476 | * __phy_hwtstamp_get - Get hardware timestamping configuration from PHY |
477 | * |
478 | * @phydev: the PHY device structure |
479 | * @config: structure holding the timestamping configuration |
480 | * |
481 | * Query the PHY device for its current hardware timestamping configuration. |
482 | */ |
483 | int __phy_hwtstamp_get(struct phy_device *phydev, |
484 | struct kernel_hwtstamp_config *config) |
485 | { |
486 | if (!phydev) |
487 | return -ENODEV; |
488 | |
489 | return -EOPNOTSUPP; |
490 | } |
491 | |
492 | /** |
493 | * __phy_hwtstamp_set - Modify PHY hardware timestamping configuration |
494 | * |
495 | * @phydev: the PHY device structure |
496 | * @config: structure holding the timestamping configuration |
497 | * @extack: netlink extended ack structure, for error reporting |
498 | */ |
499 | int __phy_hwtstamp_set(struct phy_device *phydev, |
500 | struct kernel_hwtstamp_config *config, |
501 | struct netlink_ext_ack *extack) |
502 | { |
503 | if (!phydev) |
504 | return -ENODEV; |
505 | |
506 | if (phydev->mii_ts && phydev->mii_ts->hwtstamp) |
507 | return phydev->mii_ts->hwtstamp(phydev->mii_ts, config, extack); |
508 | |
509 | return -EOPNOTSUPP; |
510 | } |
511 | |
512 | /** |
513 | * phy_queue_state_machine - Trigger the state machine to run soon |
514 | * |
515 | * @phydev: the phy_device struct |
516 | * @jiffies: Run the state machine after these jiffies |
517 | */ |
518 | void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies) |
519 | { |
520 | mod_delayed_work(wq: system_power_efficient_wq, dwork: &phydev->state_queue, |
521 | delay: jiffies); |
522 | } |
523 | EXPORT_SYMBOL(phy_queue_state_machine); |
524 | |
525 | /** |
526 | * phy_trigger_machine - Trigger the state machine to run now |
527 | * |
528 | * @phydev: the phy_device struct |
529 | */ |
530 | void phy_trigger_machine(struct phy_device *phydev) |
531 | { |
532 | phy_queue_state_machine(phydev, 0); |
533 | } |
534 | EXPORT_SYMBOL(phy_trigger_machine); |
535 | |
536 | static void phy_abort_cable_test(struct phy_device *phydev) |
537 | { |
538 | int err; |
539 | |
540 | ethnl_cable_test_finished(phydev); |
541 | |
542 | err = phy_init_hw(phydev); |
543 | if (err) |
544 | phydev_err(phydev, "Error while aborting cable test" ); |
545 | } |
546 | |
547 | /** |
548 | * phy_ethtool_get_strings - Get the statistic counter names |
549 | * |
550 | * @phydev: the phy_device struct |
551 | * @data: Where to put the strings |
552 | */ |
553 | int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data) |
554 | { |
555 | if (!phydev->drv) |
556 | return -EIO; |
557 | |
558 | mutex_lock(&phydev->lock); |
559 | phydev->drv->get_strings(phydev, data); |
560 | mutex_unlock(lock: &phydev->lock); |
561 | |
562 | return 0; |
563 | } |
564 | EXPORT_SYMBOL(phy_ethtool_get_strings); |
565 | |
566 | /** |
567 | * phy_ethtool_get_sset_count - Get the number of statistic counters |
568 | * |
569 | * @phydev: the phy_device struct |
570 | */ |
571 | int phy_ethtool_get_sset_count(struct phy_device *phydev) |
572 | { |
573 | int ret; |
574 | |
575 | if (!phydev->drv) |
576 | return -EIO; |
577 | |
578 | if (phydev->drv->get_sset_count && |
579 | phydev->drv->get_strings && |
580 | phydev->drv->get_stats) { |
581 | mutex_lock(&phydev->lock); |
582 | ret = phydev->drv->get_sset_count(phydev); |
583 | mutex_unlock(lock: &phydev->lock); |
584 | |
585 | return ret; |
586 | } |
587 | |
588 | return -EOPNOTSUPP; |
589 | } |
590 | EXPORT_SYMBOL(phy_ethtool_get_sset_count); |
591 | |
592 | /** |
593 | * phy_ethtool_get_stats - Get the statistic counters |
594 | * |
595 | * @phydev: the phy_device struct |
596 | * @stats: What counters to get |
597 | * @data: Where to store the counters |
598 | */ |
599 | int phy_ethtool_get_stats(struct phy_device *phydev, |
600 | struct ethtool_stats *stats, u64 *data) |
601 | { |
602 | if (!phydev->drv) |
603 | return -EIO; |
604 | |
605 | mutex_lock(&phydev->lock); |
606 | phydev->drv->get_stats(phydev, stats, data); |
607 | mutex_unlock(lock: &phydev->lock); |
608 | |
609 | return 0; |
610 | } |
611 | EXPORT_SYMBOL(phy_ethtool_get_stats); |
612 | |
613 | /** |
614 | * phy_ethtool_get_plca_cfg - Get PLCA RS configuration |
615 | * @phydev: the phy_device struct |
616 | * @plca_cfg: where to store the retrieved configuration |
617 | * |
618 | * Retrieve the PLCA configuration from the PHY. Return 0 on success or a |
619 | * negative value if an error occurred. |
620 | */ |
621 | int phy_ethtool_get_plca_cfg(struct phy_device *phydev, |
622 | struct phy_plca_cfg *plca_cfg) |
623 | { |
624 | int ret; |
625 | |
626 | if (!phydev->drv) { |
627 | ret = -EIO; |
628 | goto out; |
629 | } |
630 | |
631 | if (!phydev->drv->get_plca_cfg) { |
632 | ret = -EOPNOTSUPP; |
633 | goto out; |
634 | } |
635 | |
636 | mutex_lock(&phydev->lock); |
637 | ret = phydev->drv->get_plca_cfg(phydev, plca_cfg); |
638 | |
639 | mutex_unlock(lock: &phydev->lock); |
640 | out: |
641 | return ret; |
642 | } |
643 | |
644 | /** |
645 | * plca_check_valid - Check PLCA configuration before enabling |
646 | * @phydev: the phy_device struct |
647 | * @plca_cfg: current PLCA configuration |
648 | * @extack: extack for reporting useful error messages |
649 | * |
650 | * Checks whether the PLCA and PHY configuration are consistent and it is safe |
651 | * to enable PLCA. Returns 0 on success or a negative value if the PLCA or PHY |
652 | * configuration is not consistent. |
653 | */ |
654 | static int plca_check_valid(struct phy_device *phydev, |
655 | const struct phy_plca_cfg *plca_cfg, |
656 | struct netlink_ext_ack *extack) |
657 | { |
658 | int ret = 0; |
659 | |
660 | if (!linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT, |
661 | addr: phydev->advertising)) { |
662 | ret = -EOPNOTSUPP; |
663 | NL_SET_ERR_MSG(extack, |
664 | "Point to Multi-Point mode is not enabled" ); |
665 | } else if (plca_cfg->node_id >= 255) { |
666 | NL_SET_ERR_MSG(extack, "PLCA node ID is not set" ); |
667 | ret = -EINVAL; |
668 | } |
669 | |
670 | return ret; |
671 | } |
672 | |
673 | /** |
674 | * phy_ethtool_set_plca_cfg - Set PLCA RS configuration |
675 | * @phydev: the phy_device struct |
676 | * @plca_cfg: new PLCA configuration to apply |
677 | * @extack: extack for reporting useful error messages |
678 | * |
679 | * Sets the PLCA configuration in the PHY. Return 0 on success or a |
680 | * negative value if an error occurred. |
681 | */ |
682 | int phy_ethtool_set_plca_cfg(struct phy_device *phydev, |
683 | const struct phy_plca_cfg *plca_cfg, |
684 | struct netlink_ext_ack *extack) |
685 | { |
686 | struct phy_plca_cfg *curr_plca_cfg; |
687 | int ret; |
688 | |
689 | if (!phydev->drv) { |
690 | ret = -EIO; |
691 | goto out; |
692 | } |
693 | |
694 | if (!phydev->drv->set_plca_cfg || |
695 | !phydev->drv->get_plca_cfg) { |
696 | ret = -EOPNOTSUPP; |
697 | goto out; |
698 | } |
699 | |
700 | curr_plca_cfg = kmalloc(size: sizeof(*curr_plca_cfg), GFP_KERNEL); |
701 | if (!curr_plca_cfg) { |
702 | ret = -ENOMEM; |
703 | goto out; |
704 | } |
705 | |
706 | mutex_lock(&phydev->lock); |
707 | |
708 | ret = phydev->drv->get_plca_cfg(phydev, curr_plca_cfg); |
709 | if (ret) |
710 | goto out_drv; |
711 | |
712 | if (curr_plca_cfg->enabled < 0 && plca_cfg->enabled >= 0) { |
713 | NL_SET_ERR_MSG(extack, |
714 | "PHY does not support changing the PLCA 'enable' attribute" ); |
715 | ret = -EINVAL; |
716 | goto out_drv; |
717 | } |
718 | |
719 | if (curr_plca_cfg->node_id < 0 && plca_cfg->node_id >= 0) { |
720 | NL_SET_ERR_MSG(extack, |
721 | "PHY does not support changing the PLCA 'local node ID' attribute" ); |
722 | ret = -EINVAL; |
723 | goto out_drv; |
724 | } |
725 | |
726 | if (curr_plca_cfg->node_cnt < 0 && plca_cfg->node_cnt >= 0) { |
727 | NL_SET_ERR_MSG(extack, |
728 | "PHY does not support changing the PLCA 'node count' attribute" ); |
729 | ret = -EINVAL; |
730 | goto out_drv; |
731 | } |
732 | |
733 | if (curr_plca_cfg->to_tmr < 0 && plca_cfg->to_tmr >= 0) { |
734 | NL_SET_ERR_MSG(extack, |
735 | "PHY does not support changing the PLCA 'TO timer' attribute" ); |
736 | ret = -EINVAL; |
737 | goto out_drv; |
738 | } |
739 | |
740 | if (curr_plca_cfg->burst_cnt < 0 && plca_cfg->burst_cnt >= 0) { |
741 | NL_SET_ERR_MSG(extack, |
742 | "PHY does not support changing the PLCA 'burst count' attribute" ); |
743 | ret = -EINVAL; |
744 | goto out_drv; |
745 | } |
746 | |
747 | if (curr_plca_cfg->burst_tmr < 0 && plca_cfg->burst_tmr >= 0) { |
748 | NL_SET_ERR_MSG(extack, |
749 | "PHY does not support changing the PLCA 'burst timer' attribute" ); |
750 | ret = -EINVAL; |
751 | goto out_drv; |
752 | } |
753 | |
754 | // if enabling PLCA, perform a few sanity checks |
755 | if (plca_cfg->enabled > 0) { |
756 | // allow setting node_id concurrently with enabled |
757 | if (plca_cfg->node_id >= 0) |
758 | curr_plca_cfg->node_id = plca_cfg->node_id; |
759 | |
760 | ret = plca_check_valid(phydev, plca_cfg: curr_plca_cfg, extack); |
761 | if (ret) |
762 | goto out_drv; |
763 | } |
764 | |
765 | ret = phydev->drv->set_plca_cfg(phydev, plca_cfg); |
766 | |
767 | out_drv: |
768 | kfree(objp: curr_plca_cfg); |
769 | mutex_unlock(lock: &phydev->lock); |
770 | out: |
771 | return ret; |
772 | } |
773 | |
774 | /** |
775 | * phy_ethtool_get_plca_status - Get PLCA RS status information |
776 | * @phydev: the phy_device struct |
777 | * @plca_st: where to store the retrieved status information |
778 | * |
779 | * Retrieve the PLCA status information from the PHY. Return 0 on success or a |
780 | * negative value if an error occurred. |
781 | */ |
782 | int phy_ethtool_get_plca_status(struct phy_device *phydev, |
783 | struct phy_plca_status *plca_st) |
784 | { |
785 | int ret; |
786 | |
787 | if (!phydev->drv) { |
788 | ret = -EIO; |
789 | goto out; |
790 | } |
791 | |
792 | if (!phydev->drv->get_plca_status) { |
793 | ret = -EOPNOTSUPP; |
794 | goto out; |
795 | } |
796 | |
797 | mutex_lock(&phydev->lock); |
798 | ret = phydev->drv->get_plca_status(phydev, plca_st); |
799 | |
800 | mutex_unlock(lock: &phydev->lock); |
801 | out: |
802 | return ret; |
803 | } |
804 | |
805 | /** |
806 | * phy_start_cable_test - Start a cable test |
807 | * |
808 | * @phydev: the phy_device struct |
809 | * @extack: extack for reporting useful error messages |
810 | */ |
811 | int phy_start_cable_test(struct phy_device *phydev, |
812 | struct netlink_ext_ack *extack) |
813 | { |
814 | struct net_device *dev = phydev->attached_dev; |
815 | int err = -ENOMEM; |
816 | |
817 | if (!(phydev->drv && |
818 | phydev->drv->cable_test_start && |
819 | phydev->drv->cable_test_get_status)) { |
820 | NL_SET_ERR_MSG(extack, |
821 | "PHY driver does not support cable testing" ); |
822 | return -EOPNOTSUPP; |
823 | } |
824 | |
825 | mutex_lock(&phydev->lock); |
826 | if (phydev->state == PHY_CABLETEST) { |
827 | NL_SET_ERR_MSG(extack, |
828 | "PHY already performing a test" ); |
829 | err = -EBUSY; |
830 | goto out; |
831 | } |
832 | |
833 | if (phydev->state < PHY_UP || |
834 | phydev->state > PHY_CABLETEST) { |
835 | NL_SET_ERR_MSG(extack, |
836 | "PHY not configured. Try setting interface up" ); |
837 | err = -EBUSY; |
838 | goto out; |
839 | } |
840 | |
841 | err = ethnl_cable_test_alloc(phydev, cmd: ETHTOOL_MSG_CABLE_TEST_NTF); |
842 | if (err) |
843 | goto out; |
844 | |
845 | /* Mark the carrier down until the test is complete */ |
846 | phy_link_down(phydev); |
847 | |
848 | netif_testing_on(dev); |
849 | err = phydev->drv->cable_test_start(phydev); |
850 | if (err) { |
851 | netif_testing_off(dev); |
852 | phy_link_up(phydev); |
853 | goto out_free; |
854 | } |
855 | |
856 | phydev->state = PHY_CABLETEST; |
857 | |
858 | if (phy_polling_mode(phydev)) |
859 | phy_trigger_machine(phydev); |
860 | |
861 | mutex_unlock(lock: &phydev->lock); |
862 | |
863 | return 0; |
864 | |
865 | out_free: |
866 | ethnl_cable_test_free(phydev); |
867 | out: |
868 | mutex_unlock(lock: &phydev->lock); |
869 | |
870 | return err; |
871 | } |
872 | EXPORT_SYMBOL(phy_start_cable_test); |
873 | |
874 | /** |
875 | * phy_start_cable_test_tdr - Start a raw TDR cable test |
876 | * |
877 | * @phydev: the phy_device struct |
878 | * @extack: extack for reporting useful error messages |
879 | * @config: Configuration of the test to run |
880 | */ |
881 | int phy_start_cable_test_tdr(struct phy_device *phydev, |
882 | struct netlink_ext_ack *extack, |
883 | const struct phy_tdr_config *config) |
884 | { |
885 | struct net_device *dev = phydev->attached_dev; |
886 | int err = -ENOMEM; |
887 | |
888 | if (!(phydev->drv && |
889 | phydev->drv->cable_test_tdr_start && |
890 | phydev->drv->cable_test_get_status)) { |
891 | NL_SET_ERR_MSG(extack, |
892 | "PHY driver does not support cable test TDR" ); |
893 | return -EOPNOTSUPP; |
894 | } |
895 | |
896 | mutex_lock(&phydev->lock); |
897 | if (phydev->state == PHY_CABLETEST) { |
898 | NL_SET_ERR_MSG(extack, |
899 | "PHY already performing a test" ); |
900 | err = -EBUSY; |
901 | goto out; |
902 | } |
903 | |
904 | if (phydev->state < PHY_UP || |
905 | phydev->state > PHY_CABLETEST) { |
906 | NL_SET_ERR_MSG(extack, |
907 | "PHY not configured. Try setting interface up" ); |
908 | err = -EBUSY; |
909 | goto out; |
910 | } |
911 | |
912 | err = ethnl_cable_test_alloc(phydev, cmd: ETHTOOL_MSG_CABLE_TEST_TDR_NTF); |
913 | if (err) |
914 | goto out; |
915 | |
916 | /* Mark the carrier down until the test is complete */ |
917 | phy_link_down(phydev); |
918 | |
919 | netif_testing_on(dev); |
920 | err = phydev->drv->cable_test_tdr_start(phydev, config); |
921 | if (err) { |
922 | netif_testing_off(dev); |
923 | phy_link_up(phydev); |
924 | goto out_free; |
925 | } |
926 | |
927 | phydev->state = PHY_CABLETEST; |
928 | |
929 | if (phy_polling_mode(phydev)) |
930 | phy_trigger_machine(phydev); |
931 | |
932 | mutex_unlock(lock: &phydev->lock); |
933 | |
934 | return 0; |
935 | |
936 | out_free: |
937 | ethnl_cable_test_free(phydev); |
938 | out: |
939 | mutex_unlock(lock: &phydev->lock); |
940 | |
941 | return err; |
942 | } |
943 | EXPORT_SYMBOL(phy_start_cable_test_tdr); |
944 | |
945 | int phy_config_aneg(struct phy_device *phydev) |
946 | { |
947 | if (phydev->drv->config_aneg) |
948 | return phydev->drv->config_aneg(phydev); |
949 | |
950 | /* Clause 45 PHYs that don't implement Clause 22 registers are not |
951 | * allowed to call genphy_config_aneg() |
952 | */ |
953 | if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) |
954 | return genphy_c45_config_aneg(phydev); |
955 | |
956 | return genphy_config_aneg(phydev); |
957 | } |
958 | EXPORT_SYMBOL(phy_config_aneg); |
959 | |
960 | /** |
961 | * phy_check_link_status - check link status and set state accordingly |
962 | * @phydev: the phy_device struct |
963 | * |
964 | * Description: Check for link and whether autoneg was triggered / is running |
965 | * and set state accordingly |
966 | */ |
967 | static int phy_check_link_status(struct phy_device *phydev) |
968 | { |
969 | int err; |
970 | |
971 | lockdep_assert_held(&phydev->lock); |
972 | |
973 | /* Keep previous state if loopback is enabled because some PHYs |
974 | * report that Link is Down when loopback is enabled. |
975 | */ |
976 | if (phydev->loopback_enabled) |
977 | return 0; |
978 | |
979 | err = phy_read_status(phydev); |
980 | if (err) |
981 | return err; |
982 | |
983 | if (phydev->link && phydev->state != PHY_RUNNING) { |
984 | phy_check_downshift(phydev); |
985 | phydev->state = PHY_RUNNING; |
986 | err = genphy_c45_eee_is_active(phydev, |
987 | NULL, NULL, NULL); |
988 | if (err <= 0) |
989 | phydev->enable_tx_lpi = false; |
990 | else |
991 | phydev->enable_tx_lpi = phydev->eee_cfg.tx_lpi_enabled; |
992 | |
993 | phy_link_up(phydev); |
994 | } else if (!phydev->link && phydev->state != PHY_NOLINK) { |
995 | phydev->state = PHY_NOLINK; |
996 | phydev->enable_tx_lpi = false; |
997 | phy_link_down(phydev); |
998 | } |
999 | |
1000 | return 0; |
1001 | } |
1002 | |
1003 | /** |
1004 | * _phy_start_aneg - start auto-negotiation for this PHY device |
1005 | * @phydev: the phy_device struct |
1006 | * |
1007 | * Description: Sanitizes the settings (if we're not autonegotiating |
1008 | * them), and then calls the driver's config_aneg function. |
1009 | * If the PHYCONTROL Layer is operating, we change the state to |
1010 | * reflect the beginning of Auto-negotiation or forcing. |
1011 | */ |
1012 | int _phy_start_aneg(struct phy_device *phydev) |
1013 | { |
1014 | int err; |
1015 | |
1016 | lockdep_assert_held(&phydev->lock); |
1017 | |
1018 | if (!phydev->drv) |
1019 | return -EIO; |
1020 | |
1021 | if (AUTONEG_DISABLE == phydev->autoneg) |
1022 | phy_sanitize_settings(phydev); |
1023 | |
1024 | err = phy_config_aneg(phydev); |
1025 | if (err < 0) |
1026 | return err; |
1027 | |
1028 | if (phy_is_started(phydev)) |
1029 | err = phy_check_link_status(phydev); |
1030 | |
1031 | return err; |
1032 | } |
1033 | EXPORT_SYMBOL(_phy_start_aneg); |
1034 | |
1035 | /** |
1036 | * phy_start_aneg - start auto-negotiation for this PHY device |
1037 | * @phydev: the phy_device struct |
1038 | * |
1039 | * Description: Sanitizes the settings (if we're not autonegotiating |
1040 | * them), and then calls the driver's config_aneg function. |
1041 | * If the PHYCONTROL Layer is operating, we change the state to |
1042 | * reflect the beginning of Auto-negotiation or forcing. |
1043 | */ |
1044 | int phy_start_aneg(struct phy_device *phydev) |
1045 | { |
1046 | int err; |
1047 | |
1048 | mutex_lock(&phydev->lock); |
1049 | err = _phy_start_aneg(phydev); |
1050 | mutex_unlock(lock: &phydev->lock); |
1051 | |
1052 | return err; |
1053 | } |
1054 | EXPORT_SYMBOL(phy_start_aneg); |
1055 | |
1056 | static int phy_poll_aneg_done(struct phy_device *phydev) |
1057 | { |
1058 | unsigned int retries = 100; |
1059 | int ret; |
1060 | |
1061 | do { |
1062 | msleep(msecs: 100); |
1063 | ret = phy_aneg_done(phydev); |
1064 | } while (!ret && --retries); |
1065 | |
1066 | if (!ret) |
1067 | return -ETIMEDOUT; |
1068 | |
1069 | return ret < 0 ? ret : 0; |
1070 | } |
1071 | |
1072 | int phy_ethtool_ksettings_set(struct phy_device *phydev, |
1073 | const struct ethtool_link_ksettings *cmd) |
1074 | { |
1075 | __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); |
1076 | u8 autoneg = cmd->base.autoneg; |
1077 | u8 duplex = cmd->base.duplex; |
1078 | u32 speed = cmd->base.speed; |
1079 | |
1080 | if (cmd->base.phy_address != phydev->mdio.addr) |
1081 | return -EINVAL; |
1082 | |
1083 | linkmode_copy(dst: advertising, src: cmd->link_modes.advertising); |
1084 | |
1085 | /* We make sure that we don't pass unsupported values in to the PHY */ |
1086 | linkmode_and(dst: advertising, a: advertising, b: phydev->supported); |
1087 | |
1088 | /* Verify the settings we care about. */ |
1089 | if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE) |
1090 | return -EINVAL; |
1091 | |
1092 | if (autoneg == AUTONEG_ENABLE && linkmode_empty(src: advertising)) |
1093 | return -EINVAL; |
1094 | |
1095 | if (autoneg == AUTONEG_DISABLE && |
1096 | ((speed != SPEED_1000 && |
1097 | speed != SPEED_100 && |
1098 | speed != SPEED_10) || |
1099 | (duplex != DUPLEX_HALF && |
1100 | duplex != DUPLEX_FULL))) |
1101 | return -EINVAL; |
1102 | |
1103 | mutex_lock(&phydev->lock); |
1104 | phydev->autoneg = autoneg; |
1105 | |
1106 | if (autoneg == AUTONEG_DISABLE) { |
1107 | phydev->speed = speed; |
1108 | phydev->duplex = duplex; |
1109 | } |
1110 | |
1111 | linkmode_copy(dst: phydev->advertising, src: advertising); |
1112 | |
1113 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, |
1114 | addr: phydev->advertising, set: autoneg == AUTONEG_ENABLE); |
1115 | |
1116 | phydev->master_slave_set = cmd->base.master_slave_cfg; |
1117 | phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl; |
1118 | |
1119 | /* Restart the PHY */ |
1120 | if (phy_is_started(phydev)) { |
1121 | phydev->state = PHY_UP; |
1122 | phy_trigger_machine(phydev); |
1123 | } else { |
1124 | _phy_start_aneg(phydev); |
1125 | } |
1126 | |
1127 | mutex_unlock(lock: &phydev->lock); |
1128 | return 0; |
1129 | } |
1130 | EXPORT_SYMBOL(phy_ethtool_ksettings_set); |
1131 | |
1132 | /** |
1133 | * phy_speed_down - set speed to lowest speed supported by both link partners |
1134 | * @phydev: the phy_device struct |
1135 | * @sync: perform action synchronously |
1136 | * |
1137 | * Description: Typically used to save energy when waiting for a WoL packet |
1138 | * |
1139 | * WARNING: Setting sync to false may cause the system being unable to suspend |
1140 | * in case the PHY generates an interrupt when finishing the autonegotiation. |
1141 | * This interrupt may wake up the system immediately after suspend. |
1142 | * Therefore use sync = false only if you're sure it's safe with the respective |
1143 | * network chip. |
1144 | */ |
1145 | int phy_speed_down(struct phy_device *phydev, bool sync) |
1146 | { |
1147 | __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp); |
1148 | int ret = 0; |
1149 | |
1150 | mutex_lock(&phydev->lock); |
1151 | |
1152 | if (phydev->autoneg != AUTONEG_ENABLE) |
1153 | goto out; |
1154 | |
1155 | linkmode_copy(dst: adv_tmp, src: phydev->advertising); |
1156 | |
1157 | ret = phy_speed_down_core(phydev); |
1158 | if (ret) |
1159 | goto out; |
1160 | |
1161 | linkmode_copy(dst: phydev->adv_old, src: adv_tmp); |
1162 | |
1163 | if (linkmode_equal(src1: phydev->advertising, src2: adv_tmp)) { |
1164 | ret = 0; |
1165 | goto out; |
1166 | } |
1167 | |
1168 | ret = phy_config_aneg(phydev); |
1169 | if (ret) |
1170 | goto out; |
1171 | |
1172 | ret = sync ? phy_poll_aneg_done(phydev) : 0; |
1173 | out: |
1174 | mutex_unlock(lock: &phydev->lock); |
1175 | |
1176 | return ret; |
1177 | } |
1178 | EXPORT_SYMBOL_GPL(phy_speed_down); |
1179 | |
1180 | /** |
1181 | * phy_speed_up - (re)set advertised speeds to all supported speeds |
1182 | * @phydev: the phy_device struct |
1183 | * |
1184 | * Description: Used to revert the effect of phy_speed_down |
1185 | */ |
1186 | int phy_speed_up(struct phy_device *phydev) |
1187 | { |
1188 | __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp); |
1189 | int ret = 0; |
1190 | |
1191 | mutex_lock(&phydev->lock); |
1192 | |
1193 | if (phydev->autoneg != AUTONEG_ENABLE) |
1194 | goto out; |
1195 | |
1196 | if (linkmode_empty(src: phydev->adv_old)) |
1197 | goto out; |
1198 | |
1199 | linkmode_copy(dst: adv_tmp, src: phydev->advertising); |
1200 | linkmode_copy(dst: phydev->advertising, src: phydev->adv_old); |
1201 | linkmode_zero(dst: phydev->adv_old); |
1202 | |
1203 | if (linkmode_equal(src1: phydev->advertising, src2: adv_tmp)) |
1204 | goto out; |
1205 | |
1206 | ret = phy_config_aneg(phydev); |
1207 | out: |
1208 | mutex_unlock(lock: &phydev->lock); |
1209 | |
1210 | return ret; |
1211 | } |
1212 | EXPORT_SYMBOL_GPL(phy_speed_up); |
1213 | |
1214 | /** |
1215 | * phy_start_machine - start PHY state machine tracking |
1216 | * @phydev: the phy_device struct |
1217 | * |
1218 | * Description: The PHY infrastructure can run a state machine |
1219 | * which tracks whether the PHY is starting up, negotiating, |
1220 | * etc. This function starts the delayed workqueue which tracks |
1221 | * the state of the PHY. If you want to maintain your own state machine, |
1222 | * do not call this function. |
1223 | */ |
1224 | void phy_start_machine(struct phy_device *phydev) |
1225 | { |
1226 | phy_trigger_machine(phydev); |
1227 | } |
1228 | EXPORT_SYMBOL_GPL(phy_start_machine); |
1229 | |
1230 | /** |
1231 | * phy_stop_machine - stop the PHY state machine tracking |
1232 | * @phydev: target phy_device struct |
1233 | * |
1234 | * Description: Stops the state machine delayed workqueue, sets the |
1235 | * state to UP (unless it wasn't up yet). This function must be |
1236 | * called BEFORE phy_detach. |
1237 | */ |
1238 | void phy_stop_machine(struct phy_device *phydev) |
1239 | { |
1240 | cancel_delayed_work_sync(dwork: &phydev->state_queue); |
1241 | |
1242 | mutex_lock(&phydev->lock); |
1243 | if (phy_is_started(phydev)) |
1244 | phydev->state = PHY_UP; |
1245 | mutex_unlock(lock: &phydev->lock); |
1246 | } |
1247 | |
1248 | static void phy_process_error(struct phy_device *phydev) |
1249 | { |
1250 | /* phydev->lock must be held for the state change to be safe */ |
1251 | if (!mutex_is_locked(lock: &phydev->lock)) |
1252 | phydev_err(phydev, "PHY-device data unsafe context\n" ); |
1253 | |
1254 | phydev->state = PHY_ERROR; |
1255 | |
1256 | phy_trigger_machine(phydev); |
1257 | } |
1258 | |
1259 | static void phy_error_precise(struct phy_device *phydev, |
1260 | const void *func, int err) |
1261 | { |
1262 | WARN(1, "%pS: returned: %d\n" , func, err); |
1263 | phy_process_error(phydev); |
1264 | } |
1265 | |
1266 | /** |
1267 | * phy_error - enter ERROR state for this PHY device |
1268 | * @phydev: target phy_device struct |
1269 | * |
1270 | * Moves the PHY to the ERROR state in response to a read |
1271 | * or write error, and tells the controller the link is down. |
1272 | * Must be called with phydev->lock held. |
1273 | */ |
1274 | void phy_error(struct phy_device *phydev) |
1275 | { |
1276 | WARN_ON(1); |
1277 | phy_process_error(phydev); |
1278 | } |
1279 | EXPORT_SYMBOL(phy_error); |
1280 | |
1281 | /** |
1282 | * phy_disable_interrupts - Disable the PHY interrupts from the PHY side |
1283 | * @phydev: target phy_device struct |
1284 | */ |
1285 | int phy_disable_interrupts(struct phy_device *phydev) |
1286 | { |
1287 | /* Disable PHY interrupts */ |
1288 | return phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); |
1289 | } |
1290 | |
1291 | /** |
1292 | * phy_interrupt - PHY interrupt handler |
1293 | * @irq: interrupt line |
1294 | * @phy_dat: phy_device pointer |
1295 | * |
1296 | * Description: Handle PHY interrupt |
1297 | */ |
1298 | static irqreturn_t phy_interrupt(int irq, void *phy_dat) |
1299 | { |
1300 | struct phy_device *phydev = phy_dat; |
1301 | irqreturn_t ret; |
1302 | |
1303 | /* Wakeup interrupts may occur during a system sleep transition. |
1304 | * Postpone handling until the PHY has resumed. |
1305 | */ |
1306 | if (IS_ENABLED(CONFIG_PM_SLEEP) && phydev->irq_suspended) { |
1307 | struct net_device *netdev = phydev->attached_dev; |
1308 | |
1309 | if (netdev) { |
1310 | struct device *parent = netdev->dev.parent; |
1311 | |
1312 | if (netdev->wol_enabled) |
1313 | pm_system_wakeup(); |
1314 | else if (device_may_wakeup(dev: &netdev->dev)) |
1315 | pm_wakeup_dev_event(dev: &netdev->dev, msec: 0, hard: true); |
1316 | else if (parent && device_may_wakeup(dev: parent)) |
1317 | pm_wakeup_dev_event(dev: parent, msec: 0, hard: true); |
1318 | } |
1319 | |
1320 | phydev->irq_rerun = 1; |
1321 | disable_irq_nosync(irq); |
1322 | return IRQ_HANDLED; |
1323 | } |
1324 | |
1325 | mutex_lock(&phydev->lock); |
1326 | ret = phydev->drv->handle_interrupt(phydev); |
1327 | mutex_unlock(lock: &phydev->lock); |
1328 | |
1329 | return ret; |
1330 | } |
1331 | |
1332 | /** |
1333 | * phy_enable_interrupts - Enable the interrupts from the PHY side |
1334 | * @phydev: target phy_device struct |
1335 | */ |
1336 | static int phy_enable_interrupts(struct phy_device *phydev) |
1337 | { |
1338 | return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); |
1339 | } |
1340 | |
1341 | /** |
1342 | * phy_request_interrupt - request and enable interrupt for a PHY device |
1343 | * @phydev: target phy_device struct |
1344 | * |
1345 | * Description: Request and enable the interrupt for the given PHY. |
1346 | * If this fails, then we set irq to PHY_POLL. |
1347 | * This should only be called with a valid IRQ number. |
1348 | */ |
1349 | void phy_request_interrupt(struct phy_device *phydev) |
1350 | { |
1351 | int err; |
1352 | |
1353 | err = request_threaded_irq(irq: phydev->irq, NULL, thread_fn: phy_interrupt, |
1354 | IRQF_ONESHOT | IRQF_SHARED, |
1355 | name: phydev_name(phydev), dev: phydev); |
1356 | if (err) { |
1357 | phydev_warn(phydev, "Error %d requesting IRQ %d, falling back to polling\n" , |
1358 | err, phydev->irq); |
1359 | phydev->irq = PHY_POLL; |
1360 | } else { |
1361 | if (phy_enable_interrupts(phydev)) { |
1362 | phydev_warn(phydev, "Can't enable interrupt, falling back to polling\n" ); |
1363 | phy_free_interrupt(phydev); |
1364 | phydev->irq = PHY_POLL; |
1365 | } |
1366 | } |
1367 | } |
1368 | EXPORT_SYMBOL(phy_request_interrupt); |
1369 | |
1370 | /** |
1371 | * phy_free_interrupt - disable and free interrupt for a PHY device |
1372 | * @phydev: target phy_device struct |
1373 | * |
1374 | * Description: Disable and free the interrupt for the given PHY. |
1375 | * This should only be called with a valid IRQ number. |
1376 | */ |
1377 | void phy_free_interrupt(struct phy_device *phydev) |
1378 | { |
1379 | phy_disable_interrupts(phydev); |
1380 | free_irq(phydev->irq, phydev); |
1381 | } |
1382 | EXPORT_SYMBOL(phy_free_interrupt); |
1383 | |
1384 | enum phy_state_work { |
1385 | PHY_STATE_WORK_NONE, |
1386 | PHY_STATE_WORK_ANEG, |
1387 | PHY_STATE_WORK_SUSPEND, |
1388 | }; |
1389 | |
1390 | static enum phy_state_work _phy_state_machine(struct phy_device *phydev) |
1391 | { |
1392 | enum phy_state_work state_work = PHY_STATE_WORK_NONE; |
1393 | struct net_device *dev = phydev->attached_dev; |
1394 | enum phy_state old_state = phydev->state; |
1395 | const void *func = NULL; |
1396 | bool finished = false; |
1397 | int err = 0; |
1398 | |
1399 | switch (phydev->state) { |
1400 | case PHY_DOWN: |
1401 | case PHY_READY: |
1402 | break; |
1403 | case PHY_UP: |
1404 | state_work = PHY_STATE_WORK_ANEG; |
1405 | break; |
1406 | case PHY_NOLINK: |
1407 | case PHY_RUNNING: |
1408 | err = phy_check_link_status(phydev); |
1409 | func = &phy_check_link_status; |
1410 | break; |
1411 | case PHY_CABLETEST: |
1412 | err = phydev->drv->cable_test_get_status(phydev, &finished); |
1413 | if (err) { |
1414 | phy_abort_cable_test(phydev); |
1415 | netif_testing_off(dev); |
1416 | state_work = PHY_STATE_WORK_ANEG; |
1417 | phydev->state = PHY_UP; |
1418 | break; |
1419 | } |
1420 | |
1421 | if (finished) { |
1422 | ethnl_cable_test_finished(phydev); |
1423 | netif_testing_off(dev); |
1424 | state_work = PHY_STATE_WORK_ANEG; |
1425 | phydev->state = PHY_UP; |
1426 | } |
1427 | break; |
1428 | case PHY_HALTED: |
1429 | case PHY_ERROR: |
1430 | if (phydev->link) { |
1431 | phydev->link = 0; |
1432 | phy_link_down(phydev); |
1433 | } |
1434 | state_work = PHY_STATE_WORK_SUSPEND; |
1435 | break; |
1436 | } |
1437 | |
1438 | if (state_work == PHY_STATE_WORK_ANEG) { |
1439 | err = _phy_start_aneg(phydev); |
1440 | func = &_phy_start_aneg; |
1441 | } |
1442 | |
1443 | if (err == -ENODEV) |
1444 | return state_work; |
1445 | |
1446 | if (err < 0) |
1447 | phy_error_precise(phydev, func, err); |
1448 | |
1449 | phy_process_state_change(phydev, old_state); |
1450 | |
1451 | /* Only re-schedule a PHY state machine change if we are polling the |
1452 | * PHY, if PHY_MAC_INTERRUPT is set, then we will be moving |
1453 | * between states from phy_mac_interrupt(). |
1454 | * |
1455 | * In state PHY_HALTED the PHY gets suspended, so rescheduling the |
1456 | * state machine would be pointless and possibly error prone when |
1457 | * called from phy_disconnect() synchronously. |
1458 | */ |
1459 | if (phy_polling_mode(phydev) && phy_is_started(phydev)) |
1460 | phy_queue_state_machine(phydev, PHY_STATE_TIME); |
1461 | |
1462 | return state_work; |
1463 | } |
1464 | |
1465 | /* unlocked part of the PHY state machine */ |
1466 | static void _phy_state_machine_post_work(struct phy_device *phydev, |
1467 | enum phy_state_work state_work) |
1468 | { |
1469 | if (state_work == PHY_STATE_WORK_SUSPEND) |
1470 | phy_suspend(phydev); |
1471 | } |
1472 | |
1473 | /** |
1474 | * phy_state_machine - Handle the state machine |
1475 | * @work: work_struct that describes the work to be done |
1476 | */ |
1477 | void phy_state_machine(struct work_struct *work) |
1478 | { |
1479 | struct delayed_work *dwork = to_delayed_work(work); |
1480 | struct phy_device *phydev = |
1481 | container_of(dwork, struct phy_device, state_queue); |
1482 | enum phy_state_work state_work; |
1483 | |
1484 | mutex_lock(&phydev->lock); |
1485 | state_work = _phy_state_machine(phydev); |
1486 | mutex_unlock(lock: &phydev->lock); |
1487 | |
1488 | _phy_state_machine_post_work(phydev, state_work); |
1489 | } |
1490 | |
1491 | /** |
1492 | * phy_stop - Bring down the PHY link, and stop checking the status |
1493 | * @phydev: target phy_device struct |
1494 | */ |
1495 | void phy_stop(struct phy_device *phydev) |
1496 | { |
1497 | struct net_device *dev = phydev->attached_dev; |
1498 | enum phy_state_work state_work; |
1499 | enum phy_state old_state; |
1500 | |
1501 | if (!phy_is_started(phydev) && phydev->state != PHY_DOWN && |
1502 | phydev->state != PHY_ERROR) { |
1503 | WARN(1, "called from state %s\n" , |
1504 | phy_state_to_str(phydev->state)); |
1505 | return; |
1506 | } |
1507 | |
1508 | mutex_lock(&phydev->lock); |
1509 | old_state = phydev->state; |
1510 | |
1511 | if (phydev->state == PHY_CABLETEST) { |
1512 | phy_abort_cable_test(phydev); |
1513 | netif_testing_off(dev); |
1514 | } |
1515 | |
1516 | if (phydev->sfp_bus) |
1517 | sfp_upstream_stop(bus: phydev->sfp_bus); |
1518 | |
1519 | phydev->state = PHY_HALTED; |
1520 | phy_process_state_change(phydev, old_state); |
1521 | |
1522 | state_work = _phy_state_machine(phydev); |
1523 | mutex_unlock(lock: &phydev->lock); |
1524 | |
1525 | _phy_state_machine_post_work(phydev, state_work); |
1526 | phy_stop_machine(phydev); |
1527 | |
1528 | /* Cannot call flush_scheduled_work() here as desired because |
1529 | * of rtnl_lock(), but PHY_HALTED shall guarantee irq handler |
1530 | * will not reenable interrupts. |
1531 | */ |
1532 | } |
1533 | EXPORT_SYMBOL(phy_stop); |
1534 | |
1535 | /** |
1536 | * phy_start - start or restart a PHY device |
1537 | * @phydev: target phy_device struct |
1538 | * |
1539 | * Description: Indicates the attached device's readiness to |
1540 | * handle PHY-related work. Used during startup to start the |
1541 | * PHY, and after a call to phy_stop() to resume operation. |
1542 | * Also used to indicate the MDIO bus has cleared an error |
1543 | * condition. |
1544 | */ |
1545 | void phy_start(struct phy_device *phydev) |
1546 | { |
1547 | mutex_lock(&phydev->lock); |
1548 | |
1549 | if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) { |
1550 | WARN(1, "called from state %s\n" , |
1551 | phy_state_to_str(phydev->state)); |
1552 | goto out; |
1553 | } |
1554 | |
1555 | if (phydev->sfp_bus) |
1556 | sfp_upstream_start(bus: phydev->sfp_bus); |
1557 | |
1558 | /* if phy was suspended, bring the physical link up again */ |
1559 | __phy_resume(phydev); |
1560 | |
1561 | phydev->state = PHY_UP; |
1562 | |
1563 | phy_start_machine(phydev); |
1564 | out: |
1565 | mutex_unlock(lock: &phydev->lock); |
1566 | } |
1567 | EXPORT_SYMBOL(phy_start); |
1568 | |
1569 | /** |
1570 | * phy_mac_interrupt - MAC says the link has changed |
1571 | * @phydev: phy_device struct with changed link |
1572 | * |
1573 | * The MAC layer is able to indicate there has been a change in the PHY link |
1574 | * status. Trigger the state machine and work a work queue. |
1575 | */ |
1576 | void phy_mac_interrupt(struct phy_device *phydev) |
1577 | { |
1578 | /* Trigger a state machine change */ |
1579 | phy_trigger_machine(phydev); |
1580 | } |
1581 | EXPORT_SYMBOL(phy_mac_interrupt); |
1582 | |
1583 | /** |
1584 | * phy_init_eee - init and check the EEE feature |
1585 | * @phydev: target phy_device struct |
1586 | * @clk_stop_enable: PHY may stop the clock during LPI |
1587 | * |
1588 | * Description: it checks if the Energy-Efficient Ethernet (EEE) |
1589 | * is supported by looking at the MMD registers 3.20 and 7.60/61 |
1590 | * and it programs the MMD register 3.0 setting the "Clock stop enable" |
1591 | * bit if required. |
1592 | */ |
1593 | int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) |
1594 | { |
1595 | int ret; |
1596 | |
1597 | if (!phydev->drv) |
1598 | return -EIO; |
1599 | |
1600 | ret = genphy_c45_eee_is_active(phydev, NULL, NULL, NULL); |
1601 | if (ret < 0) |
1602 | return ret; |
1603 | if (!ret) |
1604 | return -EPROTONOSUPPORT; |
1605 | |
1606 | if (clk_stop_enable) |
1607 | /* Configure the PHY to stop receiving xMII |
1608 | * clock while it is signaling LPI. |
1609 | */ |
1610 | ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, |
1611 | MDIO_PCS_CTRL1_CLKSTOP_EN); |
1612 | |
1613 | return ret < 0 ? ret : 0; |
1614 | } |
1615 | EXPORT_SYMBOL(phy_init_eee); |
1616 | |
1617 | /** |
1618 | * phy_get_eee_err - report the EEE wake error count |
1619 | * @phydev: target phy_device struct |
1620 | * |
1621 | * Description: it is to report the number of time where the PHY |
1622 | * failed to complete its normal wake sequence. |
1623 | */ |
1624 | int phy_get_eee_err(struct phy_device *phydev) |
1625 | { |
1626 | int ret; |
1627 | |
1628 | if (!phydev->drv) |
1629 | return -EIO; |
1630 | |
1631 | mutex_lock(&phydev->lock); |
1632 | ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR); |
1633 | mutex_unlock(lock: &phydev->lock); |
1634 | |
1635 | return ret; |
1636 | } |
1637 | EXPORT_SYMBOL(phy_get_eee_err); |
1638 | |
1639 | /** |
1640 | * phy_ethtool_get_eee - get EEE supported and status |
1641 | * @phydev: target phy_device struct |
1642 | * @data: ethtool_keee data |
1643 | * |
1644 | * Description: reports the Supported/Advertisement/LP Advertisement |
1645 | * capabilities, etc. |
1646 | */ |
1647 | int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_keee *data) |
1648 | { |
1649 | int ret; |
1650 | |
1651 | if (!phydev->drv) |
1652 | return -EIO; |
1653 | |
1654 | mutex_lock(&phydev->lock); |
1655 | ret = genphy_c45_ethtool_get_eee(phydev, data); |
1656 | eeecfg_to_eee(eee: data, eeecfg: &phydev->eee_cfg); |
1657 | mutex_unlock(lock: &phydev->lock); |
1658 | |
1659 | return ret; |
1660 | } |
1661 | EXPORT_SYMBOL(phy_ethtool_get_eee); |
1662 | |
1663 | /** |
1664 | * phy_ethtool_set_eee_noneg - Adjusts MAC LPI configuration without PHY |
1665 | * renegotiation |
1666 | * @phydev: pointer to the target PHY device structure |
1667 | * @data: pointer to the ethtool_keee structure containing the new EEE settings |
1668 | * |
1669 | * This function updates the Energy Efficient Ethernet (EEE) configuration |
1670 | * for cases where only the MAC's Low Power Idle (LPI) configuration changes, |
1671 | * without triggering PHY renegotiation. It ensures that the MAC is properly |
1672 | * informed of the new LPI settings by cycling the link down and up, which |
1673 | * is necessary for the MAC to adopt the new configuration. This adjustment |
1674 | * is done only if there is a change in the tx_lpi_enabled or tx_lpi_timer |
1675 | * configuration. |
1676 | */ |
1677 | static void phy_ethtool_set_eee_noneg(struct phy_device *phydev, |
1678 | struct ethtool_keee *data) |
1679 | { |
1680 | if (phydev->eee_cfg.tx_lpi_enabled != data->tx_lpi_enabled || |
1681 | phydev->eee_cfg.tx_lpi_timer != data->tx_lpi_timer) { |
1682 | eee_to_eeecfg(eeecfg: &phydev->eee_cfg, eee: data); |
1683 | phydev->enable_tx_lpi = eeecfg_mac_can_tx_lpi(eeecfg: &phydev->eee_cfg); |
1684 | if (phydev->link) { |
1685 | phydev->link = false; |
1686 | phy_link_down(phydev); |
1687 | phydev->link = true; |
1688 | phy_link_up(phydev); |
1689 | } |
1690 | } |
1691 | } |
1692 | |
1693 | /** |
1694 | * phy_ethtool_set_eee - set EEE supported and status |
1695 | * @phydev: target phy_device struct |
1696 | * @data: ethtool_keee data |
1697 | * |
1698 | * Description: it is to program the Advertisement EEE register. |
1699 | */ |
1700 | int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_keee *data) |
1701 | { |
1702 | int ret; |
1703 | |
1704 | if (!phydev->drv) |
1705 | return -EIO; |
1706 | |
1707 | mutex_lock(&phydev->lock); |
1708 | ret = genphy_c45_ethtool_set_eee(phydev, data); |
1709 | if (ret >= 0) { |
1710 | if (ret == 0) |
1711 | phy_ethtool_set_eee_noneg(phydev, data); |
1712 | eee_to_eeecfg(eeecfg: &phydev->eee_cfg, eee: data); |
1713 | } |
1714 | mutex_unlock(lock: &phydev->lock); |
1715 | |
1716 | return ret < 0 ? ret : 0; |
1717 | } |
1718 | EXPORT_SYMBOL(phy_ethtool_set_eee); |
1719 | |
1720 | /** |
1721 | * phy_ethtool_set_wol - Configure Wake On LAN |
1722 | * |
1723 | * @phydev: target phy_device struct |
1724 | * @wol: Configuration requested |
1725 | */ |
1726 | int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) |
1727 | { |
1728 | int ret; |
1729 | |
1730 | if (phydev->drv && phydev->drv->set_wol) { |
1731 | mutex_lock(&phydev->lock); |
1732 | ret = phydev->drv->set_wol(phydev, wol); |
1733 | mutex_unlock(lock: &phydev->lock); |
1734 | |
1735 | return ret; |
1736 | } |
1737 | |
1738 | return -EOPNOTSUPP; |
1739 | } |
1740 | EXPORT_SYMBOL(phy_ethtool_set_wol); |
1741 | |
1742 | /** |
1743 | * phy_ethtool_get_wol - Get the current Wake On LAN configuration |
1744 | * |
1745 | * @phydev: target phy_device struct |
1746 | * @wol: Store the current configuration here |
1747 | */ |
1748 | void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) |
1749 | { |
1750 | if (phydev->drv && phydev->drv->get_wol) { |
1751 | mutex_lock(&phydev->lock); |
1752 | phydev->drv->get_wol(phydev, wol); |
1753 | mutex_unlock(lock: &phydev->lock); |
1754 | } |
1755 | } |
1756 | EXPORT_SYMBOL(phy_ethtool_get_wol); |
1757 | |
1758 | int phy_ethtool_get_link_ksettings(struct net_device *ndev, |
1759 | struct ethtool_link_ksettings *cmd) |
1760 | { |
1761 | struct phy_device *phydev = ndev->phydev; |
1762 | |
1763 | if (!phydev) |
1764 | return -ENODEV; |
1765 | |
1766 | phy_ethtool_ksettings_get(phydev, cmd); |
1767 | |
1768 | return 0; |
1769 | } |
1770 | EXPORT_SYMBOL(phy_ethtool_get_link_ksettings); |
1771 | |
1772 | int phy_ethtool_set_link_ksettings(struct net_device *ndev, |
1773 | const struct ethtool_link_ksettings *cmd) |
1774 | { |
1775 | struct phy_device *phydev = ndev->phydev; |
1776 | |
1777 | if (!phydev) |
1778 | return -ENODEV; |
1779 | |
1780 | return phy_ethtool_ksettings_set(phydev, cmd); |
1781 | } |
1782 | EXPORT_SYMBOL(phy_ethtool_set_link_ksettings); |
1783 | |
1784 | /** |
1785 | * phy_ethtool_nway_reset - Restart auto negotiation |
1786 | * @ndev: Network device to restart autoneg for |
1787 | */ |
1788 | int phy_ethtool_nway_reset(struct net_device *ndev) |
1789 | { |
1790 | struct phy_device *phydev = ndev->phydev; |
1791 | int ret; |
1792 | |
1793 | if (!phydev) |
1794 | return -ENODEV; |
1795 | |
1796 | if (!phydev->drv) |
1797 | return -EIO; |
1798 | |
1799 | mutex_lock(&phydev->lock); |
1800 | ret = phy_restart_aneg(phydev); |
1801 | mutex_unlock(lock: &phydev->lock); |
1802 | |
1803 | return ret; |
1804 | } |
1805 | EXPORT_SYMBOL(phy_ethtool_nway_reset); |
1806 | |