]>
Commit | Line | Data |
---|---|---|
a2443fd1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2f53e904 | 2 | /* Framework for finding and configuring PHYs. |
00db8189 AF |
3 | * Also contains generic PHY driver |
4 | * | |
5 | * Author: Andy Fleming | |
6 | * | |
7 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | |
00db8189 | 8 | */ |
8d242488 JP |
9 | |
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
11 | ||
00db8189 | 12 | #include <linux/kernel.h> |
00db8189 AF |
13 | #include <linux/string.h> |
14 | #include <linux/errno.h> | |
15 | #include <linux/unistd.h> | |
16 | #include <linux/slab.h> | |
17 | #include <linux/interrupt.h> | |
18 | #include <linux/init.h> | |
19 | #include <linux/delay.h> | |
20 | #include <linux/netdevice.h> | |
21 | #include <linux/etherdevice.h> | |
22 | #include <linux/skbuff.h> | |
00db8189 AF |
23 | #include <linux/mm.h> |
24 | #include <linux/module.h> | |
00db8189 AF |
25 | #include <linux/mii.h> |
26 | #include <linux/ethtool.h> | |
719655a1 | 27 | #include <linux/bitmap.h> |
00db8189 | 28 | #include <linux/phy.h> |
2e0bc452 | 29 | #include <linux/phy_led_triggers.h> |
124059fd | 30 | #include <linux/mdio.h> |
2f53e904 SS |
31 | #include <linux/io.h> |
32 | #include <linux/uaccess.h> | |
de906af1 | 33 | #include <linux/of.h> |
00db8189 | 34 | |
afcceaa3 OH |
35 | MODULE_DESCRIPTION("PHY library"); |
36 | MODULE_AUTHOR("Andy Fleming"); | |
37 | MODULE_LICENSE("GPL"); | |
38 | ||
719655a1 AL |
39 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init; |
40 | EXPORT_SYMBOL_GPL(phy_basic_features); | |
41 | ||
42 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init; | |
43 | EXPORT_SYMBOL_GPL(phy_basic_t1_features); | |
44 | ||
45 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init; | |
46 | EXPORT_SYMBOL_GPL(phy_gbit_features); | |
47 | ||
48 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init; | |
49 | EXPORT_SYMBOL_GPL(phy_gbit_fibre_features); | |
50 | ||
51 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init; | |
52 | EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features); | |
53 | ||
54 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init; | |
55 | EXPORT_SYMBOL_GPL(phy_10gbit_features); | |
56 | ||
9e857a40 AL |
57 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_fec_features) __ro_after_init; |
58 | EXPORT_SYMBOL_GPL(phy_10gbit_fec_features); | |
59 | ||
719655a1 AL |
60 | static const int phy_basic_ports_array[] = { |
61 | ETHTOOL_LINK_MODE_Autoneg_BIT, | |
62 | ETHTOOL_LINK_MODE_TP_BIT, | |
63 | ETHTOOL_LINK_MODE_MII_BIT, | |
64 | }; | |
3c1bcc86 | 65 | EXPORT_SYMBOL_GPL(phy_basic_ports_array); |
719655a1 AL |
66 | |
67 | static const int phy_fibre_port_array[] = { | |
68 | ETHTOOL_LINK_MODE_FIBRE_BIT, | |
69 | }; | |
3c1bcc86 | 70 | EXPORT_SYMBOL_GPL(phy_fibre_port_array); |
719655a1 AL |
71 | |
72 | static const int phy_all_ports_features_array[] = { | |
73 | ETHTOOL_LINK_MODE_Autoneg_BIT, | |
74 | ETHTOOL_LINK_MODE_TP_BIT, | |
75 | ETHTOOL_LINK_MODE_MII_BIT, | |
76 | ETHTOOL_LINK_MODE_FIBRE_BIT, | |
77 | ETHTOOL_LINK_MODE_AUI_BIT, | |
78 | ETHTOOL_LINK_MODE_BNC_BIT, | |
79 | ETHTOOL_LINK_MODE_Backplane_BIT, | |
80 | }; | |
3c1bcc86 | 81 | EXPORT_SYMBOL_GPL(phy_all_ports_features_array); |
719655a1 | 82 | |
3c1bcc86 | 83 | const int phy_10_100_features_array[4] = { |
719655a1 AL |
84 | ETHTOOL_LINK_MODE_10baseT_Half_BIT, |
85 | ETHTOOL_LINK_MODE_10baseT_Full_BIT, | |
86 | ETHTOOL_LINK_MODE_100baseT_Half_BIT, | |
87 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | |
88 | }; | |
3c1bcc86 | 89 | EXPORT_SYMBOL_GPL(phy_10_100_features_array); |
719655a1 | 90 | |
3c1bcc86 | 91 | const int phy_basic_t1_features_array[2] = { |
719655a1 AL |
92 | ETHTOOL_LINK_MODE_TP_BIT, |
93 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | |
94 | }; | |
3c1bcc86 | 95 | EXPORT_SYMBOL_GPL(phy_basic_t1_features_array); |
719655a1 | 96 | |
3c1bcc86 | 97 | const int phy_gbit_features_array[2] = { |
719655a1 AL |
98 | ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
99 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | |
100 | }; | |
3c1bcc86 | 101 | EXPORT_SYMBOL_GPL(phy_gbit_features_array); |
719655a1 | 102 | |
3c1bcc86 | 103 | const int phy_10gbit_features_array[1] = { |
719655a1 AL |
104 | ETHTOOL_LINK_MODE_10000baseT_Full_BIT, |
105 | }; | |
3c1bcc86 | 106 | EXPORT_SYMBOL_GPL(phy_10gbit_features_array); |
719655a1 | 107 | |
9e857a40 AL |
108 | const int phy_10gbit_fec_features_array[1] = { |
109 | ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, | |
110 | }; | |
111 | EXPORT_SYMBOL_GPL(phy_10gbit_fec_features_array); | |
112 | ||
719655a1 AL |
113 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; |
114 | EXPORT_SYMBOL_GPL(phy_10gbit_full_features); | |
115 | ||
116 | static const int phy_10gbit_full_features_array[] = { | |
117 | ETHTOOL_LINK_MODE_10baseT_Full_BIT, | |
118 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | |
119 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | |
120 | ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | |
121 | }; | |
122 | ||
123 | static void features_init(void) | |
124 | { | |
125 | /* 10/100 half/full*/ | |
126 | linkmode_set_bit_array(phy_basic_ports_array, | |
127 | ARRAY_SIZE(phy_basic_ports_array), | |
128 | phy_basic_features); | |
129 | linkmode_set_bit_array(phy_10_100_features_array, | |
130 | ARRAY_SIZE(phy_10_100_features_array), | |
131 | phy_basic_features); | |
132 | ||
133 | /* 100 full, TP */ | |
134 | linkmode_set_bit_array(phy_basic_t1_features_array, | |
135 | ARRAY_SIZE(phy_basic_t1_features_array), | |
136 | phy_basic_t1_features); | |
137 | ||
138 | /* 10/100 half/full + 1000 half/full */ | |
139 | linkmode_set_bit_array(phy_basic_ports_array, | |
140 | ARRAY_SIZE(phy_basic_ports_array), | |
141 | phy_gbit_features); | |
142 | linkmode_set_bit_array(phy_10_100_features_array, | |
143 | ARRAY_SIZE(phy_10_100_features_array), | |
144 | phy_gbit_features); | |
145 | linkmode_set_bit_array(phy_gbit_features_array, | |
146 | ARRAY_SIZE(phy_gbit_features_array), | |
147 | phy_gbit_features); | |
148 | ||
149 | /* 10/100 half/full + 1000 half/full + fibre*/ | |
150 | linkmode_set_bit_array(phy_basic_ports_array, | |
151 | ARRAY_SIZE(phy_basic_ports_array), | |
152 | phy_gbit_fibre_features); | |
153 | linkmode_set_bit_array(phy_10_100_features_array, | |
154 | ARRAY_SIZE(phy_10_100_features_array), | |
155 | phy_gbit_fibre_features); | |
156 | linkmode_set_bit_array(phy_gbit_features_array, | |
157 | ARRAY_SIZE(phy_gbit_features_array), | |
158 | phy_gbit_fibre_features); | |
159 | linkmode_set_bit_array(phy_fibre_port_array, | |
160 | ARRAY_SIZE(phy_fibre_port_array), | |
161 | phy_gbit_fibre_features); | |
162 | ||
163 | /* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/ | |
164 | linkmode_set_bit_array(phy_all_ports_features_array, | |
165 | ARRAY_SIZE(phy_all_ports_features_array), | |
166 | phy_gbit_all_ports_features); | |
167 | linkmode_set_bit_array(phy_10_100_features_array, | |
168 | ARRAY_SIZE(phy_10_100_features_array), | |
169 | phy_gbit_all_ports_features); | |
170 | linkmode_set_bit_array(phy_gbit_features_array, | |
171 | ARRAY_SIZE(phy_gbit_features_array), | |
172 | phy_gbit_all_ports_features); | |
173 | ||
174 | /* 10/100 half/full + 1000 half/full + 10G full*/ | |
175 | linkmode_set_bit_array(phy_all_ports_features_array, | |
176 | ARRAY_SIZE(phy_all_ports_features_array), | |
177 | phy_10gbit_features); | |
178 | linkmode_set_bit_array(phy_10_100_features_array, | |
179 | ARRAY_SIZE(phy_10_100_features_array), | |
180 | phy_10gbit_features); | |
181 | linkmode_set_bit_array(phy_gbit_features_array, | |
182 | ARRAY_SIZE(phy_gbit_features_array), | |
183 | phy_10gbit_features); | |
184 | linkmode_set_bit_array(phy_10gbit_features_array, | |
185 | ARRAY_SIZE(phy_10gbit_features_array), | |
186 | phy_10gbit_features); | |
187 | ||
188 | /* 10/100/1000/10G full */ | |
189 | linkmode_set_bit_array(phy_all_ports_features_array, | |
190 | ARRAY_SIZE(phy_all_ports_features_array), | |
191 | phy_10gbit_full_features); | |
192 | linkmode_set_bit_array(phy_10gbit_full_features_array, | |
193 | ARRAY_SIZE(phy_10gbit_full_features_array), | |
194 | phy_10gbit_full_features); | |
9e857a40 AL |
195 | /* 10G FEC only */ |
196 | linkmode_set_bit_array(phy_10gbit_fec_features_array, | |
197 | ARRAY_SIZE(phy_10gbit_fec_features_array), | |
198 | phy_10gbit_fec_features); | |
719655a1 AL |
199 | } |
200 | ||
6f4a7f41 AV |
201 | void phy_device_free(struct phy_device *phydev) |
202 | { | |
e5a03bfd | 203 | put_device(&phydev->mdio.dev); |
6f4a7f41 | 204 | } |
4dea547f | 205 | EXPORT_SYMBOL(phy_device_free); |
6f4a7f41 | 206 | |
711fdba3 AL |
207 | static void phy_mdio_device_free(struct mdio_device *mdiodev) |
208 | { | |
209 | struct phy_device *phydev; | |
210 | ||
211 | phydev = container_of(mdiodev, struct phy_device, mdio); | |
212 | phy_device_free(phydev); | |
213 | } | |
214 | ||
6f4a7f41 AV |
215 | static void phy_device_release(struct device *dev) |
216 | { | |
b2a43191 | 217 | kfree(to_phy_device(dev)); |
6f4a7f41 AV |
218 | } |
219 | ||
711fdba3 AL |
220 | static void phy_mdio_device_remove(struct mdio_device *mdiodev) |
221 | { | |
222 | struct phy_device *phydev; | |
223 | ||
224 | phydev = container_of(mdiodev, struct phy_device, mdio); | |
225 | phy_device_remove(phydev); | |
226 | } | |
227 | ||
921690f2 RK |
228 | static struct phy_driver genphy_driver; |
229 | extern struct phy_driver genphy_10g_driver; | |
4dea547f | 230 | |
f62220d3 AF |
231 | static LIST_HEAD(phy_fixup_list); |
232 | static DEFINE_MUTEX(phy_fixup_lock); | |
233 | ||
bc87922f AL |
234 | #ifdef CONFIG_PM |
235 | static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | |
236 | { | |
237 | struct device_driver *drv = phydev->mdio.dev.driver; | |
238 | struct phy_driver *phydrv = to_phy_driver(drv); | |
239 | struct net_device *netdev = phydev->attached_dev; | |
240 | ||
241 | if (!drv || !phydrv->suspend) | |
242 | return false; | |
243 | ||
244 | /* PHY not attached? May suspend if the PHY has not already been | |
245 | * suspended as part of a prior call to phy_disconnect() -> | |
246 | * phy_detach() -> phy_suspend() because the parent netdev might be the | |
247 | * MDIO bus driver and clock gated at this point. | |
248 | */ | |
249 | if (!netdev) | |
250 | return !phydev->suspended; | |
251 | ||
93f41e67 HK |
252 | if (netdev->wol_enabled) |
253 | return false; | |
254 | ||
255 | /* As long as not all affected network drivers support the | |
256 | * wol_enabled flag, let's check for hints that WoL is enabled. | |
257 | * Don't suspend PHY if the attached netdev parent may wake up. | |
bc87922f AL |
258 | * The parent may point to a PCI device, as in tg3 driver. |
259 | */ | |
260 | if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) | |
261 | return false; | |
262 | ||
263 | /* Also don't suspend PHY if the netdev itself may wakeup. This | |
264 | * is the case for devices w/o underlaying pwr. mgmt. aware bus, | |
265 | * e.g. SoC devices. | |
266 | */ | |
267 | if (device_may_wakeup(&netdev->dev)) | |
268 | return false; | |
269 | ||
270 | return true; | |
271 | } | |
272 | ||
273 | static int mdio_bus_phy_suspend(struct device *dev) | |
274 | { | |
275 | struct phy_device *phydev = to_phy_device(dev); | |
276 | ||
277 | /* We must stop the state machine manually, otherwise it stops out of | |
278 | * control, possibly with the phydev->lock held. Upon resume, netdev | |
279 | * may call phy routines that try to grab the same lock, and that may | |
280 | * lead to a deadlock. | |
281 | */ | |
282 | if (phydev->attached_dev && phydev->adjust_link) | |
283 | phy_stop_machine(phydev); | |
284 | ||
285 | if (!mdio_bus_phy_may_suspend(phydev)) | |
286 | return 0; | |
287 | ||
288 | return phy_suspend(phydev); | |
289 | } | |
290 | ||
291 | static int mdio_bus_phy_resume(struct device *dev) | |
292 | { | |
293 | struct phy_device *phydev = to_phy_device(dev); | |
294 | int ret; | |
295 | ||
296 | if (!mdio_bus_phy_may_suspend(phydev)) | |
297 | goto no_resume; | |
298 | ||
299 | ret = phy_resume(phydev); | |
300 | if (ret < 0) | |
301 | return ret; | |
302 | ||
303 | no_resume: | |
304 | if (phydev->attached_dev && phydev->adjust_link) | |
305 | phy_start_machine(phydev); | |
306 | ||
307 | return 0; | |
308 | } | |
309 | ||
310 | static int mdio_bus_phy_restore(struct device *dev) | |
311 | { | |
312 | struct phy_device *phydev = to_phy_device(dev); | |
313 | struct net_device *netdev = phydev->attached_dev; | |
314 | int ret; | |
315 | ||
316 | if (!netdev) | |
317 | return 0; | |
318 | ||
319 | ret = phy_init_hw(phydev); | |
320 | if (ret < 0) | |
321 | return ret; | |
322 | ||
8742beb5 KH |
323 | if (phydev->attached_dev && phydev->adjust_link) |
324 | phy_start_machine(phydev); | |
bc87922f AL |
325 | |
326 | return 0; | |
327 | } | |
328 | ||
329 | static const struct dev_pm_ops mdio_bus_phy_pm_ops = { | |
330 | .suspend = mdio_bus_phy_suspend, | |
331 | .resume = mdio_bus_phy_resume, | |
332 | .freeze = mdio_bus_phy_suspend, | |
333 | .thaw = mdio_bus_phy_resume, | |
334 | .restore = mdio_bus_phy_restore, | |
335 | }; | |
336 | ||
337 | #define MDIO_BUS_PHY_PM_OPS (&mdio_bus_phy_pm_ops) | |
338 | ||
339 | #else | |
340 | ||
341 | #define MDIO_BUS_PHY_PM_OPS NULL | |
342 | ||
343 | #endif /* CONFIG_PM */ | |
344 | ||
2f53e904 SS |
345 | /** |
346 | * phy_register_fixup - creates a new phy_fixup and adds it to the list | |
e5a03bfd | 347 | * @bus_id: A string which matches phydev->mdio.dev.bus_id (or PHY_ANY_ID) |
f62220d3 | 348 | * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY) |
2f53e904 | 349 | * It can also be PHY_ANY_UID |
f62220d3 | 350 | * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before |
2f53e904 | 351 | * comparison |
f62220d3 AF |
352 | * @run: The actual code to be run when a matching PHY is found |
353 | */ | |
354 | int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, | |
2f53e904 | 355 | int (*run)(struct phy_device *)) |
f62220d3 | 356 | { |
553fe92b | 357 | struct phy_fixup *fixup = kzalloc(sizeof(*fixup), GFP_KERNEL); |
f62220d3 | 358 | |
f62220d3 AF |
359 | if (!fixup) |
360 | return -ENOMEM; | |
361 | ||
fb28ad35 | 362 | strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id)); |
f62220d3 AF |
363 | fixup->phy_uid = phy_uid; |
364 | fixup->phy_uid_mask = phy_uid_mask; | |
365 | fixup->run = run; | |
366 | ||
367 | mutex_lock(&phy_fixup_lock); | |
368 | list_add_tail(&fixup->list, &phy_fixup_list); | |
369 | mutex_unlock(&phy_fixup_lock); | |
370 | ||
371 | return 0; | |
372 | } | |
373 | EXPORT_SYMBOL(phy_register_fixup); | |
374 | ||
375 | /* Registers a fixup to be run on any PHY with the UID in phy_uid */ | |
376 | int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, | |
2f53e904 | 377 | int (*run)(struct phy_device *)) |
f62220d3 AF |
378 | { |
379 | return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run); | |
380 | } | |
381 | EXPORT_SYMBOL(phy_register_fixup_for_uid); | |
382 | ||
383 | /* Registers a fixup to be run on the PHY with id string bus_id */ | |
384 | int phy_register_fixup_for_id(const char *bus_id, | |
2f53e904 | 385 | int (*run)(struct phy_device *)) |
f62220d3 AF |
386 | { |
387 | return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run); | |
388 | } | |
389 | EXPORT_SYMBOL(phy_register_fixup_for_id); | |
390 | ||
f38e7a32 WH |
391 | /** |
392 | * phy_unregister_fixup - remove a phy_fixup from the list | |
393 | * @bus_id: A string matches fixup->bus_id (or PHY_ANY_ID) in phy_fixup_list | |
394 | * @phy_uid: A phy id matches fixup->phy_id (or PHY_ANY_UID) in phy_fixup_list | |
395 | * @phy_uid_mask: Applied to phy_uid and fixup->phy_uid before comparison | |
396 | */ | |
397 | int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask) | |
398 | { | |
399 | struct list_head *pos, *n; | |
400 | struct phy_fixup *fixup; | |
401 | int ret; | |
402 | ||
403 | ret = -ENODEV; | |
404 | ||
405 | mutex_lock(&phy_fixup_lock); | |
406 | list_for_each_safe(pos, n, &phy_fixup_list) { | |
407 | fixup = list_entry(pos, struct phy_fixup, list); | |
408 | ||
409 | if ((!strcmp(fixup->bus_id, bus_id)) && | |
410 | ((fixup->phy_uid & phy_uid_mask) == | |
411 | (phy_uid & phy_uid_mask))) { | |
412 | list_del(&fixup->list); | |
413 | kfree(fixup); | |
414 | ret = 0; | |
415 | break; | |
416 | } | |
417 | } | |
418 | mutex_unlock(&phy_fixup_lock); | |
419 | ||
420 | return ret; | |
421 | } | |
422 | EXPORT_SYMBOL(phy_unregister_fixup); | |
423 | ||
424 | /* Unregisters a fixup of any PHY with the UID in phy_uid */ | |
425 | int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask) | |
426 | { | |
427 | return phy_unregister_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask); | |
428 | } | |
429 | EXPORT_SYMBOL(phy_unregister_fixup_for_uid); | |
430 | ||
431 | /* Unregisters a fixup of the PHY with id string bus_id */ | |
432 | int phy_unregister_fixup_for_id(const char *bus_id) | |
433 | { | |
434 | return phy_unregister_fixup(bus_id, PHY_ANY_UID, 0xffffffff); | |
435 | } | |
436 | EXPORT_SYMBOL(phy_unregister_fixup_for_id); | |
437 | ||
2f53e904 | 438 | /* Returns 1 if fixup matches phydev in bus_id and phy_uid. |
f62220d3 AF |
439 | * Fixups can be set to match any in one or more fields. |
440 | */ | |
441 | static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) | |
442 | { | |
84eff6d1 | 443 | if (strcmp(fixup->bus_id, phydev_name(phydev)) != 0) |
f62220d3 AF |
444 | if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0) |
445 | return 0; | |
446 | ||
447 | if ((fixup->phy_uid & fixup->phy_uid_mask) != | |
2f53e904 | 448 | (phydev->phy_id & fixup->phy_uid_mask)) |
f62220d3 AF |
449 | if (fixup->phy_uid != PHY_ANY_UID) |
450 | return 0; | |
451 | ||
452 | return 1; | |
453 | } | |
454 | ||
455 | /* Runs any matching fixups for this phydev */ | |
fbfcec63 | 456 | static int phy_scan_fixups(struct phy_device *phydev) |
f62220d3 AF |
457 | { |
458 | struct phy_fixup *fixup; | |
459 | ||
460 | mutex_lock(&phy_fixup_lock); | |
461 | list_for_each_entry(fixup, &phy_fixup_list, list) { | |
462 | if (phy_needs_fixup(phydev, fixup)) { | |
553fe92b | 463 | int err = fixup->run(phydev); |
f62220d3 | 464 | |
bc23283c JS |
465 | if (err < 0) { |
466 | mutex_unlock(&phy_fixup_lock); | |
f62220d3 | 467 | return err; |
bc23283c | 468 | } |
b0ae009f | 469 | phydev->has_fixups = true; |
f62220d3 AF |
470 | } |
471 | } | |
472 | mutex_unlock(&phy_fixup_lock); | |
473 | ||
474 | return 0; | |
475 | } | |
f62220d3 | 476 | |
e76a4957 AL |
477 | static int phy_bus_match(struct device *dev, struct device_driver *drv) |
478 | { | |
479 | struct phy_device *phydev = to_phy_device(dev); | |
480 | struct phy_driver *phydrv = to_phy_driver(drv); | |
481 | const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids); | |
482 | int i; | |
483 | ||
a9049e0c AL |
484 | if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)) |
485 | return 0; | |
486 | ||
e76a4957 AL |
487 | if (phydrv->match_phy_device) |
488 | return phydrv->match_phy_device(phydev); | |
489 | ||
490 | if (phydev->is_c45) { | |
491 | for (i = 1; i < num_ids; i++) { | |
492 | if (!(phydev->c45_ids.devices_in_package & (1 << i))) | |
493 | continue; | |
494 | ||
495 | if ((phydrv->phy_id & phydrv->phy_id_mask) == | |
496 | (phydev->c45_ids.device_ids[i] & | |
497 | phydrv->phy_id_mask)) | |
498 | return 1; | |
499 | } | |
500 | return 0; | |
501 | } else { | |
502 | return (phydrv->phy_id & phydrv->phy_id_mask) == | |
503 | (phydev->phy_id & phydrv->phy_id_mask); | |
504 | } | |
505 | } | |
506 | ||
7f4828ff HK |
507 | static ssize_t |
508 | phy_id_show(struct device *dev, struct device_attribute *attr, char *buf) | |
509 | { | |
510 | struct phy_device *phydev = to_phy_device(dev); | |
511 | ||
512 | return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id); | |
513 | } | |
514 | static DEVICE_ATTR_RO(phy_id); | |
515 | ||
516 | static ssize_t | |
517 | phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf) | |
518 | { | |
519 | struct phy_device *phydev = to_phy_device(dev); | |
520 | const char *mode = NULL; | |
521 | ||
522 | if (phy_is_internal(phydev)) | |
523 | mode = "internal"; | |
524 | else | |
525 | mode = phy_modes(phydev->interface); | |
526 | ||
527 | return sprintf(buf, "%s\n", mode); | |
528 | } | |
529 | static DEVICE_ATTR_RO(phy_interface); | |
530 | ||
531 | static ssize_t | |
532 | phy_has_fixups_show(struct device *dev, struct device_attribute *attr, | |
533 | char *buf) | |
534 | { | |
535 | struct phy_device *phydev = to_phy_device(dev); | |
536 | ||
537 | return sprintf(buf, "%d\n", phydev->has_fixups); | |
538 | } | |
539 | static DEVICE_ATTR_RO(phy_has_fixups); | |
540 | ||
541 | static struct attribute *phy_dev_attrs[] = { | |
542 | &dev_attr_phy_id.attr, | |
543 | &dev_attr_phy_interface.attr, | |
544 | &dev_attr_phy_has_fixups.attr, | |
545 | NULL, | |
546 | }; | |
547 | ATTRIBUTE_GROUPS(phy_dev); | |
548 | ||
549 | static const struct device_type mdio_bus_phy_type = { | |
550 | .name = "PHY", | |
551 | .groups = phy_dev_groups, | |
552 | .release = phy_device_release, | |
553 | .pm = MDIO_BUS_PHY_PM_OPS, | |
554 | }; | |
555 | ||
13d0ab67 HK |
556 | static int phy_request_driver_module(struct phy_device *dev, int phy_id) |
557 | { | |
558 | int ret; | |
559 | ||
560 | ret = request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, | |
561 | MDIO_ID_ARGS(phy_id)); | |
21e19442 HK |
562 | /* We only check for failures in executing the usermode binary, |
563 | * not whether a PHY driver module exists for the PHY ID. | |
564 | * Accept -ENOENT because this may occur in case no initramfs exists, | |
565 | * then modprobe isn't available. | |
13d0ab67 | 566 | */ |
21e19442 | 567 | if (IS_ENABLED(CONFIG_MODULES) && ret < 0 && ret != -ENOENT) { |
13d0ab67 HK |
568 | phydev_err(dev, "error %d loading PHY driver module for ID 0x%08x\n", |
569 | ret, phy_id); | |
570 | return ret; | |
571 | } | |
572 | ||
573 | return 0; | |
574 | } | |
575 | ||
ac28b9f8 | 576 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, |
2f53e904 SS |
577 | bool is_c45, |
578 | struct phy_c45_device_ids *c45_ids) | |
11b0bacd VB |
579 | { |
580 | struct phy_device *dev; | |
e5a03bfd | 581 | struct mdio_device *mdiodev; |
13d0ab67 | 582 | int ret = 0; |
8626d3b4 | 583 | |
2f53e904 | 584 | /* We allocate the device, and initialize the default values */ |
cd861280 | 585 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
ef899c07 | 586 | if (!dev) |
d3765f08 | 587 | return ERR_PTR(-ENOMEM); |
11b0bacd | 588 | |
e5a03bfd | 589 | mdiodev = &dev->mdio; |
e5a03bfd AL |
590 | mdiodev->dev.parent = &bus->dev; |
591 | mdiodev->dev.bus = &mdio_bus_type; | |
7f4828ff | 592 | mdiodev->dev.type = &mdio_bus_phy_type; |
e5a03bfd | 593 | mdiodev->bus = bus; |
e76a4957 | 594 | mdiodev->bus_match = phy_bus_match; |
e5a03bfd | 595 | mdiodev->addr = addr; |
7f854420 | 596 | mdiodev->flags = MDIO_DEVICE_FLAG_PHY; |
711fdba3 AL |
597 | mdiodev->device_free = phy_mdio_device_free; |
598 | mdiodev->device_remove = phy_mdio_device_remove; | |
6f4a7f41 | 599 | |
11b0bacd VB |
600 | dev->speed = 0; |
601 | dev->duplex = -1; | |
2f53e904 SS |
602 | dev->pause = 0; |
603 | dev->asym_pause = 0; | |
c69851e9 | 604 | dev->link = 0; |
e8a2b6a4 | 605 | dev->interface = PHY_INTERFACE_MODE_GMII; |
11b0bacd VB |
606 | |
607 | dev->autoneg = AUTONEG_ENABLE; | |
608 | ||
ac28b9f8 | 609 | dev->is_c45 = is_c45; |
11b0bacd | 610 | dev->phy_id = phy_id; |
ac28b9f8 DD |
611 | if (c45_ids) |
612 | dev->c45_ids = *c45_ids; | |
47b356e4 | 613 | dev->irq = bus->irq[addr]; |
e5a03bfd | 614 | dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr); |
11b0bacd VB |
615 | |
616 | dev->state = PHY_DOWN; | |
617 | ||
35b5f6b1 | 618 | mutex_init(&dev->lock); |
4f9c85a1 | 619 | INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); |
11b0bacd | 620 | |
8626d3b4 | 621 | /* Request the appropriate module unconditionally; don't |
2f53e904 SS |
622 | * bother trying to do so only if it isn't already loaded, |
623 | * because that gets complicated. A hotplug event would have | |
624 | * done an unconditional modprobe anyway. | |
625 | * We don't do normal hotplug because it won't work for MDIO | |
626 | * -- because it relies on the device staying around for long | |
627 | * enough for the driver to get loaded. With MDIO, the NIC | |
628 | * driver will get bored and give up as soon as it finds that | |
629 | * there's no driver _already_ loaded. | |
630 | */ | |
30fcd6a9 JA |
631 | if (is_c45 && c45_ids) { |
632 | const int num_ids = ARRAY_SIZE(c45_ids->device_ids); | |
633 | int i; | |
634 | ||
635 | for (i = 1; i < num_ids; i++) { | |
636 | if (!(c45_ids->devices_in_package & (1 << i))) | |
637 | continue; | |
638 | ||
13d0ab67 HK |
639 | ret = phy_request_driver_module(dev, |
640 | c45_ids->device_ids[i]); | |
641 | if (ret) | |
642 | break; | |
30fcd6a9 JA |
643 | } |
644 | } else { | |
13d0ab67 | 645 | ret = phy_request_driver_module(dev, phy_id); |
30fcd6a9 | 646 | } |
8626d3b4 | 647 | |
13d0ab67 HK |
648 | if (!ret) { |
649 | device_initialize(&mdiodev->dev); | |
650 | } else { | |
651 | kfree(dev); | |
652 | dev = ERR_PTR(ret); | |
653 | } | |
b2a43191 | 654 | |
11b0bacd VB |
655 | return dev; |
656 | } | |
ac28b9f8 DD |
657 | EXPORT_SYMBOL(phy_device_create); |
658 | ||
5f6c99e0 SX |
659 | /* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers. |
660 | * @bus: the target MII bus | |
661 | * @addr: PHY address on the MII bus | |
662 | * @dev_addr: MMD address in the PHY. | |
663 | * @devices_in_package: where to store the devices in package information. | |
664 | * | |
665 | * Description: reads devices in package registers of a MMD at @dev_addr | |
666 | * from PHY at @addr on @bus. | |
667 | * | |
668 | * Returns: 0 on success, -EIO on failure. | |
669 | */ | |
670 | static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr, | |
671 | u32 *devices_in_package) | |
672 | { | |
673 | int phy_reg, reg_addr; | |
674 | ||
675 | reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS2; | |
676 | phy_reg = mdiobus_read(bus, addr, reg_addr); | |
677 | if (phy_reg < 0) | |
678 | return -EIO; | |
679 | *devices_in_package = (phy_reg & 0xffff) << 16; | |
680 | ||
681 | reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS1; | |
682 | phy_reg = mdiobus_read(bus, addr, reg_addr); | |
683 | if (phy_reg < 0) | |
684 | return -EIO; | |
685 | *devices_in_package |= (phy_reg & 0xffff); | |
686 | ||
687 | return 0; | |
688 | } | |
689 | ||
ac28b9f8 DD |
690 | /** |
691 | * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs. | |
692 | * @bus: the target MII bus | |
693 | * @addr: PHY address on the MII bus | |
694 | * @phy_id: where to store the ID retrieved. | |
695 | * @c45_ids: where to store the c45 ID information. | |
696 | * | |
697 | * If the PHY devices-in-package appears to be valid, it and the | |
698 | * corresponding identifiers are stored in @c45_ids, zero is stored | |
699 | * in @phy_id. Otherwise 0xffffffff is stored in @phy_id. Returns | |
700 | * zero on success. | |
701 | * | |
702 | */ | |
703 | static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id, | |
704 | struct phy_c45_device_ids *c45_ids) { | |
705 | int phy_reg; | |
706 | int i, reg_addr; | |
707 | const int num_ids = ARRAY_SIZE(c45_ids->device_ids); | |
5f6c99e0 | 708 | u32 *devs = &c45_ids->devices_in_package; |
ac28b9f8 | 709 | |
5f6c99e0 SX |
710 | /* Find first non-zero Devices In package. Device zero is reserved |
711 | * for 802.3 c45 complied PHYs, so don't probe it at first. | |
ac28b9f8 | 712 | */ |
5f6c99e0 SX |
713 | for (i = 1; i < num_ids && *devs == 0; i++) { |
714 | phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, devs); | |
ac28b9f8 DD |
715 | if (phy_reg < 0) |
716 | return -EIO; | |
ac28b9f8 | 717 | |
5f6c99e0 SX |
718 | if ((*devs & 0x1fffffff) == 0x1fffffff) { |
719 | /* If mostly Fs, there is no device there, | |
720 | * then let's continue to probe more, as some | |
721 | * 10G PHYs have zero Devices In package, | |
722 | * e.g. Cortina CS4315/CS4340 PHY. | |
723 | */ | |
724 | phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs); | |
725 | if (phy_reg < 0) | |
726 | return -EIO; | |
727 | /* no device there, let's get out of here */ | |
728 | if ((*devs & 0x1fffffff) == 0x1fffffff) { | |
da1da284 SL |
729 | *phy_id = 0xffffffff; |
730 | return 0; | |
5f6c99e0 SX |
731 | } else { |
732 | break; | |
da1da284 | 733 | } |
ac28b9f8 DD |
734 | } |
735 | } | |
736 | ||
737 | /* Now probe Device Identifiers for each device present. */ | |
738 | for (i = 1; i < num_ids; i++) { | |
739 | if (!(c45_ids->devices_in_package & (1 << i))) | |
740 | continue; | |
741 | ||
742 | reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID1; | |
743 | phy_reg = mdiobus_read(bus, addr, reg_addr); | |
744 | if (phy_reg < 0) | |
745 | return -EIO; | |
746 | c45_ids->device_ids[i] = (phy_reg & 0xffff) << 16; | |
747 | ||
748 | reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID2; | |
749 | phy_reg = mdiobus_read(bus, addr, reg_addr); | |
750 | if (phy_reg < 0) | |
751 | return -EIO; | |
752 | c45_ids->device_ids[i] |= (phy_reg & 0xffff); | |
753 | } | |
754 | *phy_id = 0; | |
755 | return 0; | |
756 | } | |
11b0bacd | 757 | |
b3df0da8 | 758 | /** |
cac1f3c8 | 759 | * get_phy_id - reads the specified addr for its ID. |
b3df0da8 RD |
760 | * @bus: the target MII bus |
761 | * @addr: PHY address on the MII bus | |
cac1f3c8 | 762 | * @phy_id: where to store the ID retrieved. |
ac28b9f8 DD |
763 | * @is_c45: If true the PHY uses the 802.3 clause 45 protocol |
764 | * @c45_ids: where to store the c45 ID information. | |
765 | * | |
766 | * Description: In the case of a 802.3-c22 PHY, reads the ID registers | |
767 | * of the PHY at @addr on the @bus, stores it in @phy_id and returns | |
768 | * zero on success. | |
769 | * | |
770 | * In the case of a 802.3-c45 PHY, get_phy_c45_ids() is invoked, and | |
771 | * its return value is in turn returned. | |
00db8189 | 772 | * |
00db8189 | 773 | */ |
ac28b9f8 DD |
774 | static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, |
775 | bool is_c45, struct phy_c45_device_ids *c45_ids) | |
00db8189 AF |
776 | { |
777 | int phy_reg; | |
00db8189 | 778 | |
ac28b9f8 DD |
779 | if (is_c45) |
780 | return get_phy_c45_ids(bus, addr, phy_id, c45_ids); | |
781 | ||
2f53e904 | 782 | /* Grab the bits from PHYIR1, and put them in the upper half */ |
6fe32649 | 783 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); |
02a6efca | 784 | if (phy_reg < 0) { |
d8cce3a1 HK |
785 | /* returning -ENODEV doesn't stop bus scanning */ |
786 | return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; | |
02a6efca | 787 | } |
00db8189 | 788 | |
cac1f3c8 | 789 | *phy_id = (phy_reg & 0xffff) << 16; |
00db8189 AF |
790 | |
791 | /* Grab the bits from PHYIR2, and put them in the lower half */ | |
6fe32649 | 792 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); |
00db8189 | 793 | if (phy_reg < 0) |
cac1f3c8 PG |
794 | return -EIO; |
795 | ||
796 | *phy_id |= (phy_reg & 0xffff); | |
797 | ||
798 | return 0; | |
799 | } | |
800 | ||
801 | /** | |
2f53e904 SS |
802 | * get_phy_device - reads the specified PHY device and returns its @phy_device |
803 | * struct | |
cac1f3c8 PG |
804 | * @bus: the target MII bus |
805 | * @addr: PHY address on the MII bus | |
ac28b9f8 | 806 | * @is_c45: If true the PHY uses the 802.3 clause 45 protocol |
cac1f3c8 PG |
807 | * |
808 | * Description: Reads the ID registers of the PHY at @addr on the | |
809 | * @bus, then allocates and returns the phy_device to represent it. | |
810 | */ | |
ac28b9f8 | 811 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) |
cac1f3c8 | 812 | { |
ac28b9f8 | 813 | struct phy_c45_device_ids c45_ids = {0}; |
160c85f0 | 814 | u32 phy_id = 0; |
cac1f3c8 | 815 | int r; |
00db8189 | 816 | |
ac28b9f8 | 817 | r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); |
cac1f3c8 PG |
818 | if (r) |
819 | return ERR_PTR(r); | |
00db8189 | 820 | |
6436cbcd GC |
821 | /* If the phy_id is mostly Fs, there is no device there */ |
822 | if ((phy_id & 0x1fffffff) == 0x1fffffff) | |
b74766a0 | 823 | return ERR_PTR(-ENODEV); |
6436cbcd | 824 | |
e62a768f | 825 | return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); |
00db8189 | 826 | } |
4dea547f GL |
827 | EXPORT_SYMBOL(get_phy_device); |
828 | ||
829 | /** | |
830 | * phy_device_register - Register the phy device on the MDIO bus | |
1d4ac5d5 | 831 | * @phydev: phy_device structure to be added to the MDIO bus |
4dea547f GL |
832 | */ |
833 | int phy_device_register(struct phy_device *phydev) | |
834 | { | |
835 | int err; | |
836 | ||
7f854420 AL |
837 | err = mdiobus_register_device(&phydev->mdio); |
838 | if (err) | |
839 | return err; | |
4dea547f | 840 | |
bafbdd52 SS |
841 | /* Deassert the reset signal */ |
842 | phy_device_reset(phydev, 0); | |
843 | ||
4dea547f | 844 | /* Run all of the fixups for this PHY */ |
d92f5dec | 845 | err = phy_scan_fixups(phydev); |
87aa9f9c | 846 | if (err) { |
c3a6a174 | 847 | phydev_err(phydev, "failed to initialize\n"); |
87aa9f9c FF |
848 | goto out; |
849 | } | |
4dea547f | 850 | |
e5a03bfd | 851 | err = device_add(&phydev->mdio.dev); |
4dea547f | 852 | if (err) { |
c3a6a174 | 853 | phydev_err(phydev, "failed to add\n"); |
4dea547f GL |
854 | goto out; |
855 | } | |
856 | ||
857 | return 0; | |
858 | ||
859 | out: | |
bafbdd52 SS |
860 | /* Assert the reset signal */ |
861 | phy_device_reset(phydev, 1); | |
862 | ||
7f854420 | 863 | mdiobus_unregister_device(&phydev->mdio); |
4dea547f GL |
864 | return err; |
865 | } | |
866 | EXPORT_SYMBOL(phy_device_register); | |
00db8189 | 867 | |
38737e49 RK |
868 | /** |
869 | * phy_device_remove - Remove a previously registered phy device from the MDIO bus | |
870 | * @phydev: phy_device structure to remove | |
871 | * | |
872 | * This doesn't free the phy_device itself, it merely reverses the effects | |
873 | * of phy_device_register(). Use phy_device_free() to free the device | |
874 | * after calling this function. | |
875 | */ | |
876 | void phy_device_remove(struct phy_device *phydev) | |
877 | { | |
e5a03bfd | 878 | device_del(&phydev->mdio.dev); |
bafbdd52 SS |
879 | |
880 | /* Assert the reset signal */ | |
881 | phy_device_reset(phydev, 1); | |
882 | ||
7f854420 | 883 | mdiobus_unregister_device(&phydev->mdio); |
38737e49 RK |
884 | } |
885 | EXPORT_SYMBOL(phy_device_remove); | |
886 | ||
f8f76db1 JP |
887 | /** |
888 | * phy_find_first - finds the first PHY device on the bus | |
889 | * @bus: the target MII bus | |
890 | */ | |
891 | struct phy_device *phy_find_first(struct mii_bus *bus) | |
892 | { | |
7f854420 | 893 | struct phy_device *phydev; |
f8f76db1 JP |
894 | int addr; |
895 | ||
896 | for (addr = 0; addr < PHY_MAX_ADDR; addr++) { | |
7f854420 AL |
897 | phydev = mdiobus_get_phy(bus, addr); |
898 | if (phydev) | |
899 | return phydev; | |
f8f76db1 JP |
900 | } |
901 | return NULL; | |
902 | } | |
903 | EXPORT_SYMBOL(phy_find_first); | |
904 | ||
a81497be RK |
905 | static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier) |
906 | { | |
907 | struct net_device *netdev = phydev->attached_dev; | |
908 | ||
909 | if (do_carrier) { | |
910 | if (up) | |
911 | netif_carrier_on(netdev); | |
912 | else | |
913 | netif_carrier_off(netdev); | |
914 | } | |
915 | phydev->adjust_link(netdev); | |
916 | } | |
917 | ||
b3df0da8 RD |
918 | /** |
919 | * phy_prepare_link - prepares the PHY layer to monitor link status | |
920 | * @phydev: target phy_device struct | |
921 | * @handler: callback function for link status change notifications | |
00db8189 | 922 | * |
b3df0da8 | 923 | * Description: Tells the PHY infrastructure to handle the |
00db8189 AF |
924 | * gory details on monitoring link status (whether through |
925 | * polling or an interrupt), and to call back to the | |
926 | * connected device driver when the link status changes. | |
927 | * If you want to monitor your own link state, don't call | |
b3df0da8 RD |
928 | * this function. |
929 | */ | |
89ff05ec | 930 | static void phy_prepare_link(struct phy_device *phydev, |
2f53e904 | 931 | void (*handler)(struct net_device *)) |
00db8189 AF |
932 | { |
933 | phydev->adjust_link = handler; | |
934 | } | |
935 | ||
fa94f6d9 GL |
936 | /** |
937 | * phy_connect_direct - connect an ethernet device to a specific phy_device | |
938 | * @dev: the network device to connect | |
939 | * @phydev: the pointer to the phy device | |
940 | * @handler: callback function for state change notifications | |
fa94f6d9 GL |
941 | * @interface: PHY device's interface |
942 | */ | |
943 | int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, | |
f9a8f83b | 944 | void (*handler)(struct net_device *), |
fa94f6d9 GL |
945 | phy_interface_t interface) |
946 | { | |
947 | int rc; | |
948 | ||
f9a8f83b | 949 | rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface); |
fa94f6d9 GL |
950 | if (rc) |
951 | return rc; | |
952 | ||
953 | phy_prepare_link(phydev, handler); | |
fa94f6d9 GL |
954 | if (phydev->irq > 0) |
955 | phy_start_interrupts(phydev); | |
956 | ||
957 | return 0; | |
958 | } | |
959 | EXPORT_SYMBOL(phy_connect_direct); | |
960 | ||
b3df0da8 RD |
961 | /** |
962 | * phy_connect - connect an ethernet device to a PHY device | |
963 | * @dev: the network device to connect | |
5d12b132 | 964 | * @bus_id: the id string of the PHY device to connect |
b3df0da8 | 965 | * @handler: callback function for state change notifications |
b3df0da8 | 966 | * @interface: PHY device's interface |
e1393456 | 967 | * |
b3df0da8 | 968 | * Description: Convenience function for connecting ethernet |
e1393456 AF |
969 | * devices to PHY devices. The default behavior is for |
970 | * the PHY infrastructure to handle everything, and only notify | |
971 | * the connected driver when the link status changes. If you | |
972 | * don't want, or can't use the provided functionality, you may | |
973 | * choose to call only the subset of functions which provide | |
974 | * the desired functionality. | |
975 | */ | |
e109374f | 976 | struct phy_device *phy_connect(struct net_device *dev, const char *bus_id, |
2f53e904 SS |
977 | void (*handler)(struct net_device *), |
978 | phy_interface_t interface) | |
e1393456 AF |
979 | { |
980 | struct phy_device *phydev; | |
fa94f6d9 GL |
981 | struct device *d; |
982 | int rc; | |
e1393456 | 983 | |
fa94f6d9 | 984 | /* Search the list of PHY devices on the mdio bus for the |
2f53e904 SS |
985 | * PHY with the requested name |
986 | */ | |
fa94f6d9 GL |
987 | d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); |
988 | if (!d) { | |
989 | pr_err("PHY %s not found\n", bus_id); | |
990 | return ERR_PTR(-ENODEV); | |
991 | } | |
992 | phydev = to_phy_device(d); | |
e1393456 | 993 | |
f9a8f83b | 994 | rc = phy_connect_direct(dev, phydev, handler, interface); |
17ae1c65 | 995 | put_device(d); |
fa94f6d9 GL |
996 | if (rc) |
997 | return ERR_PTR(rc); | |
e1393456 AF |
998 | |
999 | return phydev; | |
1000 | } | |
1001 | EXPORT_SYMBOL(phy_connect); | |
1002 | ||
b3df0da8 | 1003 | /** |
2f53e904 SS |
1004 | * phy_disconnect - disable interrupts, stop state machine, and detach a PHY |
1005 | * device | |
b3df0da8 RD |
1006 | * @phydev: target phy_device struct |
1007 | */ | |
e1393456 AF |
1008 | void phy_disconnect(struct phy_device *phydev) |
1009 | { | |
472115d9 HK |
1010 | if (phy_is_started(phydev)) |
1011 | phy_stop(phydev); | |
1012 | ||
bb658ab7 HK |
1013 | if (phy_interrupt_is_valid(phydev)) |
1014 | free_irq(phydev->irq, phydev); | |
e1393456 | 1015 | |
e1393456 AF |
1016 | phydev->adjust_link = NULL; |
1017 | ||
1018 | phy_detach(phydev); | |
1019 | } | |
1020 | EXPORT_SYMBOL(phy_disconnect); | |
1021 | ||
87aa9f9c FF |
1022 | /** |
1023 | * phy_poll_reset - Safely wait until a PHY reset has properly completed | |
1024 | * @phydev: The PHY device to poll | |
1025 | * | |
1026 | * Description: According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, as | |
1027 | * published in 2008, a PHY reset may take up to 0.5 seconds. The MII BMCR | |
1028 | * register must be polled until the BMCR_RESET bit clears. | |
1029 | * | |
1030 | * Furthermore, any attempts to write to PHY registers may have no effect | |
1031 | * or even generate MDIO bus errors until this is complete. | |
1032 | * | |
1033 | * Some PHYs (such as the Marvell 88E1111) don't entirely conform to the | |
1034 | * standard and do not fully reset after the BMCR_RESET bit is set, and may | |
1035 | * even *REQUIRE* a soft-reset to properly restart autonegotiation. In an | |
1036 | * effort to support such broken PHYs, this function is separate from the | |
1037 | * standard phy_init_hw() which will zero all the other bits in the BMCR | |
1038 | * and reapply all driver-specific and board-specific fixups. | |
1039 | */ | |
1040 | static int phy_poll_reset(struct phy_device *phydev) | |
1041 | { | |
1042 | /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ | |
1043 | unsigned int retries = 12; | |
1044 | int ret; | |
1045 | ||
1046 | do { | |
1047 | msleep(50); | |
1048 | ret = phy_read(phydev, MII_BMCR); | |
1049 | if (ret < 0) | |
1050 | return ret; | |
1051 | } while (ret & BMCR_RESET && --retries); | |
1052 | if (ret & BMCR_RESET) | |
1053 | return -ETIMEDOUT; | |
1054 | ||
2f53e904 | 1055 | /* Some chips (smsc911x) may still need up to another 1ms after the |
87aa9f9c FF |
1056 | * BMCR_RESET bit is cleared before they are usable. |
1057 | */ | |
1058 | msleep(1); | |
1059 | return 0; | |
1060 | } | |
1061 | ||
2f5cb434 AV |
1062 | int phy_init_hw(struct phy_device *phydev) |
1063 | { | |
9df81dd7 | 1064 | int ret = 0; |
2f5cb434 | 1065 | |
bafbdd52 SS |
1066 | /* Deassert the reset signal */ |
1067 | phy_device_reset(phydev, 0); | |
1068 | ||
a5996989 | 1069 | if (!phydev->drv) |
2f5cb434 AV |
1070 | return 0; |
1071 | ||
9df81dd7 FF |
1072 | if (phydev->drv->soft_reset) |
1073 | ret = phydev->drv->soft_reset(phydev); | |
9df81dd7 | 1074 | |
87aa9f9c FF |
1075 | if (ret < 0) |
1076 | return ret; | |
1077 | ||
2f5cb434 AV |
1078 | ret = phy_scan_fixups(phydev); |
1079 | if (ret < 0) | |
1080 | return ret; | |
1081 | ||
a5996989 HK |
1082 | if (phydev->drv->config_init) |
1083 | ret = phydev->drv->config_init(phydev); | |
1084 | ||
1085 | return ret; | |
2f5cb434 | 1086 | } |
87aa9f9c | 1087 | EXPORT_SYMBOL(phy_init_hw); |
2f5cb434 | 1088 | |
2220943a AL |
1089 | void phy_attached_info(struct phy_device *phydev) |
1090 | { | |
1091 | phy_attached_print(phydev, NULL); | |
1092 | } | |
1093 | EXPORT_SYMBOL(phy_attached_info); | |
1094 | ||
5e369aef | 1095 | #define ATTACHED_FMT "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%s)" |
2220943a AL |
1096 | void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) |
1097 | { | |
fcd03e36 | 1098 | const char *drv_name = phydev->drv ? phydev->drv->name : "unbound"; |
5e369aef | 1099 | char *irq_str; |
059fbe8b | 1100 | char irq_num[8]; |
5e369aef RP |
1101 | |
1102 | switch(phydev->irq) { | |
1103 | case PHY_POLL: | |
1104 | irq_str = "POLL"; | |
1105 | break; | |
1106 | case PHY_IGNORE_INTERRUPT: | |
1107 | irq_str = "IGNORE"; | |
1108 | break; | |
1109 | default: | |
1110 | snprintf(irq_num, sizeof(irq_num), "%d", phydev->irq); | |
1111 | irq_str = irq_num; | |
1112 | break; | |
1113 | } | |
1114 | ||
fcd03e36 | 1115 | |
2220943a | 1116 | if (!fmt) { |
c4fabb8b | 1117 | phydev_info(phydev, ATTACHED_FMT "\n", |
fcd03e36 | 1118 | drv_name, phydev_name(phydev), |
5e369aef | 1119 | irq_str); |
2220943a AL |
1120 | } else { |
1121 | va_list ap; | |
1122 | ||
c4fabb8b | 1123 | phydev_info(phydev, ATTACHED_FMT, |
fcd03e36 | 1124 | drv_name, phydev_name(phydev), |
5e369aef | 1125 | irq_str); |
2220943a AL |
1126 | |
1127 | va_start(ap, fmt); | |
1128 | vprintk(fmt, ap); | |
1129 | va_end(ap); | |
1130 | } | |
1131 | } | |
1132 | EXPORT_SYMBOL(phy_attached_print); | |
1133 | ||
b3df0da8 | 1134 | /** |
fa94f6d9 | 1135 | * phy_attach_direct - attach a network device to a given PHY device pointer |
b3df0da8 | 1136 | * @dev: network device to attach |
fa94f6d9 | 1137 | * @phydev: Pointer to phy_device to attach |
b3df0da8 RD |
1138 | * @flags: PHY device's dev_flags |
1139 | * @interface: PHY device's interface | |
e1393456 | 1140 | * |
b3df0da8 | 1141 | * Description: Called by drivers to attach to a particular PHY |
e1393456 | 1142 | * device. The phy_device is found, and properly hooked up |
257184d7 AF |
1143 | * to the phy_driver. If no driver is attached, then a |
1144 | * generic driver is used. The phy_device is given a ptr to | |
e1393456 | 1145 | * the attaching device, and given a callback for link status |
b3df0da8 | 1146 | * change. The phy_device is returned to the attaching driver. |
7322967b | 1147 | * This function takes a reference on the phy device. |
e1393456 | 1148 | */ |
257184d7 AF |
1149 | int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, |
1150 | u32 flags, phy_interface_t interface) | |
e1393456 | 1151 | { |
ec988ad7 | 1152 | struct module *ndev_owner = dev->dev.parent->driver->owner; |
e5a03bfd AL |
1153 | struct mii_bus *bus = phydev->mdio.bus; |
1154 | struct device *d = &phydev->mdio.dev; | |
6d9f66ac | 1155 | bool using_genphy = false; |
d005a09e | 1156 | int err; |
e1393456 | 1157 | |
ec988ad7 FF |
1158 | /* For Ethernet device drivers that register their own MDIO bus, we |
1159 | * will have bus->owner match ndev_mod, so we do not want to increment | |
1160 | * our own module->refcnt here, otherwise we would not be able to | |
1161 | * unload later on. | |
1162 | */ | |
1163 | if (ndev_owner != bus->owner && !try_module_get(bus->owner)) { | |
3e3aaf64 RK |
1164 | dev_err(&dev->dev, "failed to get the bus module\n"); |
1165 | return -EIO; | |
1166 | } | |
1167 | ||
7322967b RK |
1168 | get_device(d); |
1169 | ||
e1393456 | 1170 | /* Assume that if there is no driver, that it doesn't |
2f53e904 SS |
1171 | * exist, and we should use the genphy driver. |
1172 | */ | |
ef899c07 | 1173 | if (!d->driver) { |
257184d7 | 1174 | if (phydev->is_c45) |
921690f2 | 1175 | d->driver = &genphy_10g_driver.mdiodrv.driver; |
257184d7 | 1176 | else |
921690f2 | 1177 | d->driver = &genphy_driver.mdiodrv.driver; |
e1393456 | 1178 | |
6d9f66ac FF |
1179 | using_genphy = true; |
1180 | } | |
1181 | ||
1182 | if (!try_module_get(d->driver->owner)) { | |
1183 | dev_err(&dev->dev, "failed to get the device driver module\n"); | |
1184 | err = -EIO; | |
1185 | goto error_put_device; | |
1186 | } | |
1187 | ||
1188 | if (using_genphy) { | |
e1393456 | 1189 | err = d->driver->probe(d); |
b7a00ecd JG |
1190 | if (err >= 0) |
1191 | err = device_bind_driver(d); | |
e1393456 | 1192 | |
b7a00ecd | 1193 | if (err) |
6d9f66ac | 1194 | goto error_module_put; |
e1393456 AF |
1195 | } |
1196 | ||
1197 | if (phydev->attached_dev) { | |
fa94f6d9 | 1198 | dev_err(&dev->dev, "PHY already attached\n"); |
3e3aaf64 RK |
1199 | err = -EBUSY; |
1200 | goto error; | |
b3565f27 EG |
1201 | } |
1202 | ||
a81497be | 1203 | phydev->phy_link_change = phy_link_change; |
e1393456 | 1204 | phydev->attached_dev = dev; |
c1f19b51 | 1205 | dev->phydev = phydev; |
a3995460 FF |
1206 | |
1207 | /* Some Ethernet drivers try to connect to a PHY device before | |
1208 | * calling register_netdevice() -> netdev_register_kobject() and | |
1209 | * does the dev->dev.kobj initialization. Here we only check for | |
1210 | * success which indicates that the network device kobject is | |
1211 | * ready. Once we do that we still need to keep track of whether | |
1212 | * links were successfully set up or not for phy_detach() to | |
1213 | * remove them accordingly. | |
1214 | */ | |
1215 | phydev->sysfs_links = false; | |
1216 | ||
5568363f FF |
1217 | err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj, |
1218 | "attached_dev"); | |
a3995460 | 1219 | if (!err) { |
4414b3ed GS |
1220 | err = sysfs_create_link_nowarn(&dev->dev.kobj, |
1221 | &phydev->mdio.dev.kobj, | |
1222 | "phydev"); | |
1223 | if (err) { | |
1224 | dev_err(&dev->dev, "could not add device link to %s err %d\n", | |
1225 | kobject_name(&phydev->mdio.dev.kobj), | |
1226 | err); | |
1227 | /* non-fatal - some net drivers can use one netdevice | |
1228 | * with more then one phy | |
1229 | */ | |
1230 | } | |
5568363f | 1231 | |
a3995460 FF |
1232 | phydev->sysfs_links = true; |
1233 | } | |
e1393456 AF |
1234 | |
1235 | phydev->dev_flags = flags; | |
1236 | ||
e8a2b6a4 AF |
1237 | phydev->interface = interface; |
1238 | ||
ef24b16b AV |
1239 | phydev->state = PHY_READY; |
1240 | ||
113c74d8 SS |
1241 | /* Initial carrier state is off as the phy is about to be |
1242 | * (re)initialized. | |
1243 | */ | |
1244 | netif_carrier_off(phydev->attached_dev); | |
1245 | ||
e8a2b6a4 AF |
1246 | /* Do initial configuration here, now that |
1247 | * we have certain key parameters | |
2f53e904 SS |
1248 | * (dev_flags and interface) |
1249 | */ | |
d005a09e MKB |
1250 | err = phy_init_hw(phydev); |
1251 | if (err) | |
a7dac9f9 | 1252 | goto error; |
1211ce53 | 1253 | |
a7dac9f9 | 1254 | phy_resume(phydev); |
2e0bc452 ZB |
1255 | phy_led_triggers_register(phydev); |
1256 | ||
d005a09e | 1257 | return err; |
3e3aaf64 RK |
1258 | |
1259 | error: | |
6d9f66ac | 1260 | /* phy_detach() does all of the cleanup below */ |
a7dac9f9 | 1261 | phy_detach(phydev); |
6d9f66ac FF |
1262 | return err; |
1263 | ||
1264 | error_module_put: | |
cafe8df8 | 1265 | module_put(d->driver->owner); |
6d9f66ac FF |
1266 | error_put_device: |
1267 | put_device(d); | |
ec988ad7 FF |
1268 | if (ndev_owner != bus->owner) |
1269 | module_put(bus->owner); | |
3e3aaf64 | 1270 | return err; |
fa94f6d9 | 1271 | } |
257184d7 | 1272 | EXPORT_SYMBOL(phy_attach_direct); |
fa94f6d9 GL |
1273 | |
1274 | /** | |
1275 | * phy_attach - attach a network device to a particular PHY device | |
1276 | * @dev: network device to attach | |
1277 | * @bus_id: Bus ID of PHY device to attach | |
fa94f6d9 GL |
1278 | * @interface: PHY device's interface |
1279 | * | |
1280 | * Description: Same as phy_attach_direct() except that a PHY bus_id | |
1281 | * string is passed instead of a pointer to a struct phy_device. | |
1282 | */ | |
2f53e904 SS |
1283 | struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, |
1284 | phy_interface_t interface) | |
fa94f6d9 GL |
1285 | { |
1286 | struct bus_type *bus = &mdio_bus_type; | |
1287 | struct phy_device *phydev; | |
1288 | struct device *d; | |
1289 | int rc; | |
1290 | ||
1291 | /* Search the list of PHY devices on the mdio bus for the | |
2f53e904 SS |
1292 | * PHY with the requested name |
1293 | */ | |
fa94f6d9 GL |
1294 | d = bus_find_device_by_name(bus, NULL, bus_id); |
1295 | if (!d) { | |
1296 | pr_err("PHY %s not found\n", bus_id); | |
1297 | return ERR_PTR(-ENODEV); | |
e8a2b6a4 | 1298 | } |
fa94f6d9 GL |
1299 | phydev = to_phy_device(d); |
1300 | ||
f9a8f83b | 1301 | rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface); |
17ae1c65 | 1302 | put_device(d); |
fa94f6d9 GL |
1303 | if (rc) |
1304 | return ERR_PTR(rc); | |
e8a2b6a4 | 1305 | |
e1393456 AF |
1306 | return phydev; |
1307 | } | |
1308 | EXPORT_SYMBOL(phy_attach); | |
1309 | ||
5db5ea99 FF |
1310 | static bool phy_driver_is_genphy_kind(struct phy_device *phydev, |
1311 | struct device_driver *driver) | |
1312 | { | |
1313 | struct device *d = &phydev->mdio.dev; | |
1314 | bool ret = false; | |
1315 | ||
1316 | if (!phydev->drv) | |
1317 | return ret; | |
1318 | ||
1319 | get_device(d); | |
1320 | ret = d->driver == driver; | |
1321 | put_device(d); | |
1322 | ||
1323 | return ret; | |
1324 | } | |
1325 | ||
1326 | bool phy_driver_is_genphy(struct phy_device *phydev) | |
1327 | { | |
1328 | return phy_driver_is_genphy_kind(phydev, | |
1329 | &genphy_driver.mdiodrv.driver); | |
1330 | } | |
1331 | EXPORT_SYMBOL_GPL(phy_driver_is_genphy); | |
1332 | ||
1333 | bool phy_driver_is_genphy_10g(struct phy_device *phydev) | |
1334 | { | |
1335 | return phy_driver_is_genphy_kind(phydev, | |
1336 | &genphy_10g_driver.mdiodrv.driver); | |
1337 | } | |
1338 | EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g); | |
1339 | ||
b3df0da8 RD |
1340 | /** |
1341 | * phy_detach - detach a PHY device from its network device | |
1342 | * @phydev: target phy_device struct | |
7322967b RK |
1343 | * |
1344 | * This detaches the phy device from its network device and the phy | |
1345 | * driver, and drops the reference count taken in phy_attach_direct(). | |
b3df0da8 | 1346 | */ |
e1393456 AF |
1347 | void phy_detach(struct phy_device *phydev) |
1348 | { | |
ec988ad7 FF |
1349 | struct net_device *dev = phydev->attached_dev; |
1350 | struct module *ndev_owner = dev->dev.parent->driver->owner; | |
3e3aaf64 | 1351 | struct mii_bus *bus; |
b3565f27 | 1352 | |
a3995460 FF |
1353 | if (phydev->sysfs_links) { |
1354 | sysfs_remove_link(&dev->dev.kobj, "phydev"); | |
1355 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); | |
1356 | } | |
93f41e67 | 1357 | phy_suspend(phydev); |
c1f19b51 | 1358 | phydev->attached_dev->phydev = NULL; |
e1393456 | 1359 | phydev->attached_dev = NULL; |
9525ae83 | 1360 | phydev->phylink = NULL; |
e1393456 | 1361 | |
0075bd69 GU |
1362 | phy_led_triggers_unregister(phydev); |
1363 | ||
6d9f66ac FF |
1364 | module_put(phydev->mdio.dev.driver->owner); |
1365 | ||
e1393456 AF |
1366 | /* If the device had no specific driver before (i.e. - it |
1367 | * was using the generic driver), we unbind the device | |
1368 | * from the generic driver so that there's a chance a | |
2f53e904 SS |
1369 | * real driver could be loaded |
1370 | */ | |
5db5ea99 FF |
1371 | if (phy_driver_is_genphy(phydev) || |
1372 | phy_driver_is_genphy_10g(phydev)) | |
921690f2 | 1373 | device_release_driver(&phydev->mdio.dev); |
3e3aaf64 | 1374 | |
7322967b RK |
1375 | /* |
1376 | * The phydev might go away on the put_device() below, so avoid | |
1377 | * a use-after-free bug by reading the underlying bus first. | |
1378 | */ | |
e5a03bfd | 1379 | bus = phydev->mdio.bus; |
3e3aaf64 | 1380 | |
e5a03bfd | 1381 | put_device(&phydev->mdio.dev); |
ec988ad7 FF |
1382 | if (ndev_owner != bus->owner) |
1383 | module_put(bus->owner); | |
bafbdd52 SS |
1384 | |
1385 | /* Assert the reset signal */ | |
1386 | phy_device_reset(phydev, 1); | |
e1393456 AF |
1387 | } |
1388 | EXPORT_SYMBOL(phy_detach); | |
1389 | ||
481b5d93 SH |
1390 | int phy_suspend(struct phy_device *phydev) |
1391 | { | |
e5a03bfd | 1392 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
93f41e67 | 1393 | struct net_device *netdev = phydev->attached_dev; |
32fc3fd4 | 1394 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
8a477a6f | 1395 | int ret = 0; |
481b5d93 SH |
1396 | |
1397 | /* If the device has WOL enabled, we cannot suspend the PHY */ | |
481b5d93 | 1398 | phy_ethtool_get_wol(phydev, &wol); |
93f41e67 | 1399 | if (wol.wolopts || (netdev && netdev->wol_enabled)) |
481b5d93 SH |
1400 | return -EBUSY; |
1401 | ||
25149ef9 | 1402 | if (phydev->drv && phydrv->suspend) |
8a477a6f FF |
1403 | ret = phydrv->suspend(phydev); |
1404 | ||
1405 | if (ret) | |
1406 | return ret; | |
1407 | ||
1408 | phydev->suspended = true; | |
1409 | ||
1410 | return ret; | |
481b5d93 | 1411 | } |
ca127697 | 1412 | EXPORT_SYMBOL(phy_suspend); |
481b5d93 | 1413 | |
9c2c2e62 | 1414 | int __phy_resume(struct phy_device *phydev) |
481b5d93 | 1415 | { |
e5a03bfd | 1416 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
8a477a6f | 1417 | int ret = 0; |
481b5d93 | 1418 | |
f5e64032 RK |
1419 | WARN_ON(!mutex_is_locked(&phydev->lock)); |
1420 | ||
25149ef9 | 1421 | if (phydev->drv && phydrv->resume) |
8a477a6f FF |
1422 | ret = phydrv->resume(phydev); |
1423 | ||
1424 | if (ret) | |
1425 | return ret; | |
1426 | ||
1427 | phydev->suspended = false; | |
1428 | ||
1429 | return ret; | |
481b5d93 | 1430 | } |
9c2c2e62 AL |
1431 | EXPORT_SYMBOL(__phy_resume); |
1432 | ||
1433 | int phy_resume(struct phy_device *phydev) | |
1434 | { | |
1435 | int ret; | |
1436 | ||
1437 | mutex_lock(&phydev->lock); | |
1438 | ret = __phy_resume(phydev); | |
1439 | mutex_unlock(&phydev->lock); | |
1440 | ||
1441 | return ret; | |
1442 | } | |
ca127697 | 1443 | EXPORT_SYMBOL(phy_resume); |
e1393456 | 1444 | |
f0f9b4ed LYS |
1445 | int phy_loopback(struct phy_device *phydev, bool enable) |
1446 | { | |
1447 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); | |
1448 | int ret = 0; | |
1449 | ||
1450 | mutex_lock(&phydev->lock); | |
1451 | ||
1452 | if (enable && phydev->loopback_enabled) { | |
1453 | ret = -EBUSY; | |
1454 | goto out; | |
1455 | } | |
1456 | ||
1457 | if (!enable && !phydev->loopback_enabled) { | |
1458 | ret = -EINVAL; | |
1459 | goto out; | |
1460 | } | |
1461 | ||
1462 | if (phydev->drv && phydrv->set_loopback) | |
1463 | ret = phydrv->set_loopback(phydev, enable); | |
1464 | else | |
1465 | ret = -EOPNOTSUPP; | |
1466 | ||
1467 | if (ret) | |
1468 | goto out; | |
1469 | ||
1470 | phydev->loopback_enabled = enable; | |
1471 | ||
1472 | out: | |
1473 | mutex_unlock(&phydev->lock); | |
1474 | return ret; | |
1475 | } | |
1476 | EXPORT_SYMBOL(phy_loopback); | |
1477 | ||
a9668491 RL |
1478 | /** |
1479 | * phy_reset_after_clk_enable - perform a PHY reset if needed | |
1480 | * @phydev: target phy_device struct | |
1481 | * | |
1482 | * Description: Some PHYs are known to need a reset after their refclk was | |
1483 | * enabled. This function evaluates the flags and perform the reset if it's | |
1484 | * needed. Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy | |
1485 | * was reset. | |
1486 | */ | |
1487 | int phy_reset_after_clk_enable(struct phy_device *phydev) | |
1488 | { | |
1489 | if (!phydev || !phydev->drv) | |
1490 | return -ENODEV; | |
1491 | ||
1492 | if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN) { | |
1493 | phy_device_reset(phydev, 1); | |
1494 | phy_device_reset(phydev, 0); | |
1495 | return 1; | |
1496 | } | |
1497 | ||
1498 | return 0; | |
1499 | } | |
1500 | EXPORT_SYMBOL(phy_reset_after_clk_enable); | |
1501 | ||
00db8189 AF |
1502 | /* Generic PHY support and helper functions */ |
1503 | ||
b3df0da8 | 1504 | /** |
25985edc | 1505 | * genphy_config_advert - sanitize and advertise auto-negotiation parameters |
b3df0da8 | 1506 | * @phydev: target phy_device struct |
00db8189 | 1507 | * |
b3df0da8 | 1508 | * Description: Writes MII_ADVERTISE with the appropriate values, |
00db8189 | 1509 | * after sanitizing the values to make sure we only advertise |
51e2a384 TP |
1510 | * what is supported. Returns < 0 on error, 0 if the PHY's advertisement |
1511 | * hasn't changed, and > 0 if it has changed. | |
00db8189 | 1512 | */ |
89ff05ec | 1513 | static int genphy_config_advert(struct phy_device *phydev) |
00db8189 AF |
1514 | { |
1515 | u32 advertise; | |
5273e3a5 | 1516 | int oldadv, adv, bmsr; |
51e2a384 | 1517 | int err, changed = 0; |
00db8189 | 1518 | |
2f53e904 | 1519 | /* Only allow advertising what this PHY supports */ |
3c1bcc86 AL |
1520 | linkmode_and(phydev->advertising, phydev->advertising, |
1521 | phydev->supported); | |
1522 | if (!ethtool_convert_link_mode_to_legacy_u32(&advertise, | |
1523 | phydev->advertising)) | |
1524 | phydev_warn(phydev, "PHY advertising (%*pb) more modes than genphy supports, some modes not advertised.\n", | |
1525 | __ETHTOOL_LINK_MODE_MASK_NBITS, | |
1526 | phydev->advertising); | |
00db8189 AF |
1527 | |
1528 | /* Setup standard advertisement */ | |
2f53e904 | 1529 | adv = phy_read(phydev, MII_ADVERTISE); |
00db8189 AF |
1530 | if (adv < 0) |
1531 | return adv; | |
1532 | ||
2f53e904 | 1533 | oldadv = adv; |
28011cf1 | 1534 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | |
00db8189 | 1535 | ADVERTISE_PAUSE_ASYM); |
37f07023 | 1536 | adv |= ethtool_adv_to_mii_adv_t(advertise); |
00db8189 | 1537 | |
51e2a384 TP |
1538 | if (adv != oldadv) { |
1539 | err = phy_write(phydev, MII_ADVERTISE, adv); | |
00db8189 | 1540 | |
51e2a384 TP |
1541 | if (err < 0) |
1542 | return err; | |
1543 | changed = 1; | |
1544 | } | |
00db8189 | 1545 | |
5273e3a5 FF |
1546 | bmsr = phy_read(phydev, MII_BMSR); |
1547 | if (bmsr < 0) | |
1548 | return bmsr; | |
1549 | ||
1550 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all | |
1551 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a | |
1552 | * logical 1. | |
1553 | */ | |
1554 | if (!(bmsr & BMSR_ESTATEN)) | |
1555 | return changed; | |
1556 | ||
00db8189 | 1557 | /* Configure gigabit if it's supported */ |
5273e3a5 FF |
1558 | adv = phy_read(phydev, MII_CTRL1000); |
1559 | if (adv < 0) | |
1560 | return adv; | |
1561 | ||
1562 | oldadv = adv; | |
1563 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | |
1564 | ||
3c1bcc86 AL |
1565 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
1566 | phydev->supported) || | |
1567 | linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | |
1568 | phydev->supported)) | |
37f07023 | 1569 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
00db8189 | 1570 | |
eb686231 M |
1571 | if (adv != oldadv) |
1572 | changed = 1; | |
1573 | ||
5273e3a5 FF |
1574 | err = phy_write(phydev, MII_CTRL1000, adv); |
1575 | if (err < 0) | |
1576 | return err; | |
1577 | ||
51e2a384 | 1578 | return changed; |
00db8189 | 1579 | } |
00db8189 | 1580 | |
d853d145 | 1581 | /** |
1582 | * genphy_config_eee_advert - disable unwanted eee mode advertisement | |
1583 | * @phydev: target phy_device struct | |
1584 | * | |
1585 | * Description: Writes MDIO_AN_EEE_ADV after disabling unsupported energy | |
1586 | * efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't | |
1587 | * changed, and 1 if it has changed. | |
1588 | */ | |
1589 | static int genphy_config_eee_advert(struct phy_device *phydev) | |
1590 | { | |
3bb9ab63 | 1591 | int broken = phydev->eee_broken_modes; |
1592 | int old_adv, adv; | |
d853d145 | 1593 | |
1594 | /* Nothing to disable */ | |
1595 | if (!broken) | |
1596 | return 0; | |
1597 | ||
1598 | /* If the following call fails, we assume that EEE is not | |
1599 | * supported by the phy. If we read 0, EEE is not advertised | |
1600 | * In both case, we don't need to continue | |
1601 | */ | |
a6d99fcd | 1602 | adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); |
d853d145 | 1603 | if (adv <= 0) |
1604 | return 0; | |
1605 | ||
1606 | old_adv = adv; | |
1607 | adv &= ~broken; | |
1608 | ||
1609 | /* Advertising remains unchanged with the broken mask */ | |
1610 | if (old_adv == adv) | |
1611 | return 0; | |
1612 | ||
a6d99fcd | 1613 | phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); |
d853d145 | 1614 | |
1615 | return 1; | |
1616 | } | |
1617 | ||
b3df0da8 RD |
1618 | /** |
1619 | * genphy_setup_forced - configures/forces speed/duplex from @phydev | |
1620 | * @phydev: target phy_device struct | |
00db8189 | 1621 | * |
b3df0da8 | 1622 | * Description: Configures MII_BMCR to force speed/duplex |
00db8189 | 1623 | * to the values in phydev. Assumes that the values are valid. |
b3df0da8 RD |
1624 | * Please see phy_sanitize_settings(). |
1625 | */ | |
3fb69bca | 1626 | int genphy_setup_forced(struct phy_device *phydev) |
00db8189 | 1627 | { |
fea23fb5 | 1628 | u16 ctl = 0; |
00db8189 | 1629 | |
2f53e904 SS |
1630 | phydev->pause = 0; |
1631 | phydev->asym_pause = 0; | |
00db8189 AF |
1632 | |
1633 | if (SPEED_1000 == phydev->speed) | |
1634 | ctl |= BMCR_SPEED1000; | |
1635 | else if (SPEED_100 == phydev->speed) | |
1636 | ctl |= BMCR_SPEED100; | |
1637 | ||
1638 | if (DUPLEX_FULL == phydev->duplex) | |
1639 | ctl |= BMCR_FULLDPLX; | |
e109374f | 1640 | |
fea23fb5 | 1641 | return phy_modify(phydev, MII_BMCR, |
18a5b052 | 1642 | ~(BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN), ctl); |
00db8189 | 1643 | } |
3fb69bca | 1644 | EXPORT_SYMBOL(genphy_setup_forced); |
00db8189 | 1645 | |
b3df0da8 RD |
1646 | /** |
1647 | * genphy_restart_aneg - Enable and Restart Autonegotiation | |
1648 | * @phydev: target phy_device struct | |
1649 | */ | |
00db8189 AF |
1650 | int genphy_restart_aneg(struct phy_device *phydev) |
1651 | { | |
00db8189 | 1652 | /* Don't isolate the PHY if we're negotiating */ |
f102852f | 1653 | return phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, |
fea23fb5 | 1654 | BMCR_ANENABLE | BMCR_ANRESTART); |
00db8189 | 1655 | } |
892871dc | 1656 | EXPORT_SYMBOL(genphy_restart_aneg); |
00db8189 | 1657 | |
b3df0da8 RD |
1658 | /** |
1659 | * genphy_config_aneg - restart auto-negotiation or write BMCR | |
1660 | * @phydev: target phy_device struct | |
00db8189 | 1661 | * |
b3df0da8 | 1662 | * Description: If auto-negotiation is enabled, we configure the |
00db8189 | 1663 | * advertising, and then restart auto-negotiation. If it is not |
b3df0da8 | 1664 | * enabled, then we write the BMCR. |
00db8189 AF |
1665 | */ |
1666 | int genphy_config_aneg(struct phy_device *phydev) | |
1667 | { | |
d853d145 | 1668 | int err, changed; |
1669 | ||
1670 | changed = genphy_config_eee_advert(phydev); | |
00db8189 | 1671 | |
de339c2a TP |
1672 | if (AUTONEG_ENABLE != phydev->autoneg) |
1673 | return genphy_setup_forced(phydev); | |
00db8189 | 1674 | |
d853d145 | 1675 | err = genphy_config_advert(phydev); |
1676 | if (err < 0) /* error */ | |
1677 | return err; | |
1678 | ||
1679 | changed |= err; | |
1680 | ||
1681 | if (changed == 0) { | |
25985edc | 1682 | /* Advertisement hasn't changed, but maybe aneg was never on to |
2f53e904 SS |
1683 | * begin with? Or maybe phy was isolated? |
1684 | */ | |
de339c2a TP |
1685 | int ctl = phy_read(phydev, MII_BMCR); |
1686 | ||
1687 | if (ctl < 0) | |
1688 | return ctl; | |
1689 | ||
1690 | if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) | |
d853d145 | 1691 | changed = 1; /* do restart aneg */ |
de339c2a TP |
1692 | } |
1693 | ||
1694 | /* Only restart aneg if we are advertising something different | |
2f53e904 SS |
1695 | * than we were before. |
1696 | */ | |
d853d145 | 1697 | if (changed > 0) |
1698 | return genphy_restart_aneg(phydev); | |
00db8189 | 1699 | |
d853d145 | 1700 | return 0; |
00db8189 AF |
1701 | } |
1702 | EXPORT_SYMBOL(genphy_config_aneg); | |
1703 | ||
a9fa6e6a FF |
1704 | /** |
1705 | * genphy_aneg_done - return auto-negotiation status | |
1706 | * @phydev: target phy_device struct | |
1707 | * | |
1708 | * Description: Reads the status register and returns 0 either if | |
1709 | * auto-negotiation is incomplete, or if there was an error. | |
1710 | * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done. | |
1711 | */ | |
1712 | int genphy_aneg_done(struct phy_device *phydev) | |
1713 | { | |
1714 | int retval = phy_read(phydev, MII_BMSR); | |
1715 | ||
1716 | return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); | |
1717 | } | |
1718 | EXPORT_SYMBOL(genphy_aneg_done); | |
1719 | ||
b3df0da8 RD |
1720 | /** |
1721 | * genphy_update_link - update link status in @phydev | |
1722 | * @phydev: target phy_device struct | |
00db8189 | 1723 | * |
b3df0da8 | 1724 | * Description: Update the value in phydev->link to reflect the |
00db8189 | 1725 | * current link value. In order to do this, we need to read |
b3df0da8 | 1726 | * the status register twice, keeping the second value. |
00db8189 AF |
1727 | */ |
1728 | int genphy_update_link(struct phy_device *phydev) | |
1729 | { | |
1730 | int status; | |
1731 | ||
1732 | /* Do a fake read */ | |
1733 | status = phy_read(phydev, MII_BMSR); | |
00db8189 AF |
1734 | if (status < 0) |
1735 | return status; | |
1736 | ||
1737 | /* Read link and autonegotiation status */ | |
1738 | status = phy_read(phydev, MII_BMSR); | |
00db8189 AF |
1739 | if (status < 0) |
1740 | return status; | |
1741 | ||
1742 | if ((status & BMSR_LSTATUS) == 0) | |
1743 | phydev->link = 0; | |
1744 | else | |
1745 | phydev->link = 1; | |
1746 | ||
1747 | return 0; | |
1748 | } | |
6b655529 | 1749 | EXPORT_SYMBOL(genphy_update_link); |
00db8189 | 1750 | |
b3df0da8 RD |
1751 | /** |
1752 | * genphy_read_status - check the link status and update current link state | |
1753 | * @phydev: target phy_device struct | |
00db8189 | 1754 | * |
b3df0da8 | 1755 | * Description: Check the link, then figure out the current state |
00db8189 AF |
1756 | * by comparing what we advertise with what the link partner |
1757 | * advertises. Start by checking the gigabit possibilities, | |
1758 | * then move on to 10/100. | |
1759 | */ | |
1760 | int genphy_read_status(struct phy_device *phydev) | |
1761 | { | |
1762 | int adv; | |
1763 | int err; | |
1764 | int lpa; | |
1765 | int lpagb = 0; | |
a4572e0c CB |
1766 | int common_adv; |
1767 | int common_adv_gb = 0; | |
00db8189 | 1768 | |
2f53e904 | 1769 | /* Update the link, but return if there was an error */ |
00db8189 AF |
1770 | err = genphy_update_link(phydev); |
1771 | if (err) | |
1772 | return err; | |
1773 | ||
c0ec3c27 | 1774 | linkmode_zero(phydev->lp_advertising); |
114002bc | 1775 | |
00db8189 | 1776 | if (AUTONEG_ENABLE == phydev->autoneg) { |
3c1bcc86 AL |
1777 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
1778 | phydev->supported) || | |
1779 | linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | |
1780 | phydev->supported)) { | |
00db8189 | 1781 | lpagb = phy_read(phydev, MII_STAT1000); |
00db8189 AF |
1782 | if (lpagb < 0) |
1783 | return lpagb; | |
1784 | ||
1785 | adv = phy_read(phydev, MII_CTRL1000); | |
00db8189 AF |
1786 | if (adv < 0) |
1787 | return adv; | |
1788 | ||
b8f8c8eb HK |
1789 | if (lpagb & LPA_1000MSFAIL) { |
1790 | if (adv & CTL1000_ENABLE_MASTER) | |
1791 | phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); | |
1792 | else | |
1793 | phydev_err(phydev, "Master/Slave resolution failed\n"); | |
1794 | return -ENOLINK; | |
1795 | } | |
1796 | ||
78a24df3 AL |
1797 | mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, |
1798 | lpagb); | |
a4572e0c | 1799 | common_adv_gb = lpagb & adv << 2; |
00db8189 AF |
1800 | } |
1801 | ||
1802 | lpa = phy_read(phydev, MII_LPA); | |
00db8189 AF |
1803 | if (lpa < 0) |
1804 | return lpa; | |
1805 | ||
d3351931 | 1806 | mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); |
114002bc | 1807 | |
00db8189 | 1808 | adv = phy_read(phydev, MII_ADVERTISE); |
00db8189 AF |
1809 | if (adv < 0) |
1810 | return adv; | |
1811 | ||
a4572e0c | 1812 | common_adv = lpa & adv; |
00db8189 AF |
1813 | |
1814 | phydev->speed = SPEED_10; | |
1815 | phydev->duplex = DUPLEX_HALF; | |
2f53e904 SS |
1816 | phydev->pause = 0; |
1817 | phydev->asym_pause = 0; | |
00db8189 | 1818 | |
a4572e0c | 1819 | if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
00db8189 AF |
1820 | phydev->speed = SPEED_1000; |
1821 | ||
a4572e0c | 1822 | if (common_adv_gb & LPA_1000FULL) |
00db8189 | 1823 | phydev->duplex = DUPLEX_FULL; |
a4572e0c | 1824 | } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
00db8189 | 1825 | phydev->speed = SPEED_100; |
e109374f | 1826 | |
a4572e0c | 1827 | if (common_adv & LPA_100FULL) |
00db8189 AF |
1828 | phydev->duplex = DUPLEX_FULL; |
1829 | } else | |
a4572e0c | 1830 | if (common_adv & LPA_10FULL) |
00db8189 AF |
1831 | phydev->duplex = DUPLEX_FULL; |
1832 | ||
e109374f | 1833 | if (phydev->duplex == DUPLEX_FULL) { |
00db8189 AF |
1834 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; |
1835 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; | |
1836 | } | |
1837 | } else { | |
1838 | int bmcr = phy_read(phydev, MII_BMCR); | |
2f53e904 | 1839 | |
00db8189 AF |
1840 | if (bmcr < 0) |
1841 | return bmcr; | |
1842 | ||
1843 | if (bmcr & BMCR_FULLDPLX) | |
1844 | phydev->duplex = DUPLEX_FULL; | |
1845 | else | |
1846 | phydev->duplex = DUPLEX_HALF; | |
1847 | ||
1848 | if (bmcr & BMCR_SPEED1000) | |
1849 | phydev->speed = SPEED_1000; | |
1850 | else if (bmcr & BMCR_SPEED100) | |
1851 | phydev->speed = SPEED_100; | |
1852 | else | |
1853 | phydev->speed = SPEED_10; | |
1854 | ||
2f53e904 SS |
1855 | phydev->pause = 0; |
1856 | phydev->asym_pause = 0; | |
00db8189 AF |
1857 | } |
1858 | ||
1859 | return 0; | |
1860 | } | |
1861 | EXPORT_SYMBOL(genphy_read_status); | |
1862 | ||
797ac071 FF |
1863 | /** |
1864 | * genphy_soft_reset - software reset the PHY via BMCR_RESET bit | |
1865 | * @phydev: target phy_device struct | |
1866 | * | |
1867 | * Description: Perform a software PHY reset using the standard | |
1868 | * BMCR_RESET bit and poll for the reset bit to be cleared. | |
1869 | * | |
1870 | * Returns: 0 on success, < 0 on failure | |
1871 | */ | |
1872 | int genphy_soft_reset(struct phy_device *phydev) | |
1873 | { | |
1874 | int ret; | |
1875 | ||
1876 | ret = phy_write(phydev, MII_BMCR, BMCR_RESET); | |
1877 | if (ret < 0) | |
1878 | return ret; | |
1879 | ||
1880 | return phy_poll_reset(phydev); | |
1881 | } | |
1882 | EXPORT_SYMBOL(genphy_soft_reset); | |
1883 | ||
af6b6967 | 1884 | int genphy_config_init(struct phy_device *phydev) |
00db8189 | 1885 | { |
84c22d79 | 1886 | int val; |
3c1bcc86 | 1887 | __ETHTOOL_DECLARE_LINK_MODE_MASK(features) = { 0, }; |
00db8189 | 1888 | |
3c1bcc86 AL |
1889 | linkmode_set_bit_array(phy_basic_ports_array, |
1890 | ARRAY_SIZE(phy_basic_ports_array), | |
1891 | features); | |
1892 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, features); | |
1893 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, features); | |
00db8189 AF |
1894 | |
1895 | /* Do we support autonegotiation? */ | |
1896 | val = phy_read(phydev, MII_BMSR); | |
00db8189 AF |
1897 | if (val < 0) |
1898 | return val; | |
1899 | ||
1900 | if (val & BMSR_ANEGCAPABLE) | |
3c1bcc86 | 1901 | linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, features); |
00db8189 AF |
1902 | |
1903 | if (val & BMSR_100FULL) | |
3c1bcc86 | 1904 | linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, features); |
00db8189 | 1905 | if (val & BMSR_100HALF) |
3c1bcc86 | 1906 | linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, features); |
00db8189 | 1907 | if (val & BMSR_10FULL) |
3c1bcc86 | 1908 | linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, features); |
00db8189 | 1909 | if (val & BMSR_10HALF) |
3c1bcc86 | 1910 | linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, features); |
00db8189 AF |
1911 | |
1912 | if (val & BMSR_ESTATEN) { | |
1913 | val = phy_read(phydev, MII_ESTATUS); | |
00db8189 AF |
1914 | if (val < 0) |
1915 | return val; | |
1916 | ||
1917 | if (val & ESTATUS_1000_TFULL) | |
3c1bcc86 AL |
1918 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
1919 | features); | |
00db8189 | 1920 | if (val & ESTATUS_1000_THALF) |
3c1bcc86 AL |
1921 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
1922 | features); | |
00db8189 AF |
1923 | } |
1924 | ||
3c1bcc86 AL |
1925 | linkmode_and(phydev->supported, phydev->supported, features); |
1926 | linkmode_and(phydev->advertising, phydev->advertising, features); | |
00db8189 AF |
1927 | |
1928 | return 0; | |
1929 | } | |
a0a32d3a | 1930 | EXPORT_SYMBOL(genphy_config_init); |
124059fd | 1931 | |
5df7af85 KH |
1932 | /* This is used for the phy device which doesn't support the MMD extended |
1933 | * register access, but it does have side effect when we are trying to access | |
1934 | * the MMD register via indirect method. | |
1935 | */ | |
1936 | int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum) | |
1937 | { | |
1938 | return -EOPNOTSUPP; | |
1939 | } | |
1940 | EXPORT_SYMBOL(genphy_read_mmd_unsupported); | |
1941 | ||
1942 | int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum, | |
1943 | u16 regnum, u16 val) | |
1944 | { | |
1945 | return -EOPNOTSUPP; | |
1946 | } | |
1947 | EXPORT_SYMBOL(genphy_write_mmd_unsupported); | |
1948 | ||
0f0ca340 GC |
1949 | int genphy_suspend(struct phy_device *phydev) |
1950 | { | |
032f4700 | 1951 | return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); |
0f0ca340 GC |
1952 | } |
1953 | EXPORT_SYMBOL(genphy_suspend); | |
00db8189 | 1954 | |
0f0ca340 GC |
1955 | int genphy_resume(struct phy_device *phydev) |
1956 | { | |
032f4700 | 1957 | return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN); |
0f0ca340 GC |
1958 | } |
1959 | EXPORT_SYMBOL(genphy_resume); | |
00db8189 | 1960 | |
f0f9b4ed LYS |
1961 | int genphy_loopback(struct phy_device *phydev, bool enable) |
1962 | { | |
f102852f | 1963 | return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, |
fea23fb5 | 1964 | enable ? BMCR_LOOPBACK : 0); |
f0f9b4ed LYS |
1965 | } |
1966 | EXPORT_SYMBOL(genphy_loopback); | |
1967 | ||
f3a6bd39 SH |
1968 | static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) |
1969 | { | |
f3a6bd39 | 1970 | switch (max_speed) { |
6915bf3b HK |
1971 | case SPEED_10: |
1972 | linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | |
1973 | phydev->supported); | |
1974 | linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | |
1975 | phydev->supported); | |
f3a6bd39 SH |
1976 | /* fall through */ |
1977 | case SPEED_100: | |
6915bf3b HK |
1978 | linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
1979 | phydev->supported); | |
1980 | linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | |
1981 | phydev->supported); | |
1982 | break; | |
1983 | case SPEED_1000: | |
1984 | break; | |
1985 | default: | |
1986 | return -ENOTSUPP; | |
f3a6bd39 SH |
1987 | } |
1988 | ||
1989 | return 0; | |
1990 | } | |
1991 | ||
1992 | int phy_set_max_speed(struct phy_device *phydev, u32 max_speed) | |
1993 | { | |
1994 | int err; | |
1995 | ||
1996 | err = __set_phy_supported(phydev, max_speed); | |
1997 | if (err) | |
1998 | return err; | |
1999 | ||
3c1bcc86 | 2000 | linkmode_copy(phydev->advertising, phydev->supported); |
f3a6bd39 SH |
2001 | |
2002 | return 0; | |
2003 | } | |
2004 | EXPORT_SYMBOL(phy_set_max_speed); | |
2005 | ||
41124fa6 AL |
2006 | /** |
2007 | * phy_remove_link_mode - Remove a supported link mode | |
2008 | * @phydev: phy_device structure to remove link mode from | |
2009 | * @link_mode: Link mode to be removed | |
2010 | * | |
2011 | * Description: Some MACs don't support all link modes which the PHY | |
2012 | * does. e.g. a 1G MAC often does not support 1000Half. Add a helper | |
2013 | * to remove a link mode. | |
2014 | */ | |
2015 | void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode) | |
2016 | { | |
3c1bcc86 AL |
2017 | linkmode_clear_bit(link_mode, phydev->supported); |
2018 | linkmode_copy(phydev->advertising, phydev->supported); | |
41124fa6 AL |
2019 | } |
2020 | EXPORT_SYMBOL(phy_remove_link_mode); | |
2021 | ||
c306ad36 AL |
2022 | /** |
2023 | * phy_support_sym_pause - Enable support of symmetrical pause | |
2024 | * @phydev: target phy_device struct | |
2025 | * | |
2026 | * Description: Called by the MAC to indicate is supports symmetrical | |
2027 | * Pause, but not asym pause. | |
2028 | */ | |
2029 | void phy_support_sym_pause(struct phy_device *phydev) | |
2030 | { | |
3c1bcc86 AL |
2031 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); |
2032 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); | |
2033 | linkmode_copy(phydev->advertising, phydev->supported); | |
c306ad36 AL |
2034 | } |
2035 | EXPORT_SYMBOL(phy_support_sym_pause); | |
2036 | ||
af8d9bb2 AL |
2037 | /** |
2038 | * phy_support_asym_pause - Enable support of asym pause | |
2039 | * @phydev: target phy_device struct | |
2040 | * | |
2041 | * Description: Called by the MAC to indicate is supports Asym Pause. | |
2042 | */ | |
2043 | void phy_support_asym_pause(struct phy_device *phydev) | |
2044 | { | |
3c1bcc86 AL |
2045 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); |
2046 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); | |
2047 | linkmode_copy(phydev->advertising, phydev->supported); | |
af8d9bb2 AL |
2048 | } |
2049 | EXPORT_SYMBOL(phy_support_asym_pause); | |
2050 | ||
0c122405 AL |
2051 | /** |
2052 | * phy_set_sym_pause - Configure symmetric Pause | |
2053 | * @phydev: target phy_device struct | |
2054 | * @rx: Receiver Pause is supported | |
2055 | * @tx: Transmit Pause is supported | |
2056 | * @autoneg: Auto neg should be used | |
2057 | * | |
2058 | * Description: Configure advertised Pause support depending on if | |
2059 | * receiver pause and pause auto neg is supported. Generally called | |
2060 | * from the set_pauseparam .ndo. | |
2061 | */ | |
2062 | void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx, | |
2063 | bool autoneg) | |
2064 | { | |
3c1bcc86 | 2065 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); |
0c122405 AL |
2066 | |
2067 | if (rx && tx && autoneg) | |
3c1bcc86 AL |
2068 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2069 | phydev->supported); | |
0c122405 | 2070 | |
3c1bcc86 | 2071 | linkmode_copy(phydev->advertising, phydev->supported); |
0c122405 AL |
2072 | } |
2073 | EXPORT_SYMBOL(phy_set_sym_pause); | |
2074 | ||
70814e81 AL |
2075 | /** |
2076 | * phy_set_asym_pause - Configure Pause and Asym Pause | |
2077 | * @phydev: target phy_device struct | |
2078 | * @rx: Receiver Pause is supported | |
2079 | * @tx: Transmit Pause is supported | |
2080 | * | |
2081 | * Description: Configure advertised Pause support depending on if | |
2082 | * transmit and receiver pause is supported. If there has been a | |
2083 | * change in adverting, trigger a new autoneg. Generally called from | |
2084 | * the set_pauseparam .ndo. | |
2085 | */ | |
2086 | void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx) | |
2087 | { | |
3c1bcc86 | 2088 | __ETHTOOL_DECLARE_LINK_MODE_MASK(oldadv); |
70814e81 | 2089 | |
3c1bcc86 | 2090 | linkmode_copy(oldadv, phydev->advertising); |
70814e81 | 2091 | |
3c1bcc86 AL |
2092 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2093 | phydev->advertising); | |
2094 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2095 | phydev->advertising); | |
70814e81 | 2096 | |
3c1bcc86 AL |
2097 | if (rx) { |
2098 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | |
2099 | phydev->advertising); | |
2100 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2101 | phydev->advertising); | |
70814e81 | 2102 | } |
3c1bcc86 AL |
2103 | |
2104 | if (tx) | |
2105 | linkmode_change_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2106 | phydev->advertising); | |
2107 | ||
2108 | if (!linkmode_equal(oldadv, phydev->advertising) && | |
2109 | phydev->autoneg) | |
2110 | phy_start_aneg(phydev); | |
70814e81 AL |
2111 | } |
2112 | EXPORT_SYMBOL(phy_set_asym_pause); | |
2113 | ||
22b7d299 AL |
2114 | /** |
2115 | * phy_validate_pause - Test if the PHY/MAC support the pause configuration | |
2116 | * @phydev: phy_device struct | |
2117 | * @pp: requested pause configuration | |
2118 | * | |
2119 | * Description: Test if the PHY/MAC combination supports the Pause | |
2120 | * configuration the user is requesting. Returns True if it is | |
2121 | * supported, false otherwise. | |
2122 | */ | |
2123 | bool phy_validate_pause(struct phy_device *phydev, | |
2124 | struct ethtool_pauseparam *pp) | |
2125 | { | |
3c1bcc86 AL |
2126 | if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2127 | phydev->supported) || | |
2128 | (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2129 | phydev->supported) && | |
22b7d299 AL |
2130 | pp->rx_pause != pp->tx_pause)) |
2131 | return false; | |
2132 | return true; | |
2133 | } | |
2134 | EXPORT_SYMBOL(phy_validate_pause); | |
2135 | ||
de906af1 SH |
2136 | static void of_set_phy_supported(struct phy_device *phydev) |
2137 | { | |
e5a03bfd | 2138 | struct device_node *node = phydev->mdio.dev.of_node; |
de906af1 SH |
2139 | u32 max_speed; |
2140 | ||
2141 | if (!IS_ENABLED(CONFIG_OF_MDIO)) | |
2142 | return; | |
2143 | ||
2144 | if (!node) | |
2145 | return; | |
2146 | ||
f3a6bd39 SH |
2147 | if (!of_property_read_u32(node, "max-speed", &max_speed)) |
2148 | __set_phy_supported(phydev, max_speed); | |
de906af1 SH |
2149 | } |
2150 | ||
d853d145 | 2151 | static void of_set_phy_eee_broken(struct phy_device *phydev) |
2152 | { | |
2153 | struct device_node *node = phydev->mdio.dev.of_node; | |
57f39862 | 2154 | u32 broken = 0; |
d853d145 | 2155 | |
2156 | if (!IS_ENABLED(CONFIG_OF_MDIO)) | |
2157 | return; | |
2158 | ||
2159 | if (!node) | |
2160 | return; | |
2161 | ||
57f39862 | 2162 | if (of_property_read_bool(node, "eee-broken-100tx")) |
2163 | broken |= MDIO_EEE_100TX; | |
2164 | if (of_property_read_bool(node, "eee-broken-1000t")) | |
2165 | broken |= MDIO_EEE_1000T; | |
2166 | if (of_property_read_bool(node, "eee-broken-10gt")) | |
2167 | broken |= MDIO_EEE_10GT; | |
2168 | if (of_property_read_bool(node, "eee-broken-1000kx")) | |
2169 | broken |= MDIO_EEE_1000KX; | |
2170 | if (of_property_read_bool(node, "eee-broken-10gkx4")) | |
2171 | broken |= MDIO_EEE_10GKX4; | |
2172 | if (of_property_read_bool(node, "eee-broken-10gkr")) | |
2173 | broken |= MDIO_EEE_10GKR; | |
2174 | ||
2175 | phydev->eee_broken_modes = broken; | |
d853d145 | 2176 | } |
2177 | ||
0d2e778e HK |
2178 | static bool phy_drv_supports_irq(struct phy_driver *phydrv) |
2179 | { | |
a21ff3c8 | 2180 | return phydrv->config_intr && phydrv->ack_interrupt; |
0d2e778e HK |
2181 | } |
2182 | ||
b3df0da8 RD |
2183 | /** |
2184 | * phy_probe - probe and init a PHY device | |
2185 | * @dev: device to probe and init | |
00db8189 | 2186 | * |
b3df0da8 | 2187 | * Description: Take care of setting up the phy_device structure, |
00db8189 AF |
2188 | * set the state to READY (the driver's init function should |
2189 | * set it to STARTING if needed). | |
2190 | */ | |
2191 | static int phy_probe(struct device *dev) | |
2192 | { | |
553fe92b | 2193 | struct phy_device *phydev = to_phy_device(dev); |
e5a03bfd | 2194 | struct device_driver *drv = phydev->mdio.dev.driver; |
553fe92b | 2195 | struct phy_driver *phydrv = to_phy_driver(drv); |
00db8189 AF |
2196 | int err = 0; |
2197 | ||
00db8189 AF |
2198 | phydev->drv = phydrv; |
2199 | ||
2c7b4921 FF |
2200 | /* Disable the interrupt if the PHY doesn't support it |
2201 | * but the interrupt is still a valid one | |
2202 | */ | |
0d2e778e | 2203 | if (!phy_drv_supports_irq(phydrv) && phy_interrupt_is_valid(phydev)) |
00db8189 AF |
2204 | phydev->irq = PHY_POLL; |
2205 | ||
4284b6a5 FF |
2206 | if (phydrv->flags & PHY_IS_INTERNAL) |
2207 | phydev->is_internal = true; | |
2208 | ||
35b5f6b1 | 2209 | mutex_lock(&phydev->lock); |
00db8189 AF |
2210 | |
2211 | /* Start out supporting everything. Eventually, | |
2212 | * a controller will attach, and may modify one | |
2f53e904 SS |
2213 | * or both of these values |
2214 | */ | |
3c1bcc86 | 2215 | linkmode_copy(phydev->supported, phydrv->features); |
de906af1 | 2216 | of_set_phy_supported(phydev); |
3c1bcc86 | 2217 | linkmode_copy(phydev->advertising, phydev->supported); |
00db8189 | 2218 | |
d853d145 | 2219 | /* Get the EEE modes we want to prohibit. We will ask |
2220 | * the PHY stop advertising these mode later on | |
2221 | */ | |
2222 | of_set_phy_eee_broken(phydev); | |
2223 | ||
529ed127 TT |
2224 | /* The Pause Frame bits indicate that the PHY can support passing |
2225 | * pause frames. During autonegotiation, the PHYs will determine if | |
2226 | * they should allow pause frames to pass. The MAC driver should then | |
2227 | * use that result to determine whether to enable flow control via | |
2228 | * pause frames. | |
2229 | * | |
2230 | * Normally, PHY drivers should not set the Pause bits, and instead | |
2231 | * allow phylib to do that. However, there may be some situations | |
2232 | * (e.g. hardware erratum) where the driver wants to set only one | |
2233 | * of these bits. | |
2234 | */ | |
719655a1 AL |
2235 | if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) || |
2236 | test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) { | |
3c1bcc86 AL |
2237 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2238 | phydev->supported); | |
2239 | linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2240 | phydev->supported); | |
719655a1 | 2241 | if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features)) |
3c1bcc86 AL |
2242 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2243 | phydev->supported); | |
719655a1 AL |
2244 | if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
2245 | phydrv->features)) | |
3c1bcc86 AL |
2246 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
2247 | phydev->supported); | |
529ed127 | 2248 | } else { |
3c1bcc86 AL |
2249 | linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
2250 | phydev->supported); | |
2251 | linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | |
2252 | phydev->supported); | |
529ed127 TT |
2253 | } |
2254 | ||
00db8189 AF |
2255 | /* Set the state to READY by default */ |
2256 | phydev->state = PHY_READY; | |
2257 | ||
bafbdd52 SS |
2258 | if (phydev->drv->probe) { |
2259 | /* Deassert the reset signal */ | |
2260 | phy_device_reset(phydev, 0); | |
2261 | ||
00db8189 | 2262 | err = phydev->drv->probe(phydev); |
bafbdd52 SS |
2263 | if (err) { |
2264 | /* Assert the reset signal */ | |
2265 | phy_device_reset(phydev, 1); | |
2266 | } | |
2267 | } | |
00db8189 | 2268 | |
35b5f6b1 | 2269 | mutex_unlock(&phydev->lock); |
00db8189 | 2270 | |
00db8189 AF |
2271 | return err; |
2272 | } | |
2273 | ||
2274 | static int phy_remove(struct device *dev) | |
2275 | { | |
553fe92b | 2276 | struct phy_device *phydev = to_phy_device(dev); |
00db8189 | 2277 | |
7b9a88a3 FF |
2278 | cancel_delayed_work_sync(&phydev->state_queue); |
2279 | ||
35b5f6b1 | 2280 | mutex_lock(&phydev->lock); |
00db8189 | 2281 | phydev->state = PHY_DOWN; |
35b5f6b1 | 2282 | mutex_unlock(&phydev->lock); |
00db8189 | 2283 | |
bafbdd52 | 2284 | if (phydev->drv && phydev->drv->remove) { |
00db8189 | 2285 | phydev->drv->remove(phydev); |
bafbdd52 SS |
2286 | |
2287 | /* Assert the reset signal */ | |
2288 | phy_device_reset(phydev, 1); | |
2289 | } | |
00db8189 AF |
2290 | phydev->drv = NULL; |
2291 | ||
2292 | return 0; | |
2293 | } | |
2294 | ||
b3df0da8 RD |
2295 | /** |
2296 | * phy_driver_register - register a phy_driver with the PHY layer | |
2297 | * @new_driver: new phy_driver to register | |
be01da72 | 2298 | * @owner: module owning this PHY |
b3df0da8 | 2299 | */ |
be01da72 | 2300 | int phy_driver_register(struct phy_driver *new_driver, struct module *owner) |
00db8189 AF |
2301 | { |
2302 | int retval; | |
2303 | ||
3e64cf7a CG |
2304 | if (WARN_ON(!new_driver->features)) { |
2305 | pr_err("%s: Driver features are missing\n", new_driver->name); | |
2306 | return -EINVAL; | |
2307 | } | |
2308 | ||
a9049e0c AL |
2309 | new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY; |
2310 | new_driver->mdiodrv.driver.name = new_driver->name; | |
2311 | new_driver->mdiodrv.driver.bus = &mdio_bus_type; | |
2312 | new_driver->mdiodrv.driver.probe = phy_probe; | |
2313 | new_driver->mdiodrv.driver.remove = phy_remove; | |
2314 | new_driver->mdiodrv.driver.owner = owner; | |
00db8189 | 2315 | |
a9049e0c | 2316 | retval = driver_register(&new_driver->mdiodrv.driver); |
00db8189 | 2317 | if (retval) { |
8d242488 JP |
2318 | pr_err("%s: Error %d in registering driver\n", |
2319 | new_driver->name, retval); | |
00db8189 AF |
2320 | |
2321 | return retval; | |
2322 | } | |
2323 | ||
f2511f13 | 2324 | pr_debug("%s: Registered new driver\n", new_driver->name); |
00db8189 AF |
2325 | |
2326 | return 0; | |
2327 | } | |
2328 | EXPORT_SYMBOL(phy_driver_register); | |
2329 | ||
be01da72 AL |
2330 | int phy_drivers_register(struct phy_driver *new_driver, int n, |
2331 | struct module *owner) | |
d5bf9071 CH |
2332 | { |
2333 | int i, ret = 0; | |
2334 | ||
2335 | for (i = 0; i < n; i++) { | |
be01da72 | 2336 | ret = phy_driver_register(new_driver + i, owner); |
d5bf9071 CH |
2337 | if (ret) { |
2338 | while (i-- > 0) | |
2339 | phy_driver_unregister(new_driver + i); | |
2340 | break; | |
2341 | } | |
2342 | } | |
2343 | return ret; | |
2344 | } | |
2345 | EXPORT_SYMBOL(phy_drivers_register); | |
2346 | ||
00db8189 AF |
2347 | void phy_driver_unregister(struct phy_driver *drv) |
2348 | { | |
a9049e0c | 2349 | driver_unregister(&drv->mdiodrv.driver); |
00db8189 AF |
2350 | } |
2351 | EXPORT_SYMBOL(phy_driver_unregister); | |
2352 | ||
d5bf9071 CH |
2353 | void phy_drivers_unregister(struct phy_driver *drv, int n) |
2354 | { | |
2355 | int i; | |
2f53e904 SS |
2356 | |
2357 | for (i = 0; i < n; i++) | |
d5bf9071 | 2358 | phy_driver_unregister(drv + i); |
d5bf9071 CH |
2359 | } |
2360 | EXPORT_SYMBOL(phy_drivers_unregister); | |
2361 | ||
921690f2 | 2362 | static struct phy_driver genphy_driver = { |
e1393456 AF |
2363 | .phy_id = 0xffffffff, |
2364 | .phy_id_mask = 0xffffffff, | |
2365 | .name = "Generic PHY", | |
0878fff1 | 2366 | .soft_reset = genphy_no_soft_reset, |
e1393456 | 2367 | .config_init = genphy_config_init, |
719655a1 | 2368 | .features = PHY_GBIT_ALL_PORTS_FEATURES, |
76a423a3 | 2369 | .aneg_done = genphy_aneg_done, |
0f0ca340 GC |
2370 | .suspend = genphy_suspend, |
2371 | .resume = genphy_resume, | |
f0f9b4ed | 2372 | .set_loopback = genphy_loopback, |
921690f2 | 2373 | }; |
00db8189 | 2374 | |
67c4f3fa | 2375 | static int __init phy_init(void) |
00db8189 | 2376 | { |
67c4f3fa | 2377 | int rc; |
67c4f3fa JG |
2378 | |
2379 | rc = mdio_bus_init(); | |
2380 | if (rc) | |
e1393456 | 2381 | return rc; |
00db8189 | 2382 | |
719655a1 AL |
2383 | features_init(); |
2384 | ||
921690f2 | 2385 | rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE); |
e1393456 | 2386 | if (rc) |
921690f2 RK |
2387 | goto err_10g; |
2388 | ||
2389 | rc = phy_driver_register(&genphy_driver, THIS_MODULE); | |
2390 | if (rc) { | |
2391 | phy_driver_unregister(&genphy_10g_driver); | |
2392 | err_10g: | |
e1393456 | 2393 | mdio_bus_exit(); |
921690f2 | 2394 | } |
67c4f3fa | 2395 | |
67c4f3fa | 2396 | return rc; |
00db8189 AF |
2397 | } |
2398 | ||
67c4f3fa | 2399 | static void __exit phy_exit(void) |
00db8189 | 2400 | { |
921690f2 RK |
2401 | phy_driver_unregister(&genphy_10g_driver); |
2402 | phy_driver_unregister(&genphy_driver); | |
e1393456 | 2403 | mdio_bus_exit(); |
00db8189 AF |
2404 | } |
2405 | ||
e1393456 | 2406 | subsys_initcall(phy_init); |
67c4f3fa | 2407 | module_exit(phy_exit); |