blob: 270176cfe6296f36e9c19e39ff1cd18ee9fdc54b [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Fleming5f184712011-04-08 02:10:27 -05002/*
3 * Generic PHY Management code
4 *
Andy Fleming5f184712011-04-08 02:10:27 -05005 * Copyright 2011 Freescale Semiconductor, Inc.
6 * author Andy Fleming
7 *
8 * Based loosely off of Linux's PHY Lib
9 */
Andy Fleming5f184712011-04-08 02:10:27 -050010#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -070011#include <console.h>
Simon Glassc74c8e62015-04-05 16:07:39 -060012#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060013#include <log.h>
Andy Fleming5f184712011-04-08 02:10:27 -050014#include <malloc.h>
15#include <net.h>
16#include <command.h>
17#include <miiphy.h>
18#include <phy.h>
19#include <errno.h>
Simon Glass401d1c42020-10-30 21:38:53 -060020#include <asm/global_data.h>
Marek Vasute99a6ef2024-03-18 15:57:01 +010021#include <asm-generic/gpio.h>
22#include <dm/device_compat.h>
Bin Meng676fbd32021-03-14 20:14:52 +080023#include <dm/of_extra.h>
Simon Glasscd93d622020-05-10 11:40:13 -060024#include <linux/bitops.h>
Simon Glassc05ed002020-05-10 11:40:11 -060025#include <linux/delay.h>
Troy Kisky1adb4062012-10-22 16:40:43 +000026#include <linux/err.h>
Shengzhou Liu597fe042014-04-11 16:14:17 +080027#include <linux/compiler.h>
Andy Fleming5f184712011-04-08 02:10:27 -050028
Michal Simekabbfcbe2015-05-13 13:40:40 +020029DECLARE_GLOBAL_DATA_PTR;
30
Andy Fleming5f184712011-04-08 02:10:27 -050031/* Generic PHY support and helper functions */
32
33/**
Mario Six8d631202018-01-15 11:08:27 +010034 * genphy_config_advert - sanitize and advertise auto-negotiation parameters
Andy Fleming5f184712011-04-08 02:10:27 -050035 * @phydev: target phy_device struct
36 *
37 * Description: Writes MII_ADVERTISE with the appropriate values,
38 * after sanitizing the values to make sure we only advertise
39 * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
40 * hasn't changed, and > 0 if it has changed.
41 */
Kim Phillips960d70c2012-10-29 13:34:34 +000042static int genphy_config_advert(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -050043{
44 u32 advertise;
Florian Fainellibbdcaff2016-01-13 16:59:31 +030045 int oldadv, adv, bmsr;
Andy Fleming5f184712011-04-08 02:10:27 -050046 int err, changed = 0;
47
Florian Fainellibbdcaff2016-01-13 16:59:31 +030048 /* Only allow advertising what this PHY supports */
Andy Fleming5f184712011-04-08 02:10:27 -050049 phydev->advertising &= phydev->supported;
50 advertise = phydev->advertising;
51
52 /* Setup standard advertisement */
Florian Fainellibbdcaff2016-01-13 16:59:31 +030053 adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
54 oldadv = adv;
Andy Fleming5f184712011-04-08 02:10:27 -050055
56 if (adv < 0)
57 return adv;
58
59 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
60 ADVERTISE_PAUSE_ASYM);
61 if (advertise & ADVERTISED_10baseT_Half)
62 adv |= ADVERTISE_10HALF;
63 if (advertise & ADVERTISED_10baseT_Full)
64 adv |= ADVERTISE_10FULL;
65 if (advertise & ADVERTISED_100baseT_Half)
66 adv |= ADVERTISE_100HALF;
67 if (advertise & ADVERTISED_100baseT_Full)
68 adv |= ADVERTISE_100FULL;
69 if (advertise & ADVERTISED_Pause)
70 adv |= ADVERTISE_PAUSE_CAP;
71 if (advertise & ADVERTISED_Asym_Pause)
72 adv |= ADVERTISE_PAUSE_ASYM;
Charles Coldwellde1d7862013-02-21 08:25:52 -050073 if (advertise & ADVERTISED_1000baseX_Half)
74 adv |= ADVERTISE_1000XHALF;
75 if (advertise & ADVERTISED_1000baseX_Full)
76 adv |= ADVERTISE_1000XFULL;
Andy Fleming5f184712011-04-08 02:10:27 -050077
78 if (adv != oldadv) {
79 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
80
81 if (err < 0)
82 return err;
83 changed = 1;
84 }
85
Florian Fainellibbdcaff2016-01-13 16:59:31 +030086 bmsr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
87 if (bmsr < 0)
88 return bmsr;
89
90 /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
91 * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
92 * logical 1.
93 */
94 if (!(bmsr & BMSR_ESTATEN))
95 return changed;
96
Andy Fleming5f184712011-04-08 02:10:27 -050097 /* Configure gigabit if it's supported */
Florian Fainellibbdcaff2016-01-13 16:59:31 +030098 adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
99 oldadv = adv;
100
101 if (adv < 0)
102 return adv;
103
104 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
105
Andy Fleming5f184712011-04-08 02:10:27 -0500106 if (phydev->supported & (SUPPORTED_1000baseT_Half |
107 SUPPORTED_1000baseT_Full)) {
Andy Fleming5f184712011-04-08 02:10:27 -0500108 if (advertise & SUPPORTED_1000baseT_Half)
109 adv |= ADVERTISE_1000HALF;
110 if (advertise & SUPPORTED_1000baseT_Full)
111 adv |= ADVERTISE_1000FULL;
Andy Fleming5f184712011-04-08 02:10:27 -0500112 }
113
Florian Fainellibbdcaff2016-01-13 16:59:31 +0300114 if (adv != oldadv)
115 changed = 1;
116
117 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, adv);
118 if (err < 0)
119 return err;
120
Andy Fleming5f184712011-04-08 02:10:27 -0500121 return changed;
122}
123
Andy Fleming5f184712011-04-08 02:10:27 -0500124/**
125 * genphy_setup_forced - configures/forces speed/duplex from @phydev
126 * @phydev: target phy_device struct
127 *
128 * Description: Configures MII_BMCR to force speed/duplex
129 * to the values in phydev. Assumes that the values are valid.
130 */
Kim Phillips960d70c2012-10-29 13:34:34 +0000131static int genphy_setup_forced(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500132{
133 int err;
Alexandre Messier53b0c382016-01-22 14:16:15 -0500134 int ctl = BMCR_ANRESTART;
Andy Fleming5f184712011-04-08 02:10:27 -0500135
Mario Six8d631202018-01-15 11:08:27 +0100136 phydev->pause = 0;
137 phydev->asym_pause = 0;
Andy Fleming5f184712011-04-08 02:10:27 -0500138
Mario Six8d631202018-01-15 11:08:27 +0100139 if (phydev->speed == SPEED_1000)
Andy Fleming5f184712011-04-08 02:10:27 -0500140 ctl |= BMCR_SPEED1000;
Mario Six8d631202018-01-15 11:08:27 +0100141 else if (phydev->speed == SPEED_100)
Andy Fleming5f184712011-04-08 02:10:27 -0500142 ctl |= BMCR_SPEED100;
143
Mario Six8d631202018-01-15 11:08:27 +0100144 if (phydev->duplex == DUPLEX_FULL)
Andy Fleming5f184712011-04-08 02:10:27 -0500145 ctl |= BMCR_FULLDPLX;
146
147 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
148
149 return err;
150}
151
Andy Fleming5f184712011-04-08 02:10:27 -0500152/**
153 * genphy_restart_aneg - Enable and Restart Autonegotiation
154 * @phydev: target phy_device struct
155 */
156int genphy_restart_aneg(struct phy_device *phydev)
157{
158 int ctl;
159
160 ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
161
162 if (ctl < 0)
163 return ctl;
164
165 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
166
167 /* Don't isolate the PHY if we're negotiating */
168 ctl &= ~(BMCR_ISOLATE);
169
170 ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
171
172 return ctl;
173}
174
Andy Fleming5f184712011-04-08 02:10:27 -0500175/**
176 * genphy_config_aneg - restart auto-negotiation or write BMCR
177 * @phydev: target phy_device struct
178 *
179 * Description: If auto-negotiation is enabled, we configure the
180 * advertising, and then restart auto-negotiation. If it is not
181 * enabled, then we write the BMCR.
182 */
183int genphy_config_aneg(struct phy_device *phydev)
184{
185 int result;
186
Mario Six8d631202018-01-15 11:08:27 +0100187 if (phydev->autoneg != AUTONEG_ENABLE)
Andy Fleming5f184712011-04-08 02:10:27 -0500188 return genphy_setup_forced(phydev);
189
190 result = genphy_config_advert(phydev);
191
192 if (result < 0) /* error */
193 return result;
194
195 if (result == 0) {
Mario Six8d631202018-01-15 11:08:27 +0100196 /*
197 * Advertisment hasn't changed, but maybe aneg was never on to
198 * begin with? Or maybe phy was isolated?
199 */
Andy Fleming5f184712011-04-08 02:10:27 -0500200 int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
201
202 if (ctl < 0)
203 return ctl;
204
205 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
206 result = 1; /* do restart aneg */
207 }
208
Mario Six8d631202018-01-15 11:08:27 +0100209 /*
210 * Only restart aneg if we are advertising something different
211 * than we were before.
212 */
Andy Fleming5f184712011-04-08 02:10:27 -0500213 if (result > 0)
214 result = genphy_restart_aneg(phydev);
215
216 return result;
217}
218
219/**
220 * genphy_update_link - update link status in @phydev
221 * @phydev: target phy_device struct
222 *
223 * Description: Update the value in phydev->link to reflect the
224 * current link value. In order to do this, we need to read
225 * the status register twice, keeping the second value.
226 */
227int genphy_update_link(struct phy_device *phydev)
228{
229 unsigned int mii_reg;
230
231 /*
232 * Wait if the link is up, and autonegotiation is in progress
233 * (ie - we're capable and it's not done)
234 */
235 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
236
237 /*
238 * If we already saw the link up, and it hasn't gone down, then
239 * we don't need to wait for autoneg again
240 */
241 if (phydev->link && mii_reg & BMSR_LSTATUS)
242 return 0;
243
Alexandre Messier1f9e6722016-01-22 14:16:56 -0500244 if ((phydev->autoneg == AUTONEG_ENABLE) &&
245 !(mii_reg & BMSR_ANEGCOMPLETE)) {
Andy Fleming5f184712011-04-08 02:10:27 -0500246 int i = 0;
247
248 printf("%s Waiting for PHY auto negotiation to complete",
Mario Six8d631202018-01-15 11:08:27 +0100249 phydev->dev->name);
Andy Fleming5f184712011-04-08 02:10:27 -0500250 while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
251 /*
252 * Timeout reached ?
253 */
Andre Przywaraa44ee242020-01-03 22:08:47 +0000254 if (i > (PHY_ANEG_TIMEOUT / 50)) {
Andy Fleming5f184712011-04-08 02:10:27 -0500255 printf(" TIMEOUT !\n");
256 phydev->link = 0;
Michal Simekef5e8212016-05-18 12:48:57 +0200257 return -ETIMEDOUT;
Andy Fleming5f184712011-04-08 02:10:27 -0500258 }
259
260 if (ctrlc()) {
261 puts("user interrupt!\n");
262 phydev->link = 0;
263 return -EINTR;
264 }
265
Stefan Roese27c3f702019-09-30 10:26:42 +0200266 if ((i++ % 10) == 0)
Andy Fleming5f184712011-04-08 02:10:27 -0500267 printf(".");
268
Andy Fleming5f184712011-04-08 02:10:27 -0500269 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
Stefan Roese27c3f702019-09-30 10:26:42 +0200270 mdelay(50); /* 50 ms */
Andy Fleming5f184712011-04-08 02:10:27 -0500271 }
272 printf(" done\n");
273 phydev->link = 1;
274 } else {
275 /* Read the link a second time to clear the latched state */
276 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
277
278 if (mii_reg & BMSR_LSTATUS)
279 phydev->link = 1;
280 else
281 phydev->link = 0;
282 }
283
284 return 0;
285}
286
287/*
288 * Generic function which updates the speed and duplex. If
289 * autonegotiation is enabled, it uses the AND of the link
290 * partner's advertised capabilities and our advertised
291 * capabilities. If autonegotiation is disabled, we use the
292 * appropriate bits in the control register.
293 *
294 * Stolen from Linux's mii.c and phy_device.c
295 */
Yegor Yefremove2043f52012-11-28 11:15:17 +0100296int genphy_parse_link(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500297{
298 int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
299
300 /* We're using autonegotiation */
Alexandre Messier1f9e6722016-01-22 14:16:56 -0500301 if (phydev->autoneg == AUTONEG_ENABLE) {
Andy Fleming5f184712011-04-08 02:10:27 -0500302 u32 lpa = 0;
Heiko Schocherf6d1f6e2013-07-23 15:32:36 +0200303 int gblpa = 0;
Charles Coldwellde1d7862013-02-21 08:25:52 -0500304 u32 estatus = 0;
Andy Fleming5f184712011-04-08 02:10:27 -0500305
306 /* Check for gigabit capability */
David Dueck3a530d12013-11-05 17:23:02 +0100307 if (phydev->supported & (SUPPORTED_1000baseT_Full |
308 SUPPORTED_1000baseT_Half)) {
Andy Fleming5f184712011-04-08 02:10:27 -0500309 /* We want a list of states supported by
310 * both PHYs in the link
311 */
312 gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
Heiko Schocherf6d1f6e2013-07-23 15:32:36 +0200313 if (gblpa < 0) {
Mario Six8d631202018-01-15 11:08:27 +0100314 debug("Could not read MII_STAT1000. ");
315 debug("Ignoring gigabit capability\n");
Heiko Schocherf6d1f6e2013-07-23 15:32:36 +0200316 gblpa = 0;
317 }
Andy Fleming5f184712011-04-08 02:10:27 -0500318 gblpa &= phy_read(phydev,
319 MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
320 }
321
322 /* Set the baseline so we only have to set them
323 * if they're different
324 */
325 phydev->speed = SPEED_10;
326 phydev->duplex = DUPLEX_HALF;
327
328 /* Check the gigabit fields */
329 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
330 phydev->speed = SPEED_1000;
331
332 if (gblpa & PHY_1000BTSR_1000FD)
333 phydev->duplex = DUPLEX_FULL;
334
335 /* We're done! */
336 return 0;
337 }
338
339 lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
340 lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
341
Wolfgang Denk0dcfb0f2011-09-28 21:02:43 +0200342 if (lpa & (LPA_100FULL | LPA_100HALF)) {
Andy Fleming5f184712011-04-08 02:10:27 -0500343 phydev->speed = SPEED_100;
344
Wolfgang Denk0dcfb0f2011-09-28 21:02:43 +0200345 if (lpa & LPA_100FULL)
346 phydev->duplex = DUPLEX_FULL;
347
Mario Six8d631202018-01-15 11:08:27 +0100348 } else if (lpa & LPA_10FULL) {
Andy Fleming5f184712011-04-08 02:10:27 -0500349 phydev->duplex = DUPLEX_FULL;
Mario Six8d631202018-01-15 11:08:27 +0100350 }
Charles Coldwellde1d7862013-02-21 08:25:52 -0500351
Sascha Silbe9ba30f62013-07-19 12:25:10 +0200352 /*
353 * Extended status may indicate that the PHY supports
354 * 1000BASE-T/X even though the 1000BASE-T registers
355 * are missing. In this case we can't tell whether the
356 * peer also supports it, so we only check extended
357 * status if the 1000BASE-T registers are actually
358 * missing.
359 */
360 if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
Charles Coldwellde1d7862013-02-21 08:25:52 -0500361 estatus = phy_read(phydev, MDIO_DEVAD_NONE,
362 MII_ESTATUS);
363
364 if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
365 ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
366 phydev->speed = SPEED_1000;
367 if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_TFULL))
368 phydev->duplex = DUPLEX_FULL;
369 }
370
Andy Fleming5f184712011-04-08 02:10:27 -0500371 } else {
372 u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
373
374 phydev->speed = SPEED_10;
375 phydev->duplex = DUPLEX_HALF;
376
377 if (bmcr & BMCR_FULLDPLX)
378 phydev->duplex = DUPLEX_FULL;
379
380 if (bmcr & BMCR_SPEED1000)
381 phydev->speed = SPEED_1000;
382 else if (bmcr & BMCR_SPEED100)
383 phydev->speed = SPEED_100;
384 }
385
386 return 0;
387}
388
389int genphy_config(struct phy_device *phydev)
390{
391 int val;
392 u32 features;
393
Andy Fleming5f184712011-04-08 02:10:27 -0500394 features = (SUPPORTED_TP | SUPPORTED_MII
395 | SUPPORTED_AUI | SUPPORTED_FIBRE |
396 SUPPORTED_BNC);
397
398 /* Do we support autonegotiation? */
399 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
400
401 if (val < 0)
402 return val;
403
404 if (val & BMSR_ANEGCAPABLE)
405 features |= SUPPORTED_Autoneg;
406
407 if (val & BMSR_100FULL)
408 features |= SUPPORTED_100baseT_Full;
409 if (val & BMSR_100HALF)
410 features |= SUPPORTED_100baseT_Half;
411 if (val & BMSR_10FULL)
412 features |= SUPPORTED_10baseT_Full;
413 if (val & BMSR_10HALF)
414 features |= SUPPORTED_10baseT_Half;
415
416 if (val & BMSR_ESTATEN) {
417 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
418
419 if (val < 0)
420 return val;
421
422 if (val & ESTATUS_1000_TFULL)
423 features |= SUPPORTED_1000baseT_Full;
424 if (val & ESTATUS_1000_THALF)
425 features |= SUPPORTED_1000baseT_Half;
Charles Coldwellde1d7862013-02-21 08:25:52 -0500426 if (val & ESTATUS_1000_XFULL)
427 features |= SUPPORTED_1000baseX_Full;
428 if (val & ESTATUS_1000_XHALF)
Fabio Estevam9a5dad22013-07-19 10:01:34 -0300429 features |= SUPPORTED_1000baseX_Half;
Andy Fleming5f184712011-04-08 02:10:27 -0500430 }
431
Sascha Hauer44bc3172016-01-13 16:59:32 +0300432 phydev->supported &= features;
433 phydev->advertising &= features;
Andy Fleming5f184712011-04-08 02:10:27 -0500434
435 genphy_config_aneg(phydev);
436
437 return 0;
438}
439
440int genphy_startup(struct phy_device *phydev)
441{
Michal Simekb733c272016-05-18 12:46:12 +0200442 int ret;
Andy Fleming5f184712011-04-08 02:10:27 -0500443
Michal Simekb733c272016-05-18 12:46:12 +0200444 ret = genphy_update_link(phydev);
445 if (ret)
446 return ret;
447
448 return genphy_parse_link(phydev);
Andy Fleming5f184712011-04-08 02:10:27 -0500449}
450
451int genphy_shutdown(struct phy_device *phydev)
452{
453 return 0;
454}
455
Marek Vasutf7053292023-03-19 18:03:12 +0100456U_BOOT_PHY_DRIVER(genphy) = {
Andy Fleming5f184712011-04-08 02:10:27 -0500457 .uid = 0xffffffff,
458 .mask = 0xffffffff,
459 .name = "Generic PHY",
Sascha Hauer44bc3172016-01-13 16:59:32 +0300460 .features = PHY_GBIT_FEATURES | SUPPORTED_MII |
461 SUPPORTED_AUI | SUPPORTED_FIBRE |
462 SUPPORTED_BNC,
Andy Fleming5f184712011-04-08 02:10:27 -0500463 .config = genphy_config,
464 .startup = genphy_startup,
465 .shutdown = genphy_shutdown,
466};
467
Alexey Brodkinb18acb02016-01-13 16:59:34 +0300468int phy_set_supported(struct phy_device *phydev, u32 max_speed)
469{
470 /* The default values for phydev->supported are provided by the PHY
471 * driver "features" member, we want to reset to sane defaults first
472 * before supporting higher speeds.
473 */
474 phydev->supported &= PHY_DEFAULT_FEATURES;
475
476 switch (max_speed) {
477 default:
478 return -ENOTSUPP;
479 case SPEED_1000:
480 phydev->supported |= PHY_1000BT_FEATURES;
481 /* fall through */
482 case SPEED_100:
483 phydev->supported |= PHY_100BT_FEATURES;
484 /* fall through */
485 case SPEED_10:
486 phydev->supported |= PHY_10BT_FEATURES;
487 }
488
489 return 0;
490}
491
Kim Phillips960d70c2012-10-29 13:34:34 +0000492static int phy_probe(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500493{
494 int err = 0;
495
Mario Six8d631202018-01-15 11:08:27 +0100496 phydev->advertising = phydev->drv->features;
497 phydev->supported = phydev->drv->features;
498
Andy Fleming5f184712011-04-08 02:10:27 -0500499 phydev->mmds = phydev->drv->mmds;
500
501 if (phydev->drv->probe)
502 err = phydev->drv->probe(phydev);
503
504 return err;
505}
506
Marek Behún79bef5f2022-04-07 00:33:06 +0200507static struct phy_driver *generic_for_phy(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500508{
509#ifdef CONFIG_PHYLIB_10G
Marek Behún79bef5f2022-04-07 00:33:06 +0200510 if (phydev->is_c45)
Marek Vasut20bd8e42023-03-19 18:03:13 +0100511 return ll_entry_get(struct phy_driver, gen10g, phy_driver);
Andy Fleming5f184712011-04-08 02:10:27 -0500512#endif
513
Marek Vasutf7053292023-03-19 18:03:12 +0100514 return ll_entry_get(struct phy_driver, genphy, phy_driver);
Andy Fleming5f184712011-04-08 02:10:27 -0500515}
516
Marek Behúne24b58f2022-04-07 00:33:08 +0200517static struct phy_driver *get_phy_driver(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500518{
Marek Vasut7940a932023-03-19 18:02:42 +0100519 const int ll_n_ents = ll_entry_count(struct phy_driver, phy_driver);
Andy Fleming5f184712011-04-08 02:10:27 -0500520 int phy_id = phydev->phy_id;
Marek Vasut8728d4c2023-03-19 18:03:14 +0100521 struct phy_driver *ll_entry;
522 struct phy_driver *drv;
Andy Fleming5f184712011-04-08 02:10:27 -0500523
Marek Vasut7940a932023-03-19 18:02:42 +0100524 ll_entry = ll_entry_start(struct phy_driver, phy_driver);
525 for (drv = ll_entry; drv != ll_entry + ll_n_ents; drv++)
526 if ((drv->uid & drv->mask) == (phy_id & drv->mask))
527 return drv;
528
Andy Fleming5f184712011-04-08 02:10:27 -0500529 /* If we made it here, there's no driver for this PHY */
Marek Behún79bef5f2022-04-07 00:33:06 +0200530 return generic_for_phy(phydev);
Andy Fleming5f184712011-04-08 02:10:27 -0500531}
532
Michal Simek32491162022-02-23 15:45:41 +0100533struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
Marek Behúne24b58f2022-04-07 00:33:08 +0200534 u32 phy_id, bool is_c45)
Andy Fleming5f184712011-04-08 02:10:27 -0500535{
536 struct phy_device *dev;
537
Mario Six8d631202018-01-15 11:08:27 +0100538 /*
539 * We allocate the device, and initialize the
540 * default values
541 */
Andy Fleming5f184712011-04-08 02:10:27 -0500542 dev = malloc(sizeof(*dev));
543 if (!dev) {
544 printf("Failed to allocate PHY device for %s:%d\n",
Vladimir Oltean15c49df2020-07-16 18:09:08 +0800545 bus ? bus->name : "(null bus)", addr);
Andy Fleming5f184712011-04-08 02:10:27 -0500546 return NULL;
547 }
548
549 memset(dev, 0, sizeof(*dev));
550
551 dev->duplex = -1;
Mugunthan V N26d3acd2015-09-03 15:50:21 +0530552 dev->link = 0;
Marek Behúne24b58f2022-04-07 00:33:08 +0200553 dev->interface = PHY_INTERFACE_MODE_NA;
Andy Fleming5f184712011-04-08 02:10:27 -0500554
Grygorii Strashkoeef0b8a2018-07-05 12:02:48 -0500555 dev->node = ofnode_null();
Grygorii Strashkoeef0b8a2018-07-05 12:02:48 -0500556
Andy Fleming5f184712011-04-08 02:10:27 -0500557 dev->autoneg = AUTONEG_ENABLE;
558
559 dev->addr = addr;
560 dev->phy_id = phy_id;
Pankaj Bansalb3eabd82018-11-16 06:26:18 +0000561 dev->is_c45 = is_c45;
Andy Fleming5f184712011-04-08 02:10:27 -0500562 dev->bus = bus;
563
Marek Behúne24b58f2022-04-07 00:33:08 +0200564 dev->drv = get_phy_driver(dev);
Andy Fleming5f184712011-04-08 02:10:27 -0500565
Siva Durga Prasad Paladugu05eb6a62019-03-04 16:02:11 +0100566 if (phy_probe(dev)) {
567 printf("%s, PHY probe failed\n", __func__);
568 return NULL;
569 }
Andy Fleming5f184712011-04-08 02:10:27 -0500570
Jacky Chouf146c442024-01-15 18:34:47 +0800571 if (addr >= 0 && addr < PHY_MAX_ADDR && phy_id != PHY_FIXED_ID &&
572 phy_id != PHY_NCSI_ID)
Michal Simek7b4ea2d2018-12-19 16:57:38 +0100573 bus->phymap[addr] = dev;
Andy Fleming5f184712011-04-08 02:10:27 -0500574
575 return dev;
576}
577
578/**
579 * get_phy_id - reads the specified addr for its ID.
580 * @bus: the target MII bus
581 * @addr: PHY address on the MII bus
582 * @phy_id: where to store the ID retrieved.
583 *
584 * Description: Reads the ID registers of the PHY at @addr on the
585 * @bus, stores it in @phy_id and returns zero on success.
586 */
Shengzhou Liu5707d5f2015-04-07 18:46:32 +0800587int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
Andy Fleming5f184712011-04-08 02:10:27 -0500588{
589 int phy_reg;
590
Mario Six8d631202018-01-15 11:08:27 +0100591 /*
592 * Grab the bits from PHYIR1, and put them
593 * in the upper half
594 */
Andy Fleming5f184712011-04-08 02:10:27 -0500595 phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
596
597 if (phy_reg < 0)
598 return -EIO;
599
600 *phy_id = (phy_reg & 0xffff) << 16;
601
602 /* Grab the bits from PHYIR2, and put them in the lower half */
603 phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
604
605 if (phy_reg < 0)
606 return -EIO;
607
608 *phy_id |= (phy_reg & 0xffff);
609
610 return 0;
611}
612
Troy Kisky1adb4062012-10-22 16:40:43 +0000613static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
Marek Behúne24b58f2022-04-07 00:33:08 +0200614 uint phy_mask, int devad)
Troy Kisky1adb4062012-10-22 16:40:43 +0000615{
616 u32 phy_id = 0xffffffff;
Pankaj Bansalb3eabd82018-11-16 06:26:18 +0000617 bool is_c45;
Mario Six8d631202018-01-15 11:08:27 +0100618
Troy Kisky1adb4062012-10-22 16:40:43 +0000619 while (phy_mask) {
620 int addr = ffs(phy_mask) - 1;
621 int r = get_phy_id(bus, addr, devad, &phy_id);
Alex Marginean3bf135b2019-07-05 12:28:55 +0300622
623 /*
624 * If the PHY ID is flat 0 we ignore it. There are C45 PHYs
625 * that return all 0s for C22 reads (like Aquantia AQR112) and
626 * there are C22 PHYs that return all 0s for C45 reads (like
627 * Atheros AR8035).
628 */
629 if (r == 0 && phy_id == 0)
630 goto next;
631
Troy Kisky1adb4062012-10-22 16:40:43 +0000632 /* If the PHY ID is mostly f's, we didn't find anything */
Pankaj Bansalb3eabd82018-11-16 06:26:18 +0000633 if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) {
634 is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true;
Marek Behúne24b58f2022-04-07 00:33:08 +0200635 return phy_device_create(bus, addr, phy_id, is_c45);
Pankaj Bansalb3eabd82018-11-16 06:26:18 +0000636 }
Alex Marginean3bf135b2019-07-05 12:28:55 +0300637next:
Troy Kisky1adb4062012-10-22 16:40:43 +0000638 phy_mask &= ~(1 << addr);
639 }
640 return NULL;
641}
642
643static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
Marek Behúne24b58f2022-04-07 00:33:08 +0200644 uint phy_mask)
Troy Kisky1adb4062012-10-22 16:40:43 +0000645{
646 /* If we have one, return the existing device, with new interface */
647 while (phy_mask) {
Eugeniu Roscaf5dbfc82024-01-04 05:26:23 +0100648 unsigned int addr = ffs(phy_mask) - 1;
Mario Six8d631202018-01-15 11:08:27 +0100649
Marek Behúne24b58f2022-04-07 00:33:08 +0200650 if (bus->phymap[addr])
Troy Kisky1adb4062012-10-22 16:40:43 +0000651 return bus->phymap[addr];
Marek Behúne24b58f2022-04-07 00:33:08 +0200652
Eugeniu Roscaf5dbfc82024-01-04 05:26:23 +0100653 phy_mask &= ~(1U << addr);
Troy Kisky1adb4062012-10-22 16:40:43 +0000654 }
655 return NULL;
656}
657
658static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
Marek Behúne24b58f2022-04-07 00:33:08 +0200659 uint phy_mask)
Troy Kisky1adb4062012-10-22 16:40:43 +0000660{
Troy Kisky1adb4062012-10-22 16:40:43 +0000661 struct phy_device *phydev;
Florin Chiculita9c6de502020-04-29 14:25:48 +0300662 int devad[] = {
663 /* Clause-22 */
664 MDIO_DEVAD_NONE,
665 /* Clause-45 */
666 MDIO_MMD_PMAPMD,
667 MDIO_MMD_WIS,
668 MDIO_MMD_PCS,
669 MDIO_MMD_PHYXS,
670 MDIO_MMD_VEND1,
671 };
672 int i, devad_cnt;
Troy Kisky1adb4062012-10-22 16:40:43 +0000673
Florin Chiculita9c6de502020-04-29 14:25:48 +0300674 devad_cnt = sizeof(devad)/sizeof(int);
Marek Behúne24b58f2022-04-07 00:33:08 +0200675 phydev = search_for_existing_phy(bus, phy_mask);
Troy Kisky1adb4062012-10-22 16:40:43 +0000676 if (phydev)
677 return phydev;
Florin Chiculita9c6de502020-04-29 14:25:48 +0300678 /* try different access clauses */
679 for (i = 0; i < devad_cnt; i++) {
Marek Behúne24b58f2022-04-07 00:33:08 +0200680 phydev = create_phy_by_mask(bus, phy_mask, devad[i]);
Troy Kisky1adb4062012-10-22 16:40:43 +0000681 if (IS_ERR(phydev))
682 return NULL;
683 if (phydev)
684 return phydev;
685 }
Bin Meng3e1949d2015-10-07 21:19:30 -0700686
687 debug("\n%s PHY: ", bus->name);
688 while (phy_mask) {
689 int addr = ffs(phy_mask) - 1;
Mario Six8d631202018-01-15 11:08:27 +0100690
Bin Meng3e1949d2015-10-07 21:19:30 -0700691 debug("%d ", addr);
692 phy_mask &= ~(1 << addr);
693 }
694 debug("not found\n");
Bin Meng0132b9a2015-10-07 21:19:29 -0700695
696 return NULL;
Troy Kisky1adb4062012-10-22 16:40:43 +0000697}
698
Andy Fleming5f184712011-04-08 02:10:27 -0500699/**
Mario Six8d631202018-01-15 11:08:27 +0100700 * get_phy_device - reads the specified PHY device and returns its
701 * @phy_device struct
Andy Fleming5f184712011-04-08 02:10:27 -0500702 * @bus: the target MII bus
703 * @addr: PHY address on the MII bus
704 *
705 * Description: Reads the ID registers of the PHY at @addr on the
706 * @bus, then allocates and returns the phy_device to represent it.
707 */
Marek Behúne24b58f2022-04-07 00:33:08 +0200708static struct phy_device *get_phy_device(struct mii_dev *bus, int addr)
Andy Fleming5f184712011-04-08 02:10:27 -0500709{
Marek Behúne24b58f2022-04-07 00:33:08 +0200710 return get_phy_device_by_mask(bus, 1 << addr);
Andy Fleming5f184712011-04-08 02:10:27 -0500711}
712
713int phy_reset(struct phy_device *phydev)
714{
715 int reg;
716 int timeout = 500;
717 int devad = MDIO_DEVAD_NONE;
718
Shaohui Xieddcd1f32016-01-28 15:55:46 +0800719 if (phydev->flags & PHY_FLAG_BROKEN_RESET)
720 return 0;
721
Andy Fleming5f184712011-04-08 02:10:27 -0500722#ifdef CONFIG_PHYLIB_10G
723 /* If it's 10G, we need to issue reset through one of the MMDs */
Marek Behún79bef5f2022-04-07 00:33:06 +0200724 if (phydev->is_c45) {
Andy Fleming5f184712011-04-08 02:10:27 -0500725 if (!phydev->mmds)
726 gen10g_discover_mmds(phydev);
727
728 devad = ffs(phydev->mmds) - 1;
729 }
730#endif
731
Stefan Agnera0580522015-12-09 11:21:25 -0800732 if (phy_write(phydev, devad, MII_BMCR, BMCR_RESET) < 0) {
Andy Fleming5f184712011-04-08 02:10:27 -0500733 debug("PHY reset failed\n");
734 return -1;
735 }
736
Tom Rini16199a82022-03-18 08:38:26 -0400737#if CONFIG_PHY_RESET_DELAY > 0
Andy Fleming5f184712011-04-08 02:10:27 -0500738 udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
739#endif
740 /*
741 * Poll the control register for the reset bit to go to 0 (it is
742 * auto-clearing). This should happen within 0.5 seconds per the
743 * IEEE spec.
744 */
Stefan Agnera0580522015-12-09 11:21:25 -0800745 reg = phy_read(phydev, devad, MII_BMCR);
Andy Fleming5f184712011-04-08 02:10:27 -0500746 while ((reg & BMCR_RESET) && timeout--) {
747 reg = phy_read(phydev, devad, MII_BMCR);
748
749 if (reg < 0) {
750 debug("PHY status read failed\n");
751 return -1;
752 }
753 udelay(1000);
754 }
755
756 if (reg & BMCR_RESET) {
757 puts("PHY reset timed out\n");
758 return -1;
759 }
760
761 return 0;
762}
763
764int miiphy_reset(const char *devname, unsigned char addr)
765{
766 struct mii_dev *bus = miiphy_get_dev_by_name(devname);
767 struct phy_device *phydev;
768
Marek Behúne24b58f2022-04-07 00:33:08 +0200769 phydev = get_phy_device(bus, addr);
Andy Fleming5f184712011-04-08 02:10:27 -0500770
771 return phy_reset(phydev);
772}
773
Marek Vasute99a6ef2024-03-18 15:57:01 +0100774#if CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(OF_REAL) && \
775 !IS_ENABLED(CONFIG_DM_ETH_PHY)
776int phy_gpio_reset(struct udevice *dev)
777{
778 struct ofnode_phandle_args phandle_args;
779 struct gpio_desc gpio;
780 u32 assert, deassert;
781 ofnode node;
782 int ret;
783
784 ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
785 &phandle_args);
786 /* No PHY handle is OK */
787 if (ret)
788 return 0;
789
790 node = phandle_args.node;
791 if (!ofnode_valid(node))
792 return -EINVAL;
793
794 ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio,
795 GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
796 /* No PHY reset GPIO is OK */
797 if (ret)
798 return 0;
799
800 assert = ofnode_read_u32_default(node, "reset-assert-us", 20000);
801 deassert = ofnode_read_u32_default(node, "reset-deassert-us", 1000);
802 ret = dm_gpio_set_value(&gpio, 1);
803 if (ret) {
804 dev_err(dev, "Failed assert gpio, err: %d\n", ret);
805 return ret;
806 }
807
808 udelay(assert);
809
810 ret = dm_gpio_set_value(&gpio, 0);
811 if (ret) {
812 dev_err(dev, "Failed deassert gpio, err: %d\n", ret);
813 return ret;
814 }
815
816 udelay(deassert);
817
818 return 0;
819}
820#else
821int phy_gpio_reset(struct udevice *dev)
822{
823 return 0;
824}
825#endif
826
Marek Behúne24b58f2022-04-07 00:33:08 +0200827struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask)
Andy Fleming5f184712011-04-08 02:10:27 -0500828{
Andy Fleming5f184712011-04-08 02:10:27 -0500829 /* Reset the bus */
Jörg Krause59370f32015-07-15 15:18:22 +0200830 if (bus->reset) {
Vladimir Zapolskiye3a77212011-09-05 07:24:07 +0000831 bus->reset(bus);
Andy Fleming5f184712011-04-08 02:10:27 -0500832
Jörg Krause59370f32015-07-15 15:18:22 +0200833 /* Wait 15ms to make sure the PHY has come out of hard reset */
Mario Six8d631202018-01-15 11:08:27 +0100834 mdelay(15);
Jörg Krause59370f32015-07-15 15:18:22 +0200835 }
836
Marek Behúne24b58f2022-04-07 00:33:08 +0200837 return get_phy_device_by_mask(bus, phy_mask);
Troy Kisky1adb4062012-10-22 16:40:43 +0000838}
Andy Fleming5f184712011-04-08 02:10:27 -0500839
Marek Vasut495fc042023-05-31 00:51:25 +0200840static void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
841 phy_interface_t interface)
Troy Kisky1adb4062012-10-22 16:40:43 +0000842{
Andy Fleming5f184712011-04-08 02:10:27 -0500843 /* Soft Reset the PHY */
844 phy_reset(phydev);
Bin Meng17ecfa92015-10-07 21:19:31 -0700845 if (phydev->dev && phydev->dev != dev) {
Andy Fleming5f184712011-04-08 02:10:27 -0500846 printf("%s:%d is connected to %s. Reconnecting to %s\n",
Mario Six8d631202018-01-15 11:08:27 +0100847 phydev->bus->name, phydev->addr,
848 phydev->dev->name, dev->name);
Troy Kisky1adb4062012-10-22 16:40:43 +0000849 }
Andy Fleming5f184712011-04-08 02:10:27 -0500850 phydev->dev = dev;
Marek Behúne24b58f2022-04-07 00:33:08 +0200851 phydev->interface = interface;
852 debug("%s connected to %s mode %s\n", dev->name, phydev->drv->name,
853 phy_string_for_interface(interface));
Troy Kisky1adb4062012-10-22 16:40:43 +0000854}
Andy Fleming5f184712011-04-08 02:10:27 -0500855
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530856#ifdef CONFIG_PHY_XILINX_GMII2RGMII
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530857static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
Marek Behúne24b58f2022-04-07 00:33:08 +0200858 struct udevice *dev)
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530859{
860 struct phy_device *phydev = NULL;
Michal Simek0a9f0e02021-04-26 14:26:48 +0200861 ofnode node;
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530862
Michal Simek0a9f0e02021-04-26 14:26:48 +0200863 ofnode_for_each_subnode(node, dev_ofnode(dev)) {
Bin Meng6c993812021-03-14 20:14:50 +0800864 node = ofnode_by_compatible(node, "xlnx,gmii-to-rgmii-1.0");
865 if (ofnode_valid(node)) {
Tejas Bhumkare31d7072023-09-15 10:20:43 +0530866 int gmiirgmii_phyaddr;
867
868 gmiirgmii_phyaddr = ofnode_read_u32_default(node, "reg", 0);
869 phydev = phy_device_create(bus, gmiirgmii_phyaddr,
Marek Behúne24b58f2022-04-07 00:33:08 +0200870 PHY_GMII2RGMII_ID, false);
Bin Meng6c993812021-03-14 20:14:50 +0800871 if (phydev)
872 phydev->node = node;
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530873 break;
874 }
Bin Meng6c993812021-03-14 20:14:50 +0800875
876 node = ofnode_first_subnode(node);
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530877 }
878
879 return phydev;
880}
881#endif
882
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530883#ifdef CONFIG_PHY_FIXED
Vladimir Olteand0781c92021-01-25 14:23:52 +0200884/**
885 * fixed_phy_create() - create an unconnected fixed-link pseudo-PHY device
886 * @node: OF node for the container of the fixed-link node
887 *
888 * Description: Creates a struct phy_device based on a fixed-link of_node
889 * description. Can be used without phy_connect by drivers which do not expose
890 * a UCLASS_ETH udevice.
891 */
892struct phy_device *fixed_phy_create(ofnode node)
893{
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +0800894 struct phy_device *phydev;
Vladimir Olteand0781c92021-01-25 14:23:52 +0200895 ofnode subnode;
896
Vladimir Olteand0781c92021-01-25 14:23:52 +0200897 subnode = ofnode_find_subnode(node, "fixed-link");
898 if (!ofnode_valid(subnode)) {
899 return NULL;
900 }
901
Marek Behúne24b58f2022-04-07 00:33:08 +0200902 phydev = phy_device_create(NULL, 0, PHY_FIXED_ID, false);
Heinrich Schuchardtebb8ff62022-07-11 19:40:13 +0200903 if (phydev) {
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +0800904 phydev->node = subnode;
Heinrich Schuchardtebb8ff62022-07-11 19:40:13 +0200905 phydev->interface = ofnode_read_phy_mode(node);
906 }
Marek Behúne24b58f2022-04-07 00:33:08 +0200907
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +0800908 return phydev;
Vladimir Olteand0781c92021-01-25 14:23:52 +0200909}
910
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530911static struct phy_device *phy_connect_fixed(struct mii_dev *bus,
Marek Behúne24b58f2022-04-07 00:33:08 +0200912 struct udevice *dev)
Troy Kisky1adb4062012-10-22 16:40:43 +0000913{
Vladimir Olteanf27bc8a2021-03-14 20:14:48 +0800914 ofnode node = dev_ofnode(dev), subnode;
Bin Meng676fbd32021-03-14 20:14:52 +0800915 struct phy_device *phydev = NULL;
Mario Six8d631202018-01-15 11:08:27 +0100916
Bin Meng676fbd32021-03-14 20:14:52 +0800917 if (ofnode_phy_is_fixed_link(node, &subnode)) {
Marek Behúne24b58f2022-04-07 00:33:08 +0200918 phydev = phy_device_create(bus, 0, PHY_FIXED_ID, false);
Bin Meng676fbd32021-03-14 20:14:52 +0800919 if (phydev)
920 phydev->node = subnode;
921 }
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530922
923 return phydev;
924}
Hannes Schmelzerdb40c1a2017-03-23 15:11:43 +0100925#endif
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530926
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530927struct phy_device *phy_connect(struct mii_dev *bus, int addr,
928 struct udevice *dev,
929 phy_interface_t interface)
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530930{
931 struct phy_device *phydev = NULL;
Priyanka Jain1f607892019-11-05 04:05:11 +0000932 uint mask = (addr >= 0) ? (1 << addr) : 0xffffffff;
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530933
934#ifdef CONFIG_PHY_FIXED
Marek Behúne24b58f2022-04-07 00:33:08 +0200935 phydev = phy_connect_fixed(bus, dev);
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530936#endif
Samuel Mendoza-Jonase2ffeaa2019-06-18 11:37:18 +1000937
938#ifdef CONFIG_PHY_NCSI
Samuel Mendoza-Jonas09bd3d02022-08-08 21:46:03 +0930939 if (!phydev && interface == PHY_INTERFACE_MODE_NCSI)
Marek Behúne24b58f2022-04-07 00:33:08 +0200940 phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false);
Samuel Mendoza-Jonase2ffeaa2019-06-18 11:37:18 +1000941#endif
942
Michal Simeka744a282022-02-23 15:45:42 +0100943#ifdef CONFIG_PHY_ETHERNET_ID
944 if (!phydev)
Tom Rini7f418ea2022-04-15 08:09:52 -0400945 phydev = phy_connect_phy_id(bus, dev, addr);
Michal Simeka744a282022-02-23 15:45:42 +0100946#endif
947
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530948#ifdef CONFIG_PHY_XILINX_GMII2RGMII
949 if (!phydev)
Marek Behúne24b58f2022-04-07 00:33:08 +0200950 phydev = phy_connect_gmii2rgmii(bus, dev);
Siva Durga Prasad Paladuguf41e5882018-11-27 11:49:11 +0530951#endif
Siva Durga Prasad Paladuguc256d3f2018-11-27 11:49:10 +0530952
Mario Six8d631202018-01-15 11:08:27 +0100953 if (!phydev)
Marek Behúne24b58f2022-04-07 00:33:08 +0200954 phydev = phy_find_by_mask(bus, mask);
Troy Kisky1adb4062012-10-22 16:40:43 +0000955
Troy Kisky1adb4062012-10-22 16:40:43 +0000956 if (phydev)
Marek Behúne24b58f2022-04-07 00:33:08 +0200957 phy_connect_dev(phydev, dev, interface);
Troy Kisky1adb4062012-10-22 16:40:43 +0000958 else
959 printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
Andy Fleming5f184712011-04-08 02:10:27 -0500960 return phydev;
961}
962
Timur Tabi6e5b9ac2012-07-05 10:33:18 +0000963/*
964 * Start the PHY. Returns 0 on success, or a negative error code.
965 */
Andy Fleming5f184712011-04-08 02:10:27 -0500966int phy_startup(struct phy_device *phydev)
967{
968 if (phydev->drv->startup)
Timur Tabi6e5b9ac2012-07-05 10:33:18 +0000969 return phydev->drv->startup(phydev);
Andy Fleming5f184712011-04-08 02:10:27 -0500970
971 return 0;
972}
973
Jeroen Hofstee3c6928f2014-10-08 22:57:26 +0200974__weak int board_phy_config(struct phy_device *phydev)
Andy Fleming5f184712011-04-08 02:10:27 -0500975{
Troy Kisky9fafe7d2012-02-07 14:08:49 +0000976 if (phydev->drv->config)
977 return phydev->drv->config(phydev);
Andy Fleming5f184712011-04-08 02:10:27 -0500978 return 0;
979}
980
Andy Fleming5f184712011-04-08 02:10:27 -0500981int phy_config(struct phy_device *phydev)
982{
Andy Fleming5f184712011-04-08 02:10:27 -0500983 /* Invoke an optional board-specific helper */
Michal Simek7a673f02016-05-18 14:37:23 +0200984 return board_phy_config(phydev);
Andy Fleming5f184712011-04-08 02:10:27 -0500985}
986
987int phy_shutdown(struct phy_device *phydev)
988{
989 if (phydev->drv->shutdown)
990 phydev->drv->shutdown(phydev);
991
992 return 0;
993}
Simon Glassc74c8e62015-04-05 16:07:39 -0600994
Ariel D'Alessandro087baf82022-04-12 10:31:36 -0300995/**
996 * phy_modify - Convenience function for modifying a given PHY register
997 * @phydev: the phy_device struct
998 * @devad: The MMD to read from
999 * @regnum: register number to write
1000 * @mask: bit mask of bits to clear
1001 * @set: new value of bits set in mask to write to @regnum
1002 */
1003int phy_modify(struct phy_device *phydev, int devad, int regnum, u16 mask,
1004 u16 set)
1005{
1006 int ret;
1007
1008 ret = phy_read(phydev, devad, regnum);
1009 if (ret < 0)
1010 return ret;
1011
1012 return phy_write(phydev, devad, regnum, (ret & ~mask) | set);
1013}
Ramon Fried65f22662022-06-05 03:44:15 +03001014
1015/**
1016 * phy_read - Convenience function for reading a given PHY register
1017 * @phydev: the phy_device struct
1018 * @devad: The MMD to read from
1019 * @regnum: register number to read
1020 * @return: value for success or negative errno for failure
1021 */
1022int phy_read(struct phy_device *phydev, int devad, int regnum)
1023{
1024 struct mii_dev *bus = phydev->bus;
1025
1026 if (!bus || !bus->read) {
1027 debug("%s: No bus configured\n", __func__);
1028 return -1;
1029 }
1030
1031 return bus->read(bus, phydev->addr, devad, regnum);
1032}
1033
1034/**
1035 * phy_write - Convenience function for writing a given PHY register
1036 * @phydev: the phy_device struct
1037 * @devad: The MMD to read from
1038 * @regnum: register number to write
1039 * @val: value to write to @regnum
1040 * @return: 0 for success or negative errno for failure
1041 */
1042int phy_write(struct phy_device *phydev, int devad, int regnum, u16 val)
1043{
1044 struct mii_dev *bus = phydev->bus;
1045
1046 if (!bus || !bus->write) {
1047 debug("%s: No bus configured\n", __func__);
1048 return -1;
1049 }
1050
1051 return bus->write(bus, phydev->addr, devad, regnum, val);
1052}
1053
1054/**
1055 * phy_mmd_start_indirect - Convenience function for writing MMD registers
1056 * @phydev: the phy_device struct
1057 * @devad: The MMD to read from
1058 * @regnum: register number to write
1059 * @return: None
1060 */
1061void phy_mmd_start_indirect(struct phy_device *phydev, int devad, int regnum)
1062{
1063 /* Write the desired MMD Devad */
1064 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad);
1065
1066 /* Write the desired MMD register address */
1067 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum);
1068
1069 /* Select the Function : DATA with no post increment */
1070 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL,
1071 (devad | MII_MMD_CTRL_NOINCR));
1072}
1073
1074/**
1075 * phy_read_mmd - Convenience function for reading a register
1076 * from an MMD on a given PHY.
1077 * @phydev: The phy_device struct
1078 * @devad: The MMD to read from
1079 * @regnum: The register on the MMD to read
1080 * @return: Value for success or negative errno for failure
1081 */
1082int phy_read_mmd(struct phy_device *phydev, int devad, int regnum)
1083{
1084 struct phy_driver *drv = phydev->drv;
1085
1086 if (regnum > (u16)~0 || devad > 32)
1087 return -EINVAL;
1088
1089 /* driver-specific access */
1090 if (drv->read_mmd)
1091 return drv->read_mmd(phydev, devad, regnum);
1092
1093 /* direct C45 / C22 access */
1094 if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
1095 devad == MDIO_DEVAD_NONE || !devad)
1096 return phy_read(phydev, devad, regnum);
1097
1098 /* indirect C22 access */
1099 phy_mmd_start_indirect(phydev, devad, regnum);
1100
1101 /* Read the content of the MMD's selected register */
1102 return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
1103}
1104
1105/**
1106 * phy_write_mmd - Convenience function for writing a register
1107 * on an MMD on a given PHY.
1108 * @phydev: The phy_device struct
1109 * @devad: The MMD to read from
1110 * @regnum: The register on the MMD to read
1111 * @val: value to write to @regnum
1112 * @return: 0 for success or negative errno for failure
1113 */
1114int phy_write_mmd(struct phy_device *phydev, int devad, int regnum, u16 val)
1115{
1116 struct phy_driver *drv = phydev->drv;
1117
1118 if (regnum > (u16)~0 || devad > 32)
1119 return -EINVAL;
1120
1121 /* driver-specific access */
1122 if (drv->write_mmd)
1123 return drv->write_mmd(phydev, devad, regnum, val);
1124
1125 /* direct C45 / C22 access */
1126 if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
1127 devad == MDIO_DEVAD_NONE || !devad)
1128 return phy_write(phydev, devad, regnum, val);
1129
1130 /* indirect C22 access */
1131 phy_mmd_start_indirect(phydev, devad, regnum);
1132
1133 /* Write the data into MMD's selected register */
1134 return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
1135}
1136
1137/**
1138 * phy_set_bits_mmd - Convenience function for setting bits in a register
1139 * on MMD
1140 * @phydev: the phy_device struct
1141 * @devad: the MMD containing register to modify
1142 * @regnum: register number to modify
1143 * @val: bits to set
1144 * @return: 0 for success or negative errno for failure
1145 */
1146int phy_set_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
1147{
1148 int value, ret;
1149
1150 value = phy_read_mmd(phydev, devad, regnum);
1151 if (value < 0)
1152 return value;
1153
1154 value |= val;
1155
1156 ret = phy_write_mmd(phydev, devad, regnum, value);
1157 if (ret < 0)
1158 return ret;
1159
1160 return 0;
1161}
1162
1163/**
1164 * phy_clear_bits_mmd - Convenience function for clearing bits in a register
1165 * on MMD
1166 * @phydev: the phy_device struct
1167 * @devad: the MMD containing register to modify
1168 * @regnum: register number to modify
1169 * @val: bits to clear
1170 * @return: 0 for success or negative errno for failure
1171 */
1172int phy_clear_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
1173{
1174 int value, ret;
1175
1176 value = phy_read_mmd(phydev, devad, regnum);
1177 if (value < 0)
1178 return value;
1179
1180 value &= ~val;
1181
1182 ret = phy_write_mmd(phydev, devad, regnum, value);
1183 if (ret < 0)
1184 return ret;
1185
1186 return 0;
1187}
Samuel Mendoza-Jonas09bd3d02022-08-08 21:46:03 +09301188
Marek Vasut87b75022023-03-19 18:08:07 +01001189/**
1190 * phy_modify_mmd_changed - Function for modifying a register on MMD
1191 * @phydev: the phy_device struct
1192 * @devad: the MMD containing register to modify
1193 * @regnum: register number to modify
1194 * @mask: bit mask of bits to clear
1195 * @set: new value of bits set in mask to write to @regnum
1196 *
1197 * NOTE: MUST NOT be called from interrupt context,
1198 * because the bus read/write functions may wait for an interrupt
1199 * to conclude the operation.
1200 *
1201 * Returns negative errno, 0 if there was no change, and 1 in case of change
1202 */
1203int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
1204 u16 mask, u16 set)
1205{
1206 int new, ret;
1207
1208 ret = phy_read_mmd(phydev, devad, regnum);
1209 if (ret < 0)
1210 return ret;
1211
1212 new = (ret & ~mask) | set;
1213 if (new == ret)
1214 return 0;
1215
1216 ret = phy_write_mmd(phydev, devad, regnum, new);
1217
1218 return ret < 0 ? ret : 1;
1219}
1220
1221/**
1222 * phy_modify_mmd - Convenience function for modifying a register on MMD
1223 * @phydev: the phy_device struct
1224 * @devad: the MMD containing register to modify
1225 * @regnum: register number to modify
1226 * @mask: bit mask of bits to clear
1227 * @set: new value of bits set in mask to write to @regnum
1228 *
1229 * NOTE: MUST NOT be called from interrupt context,
1230 * because the bus read/write functions may wait for an interrupt
1231 * to conclude the operation.
1232 */
1233int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
1234 u16 mask, u16 set)
1235{
1236 int ret;
1237
1238 ret = phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
1239
1240 return ret < 0 ? ret : 0;
1241}
1242
Samuel Mendoza-Jonas09bd3d02022-08-08 21:46:03 +09301243bool phy_interface_is_ncsi(void)
1244{
Marek Vasut75d28892023-03-21 18:25:54 +01001245#ifdef CONFIG_PHY_NCSI
Samuel Mendoza-Jonas09bd3d02022-08-08 21:46:03 +09301246 struct eth_pdata *pdata = dev_get_plat(eth_get_dev());
1247
1248 return pdata->phy_interface == PHY_INTERFACE_MODE_NCSI;
Marek Vasut75d28892023-03-21 18:25:54 +01001249#else
1250 return 0;
1251#endif
Samuel Mendoza-Jonas09bd3d02022-08-08 21:46:03 +09301252}