Merge branch '2021-09-24-arm64-optimized-str-funcs' into next
[platform/kernel/u-boot.git] / common / miiphyutil.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2001
4  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
5  */
6
7 /*
8  * This provides a bit-banged interface to the ethernet MII management
9  * channel.
10  */
11
12 #include <common.h>
13 #include <dm.h>
14 #include <log.h>
15 #include <miiphy.h>
16 #include <phy.h>
17 #include <linux/delay.h>
18
19 #include <asm/types.h>
20 #include <linux/list.h>
21 #include <malloc.h>
22 #include <net.h>
23
24 /* local debug macro */
25 #undef MII_DEBUG
26
27 #undef debug
28 #ifdef MII_DEBUG
29 #define debug(fmt, args...)     printf(fmt, ##args)
30 #else
31 #define debug(fmt, args...)
32 #endif /* MII_DEBUG */
33
34 static struct list_head mii_devs;
35 static struct mii_dev *current_mii;
36
37 /*
38  * Lookup the mii_dev struct by the registered device name.
39  */
40 struct mii_dev *miiphy_get_dev_by_name(const char *devname)
41 {
42         struct list_head *entry;
43         struct mii_dev *dev;
44
45         if (!devname) {
46                 printf("NULL device name!\n");
47                 return NULL;
48         }
49
50         list_for_each(entry, &mii_devs) {
51                 dev = list_entry(entry, struct mii_dev, link);
52                 if (strcmp(dev->name, devname) == 0)
53                         return dev;
54         }
55
56         return NULL;
57 }
58
59 /*****************************************************************************
60  *
61  * Initialize global data. Need to be called before any other miiphy routine.
62  */
63 void miiphy_init(void)
64 {
65         INIT_LIST_HEAD(&mii_devs);
66         current_mii = NULL;
67 }
68
69 struct mii_dev *mdio_alloc(void)
70 {
71         struct mii_dev *bus;
72
73         bus = malloc(sizeof(*bus));
74         if (!bus)
75                 return bus;
76
77         memset(bus, 0, sizeof(*bus));
78
79         /* initalize mii_dev struct fields */
80         INIT_LIST_HEAD(&bus->link);
81
82         return bus;
83 }
84
85 void mdio_free(struct mii_dev *bus)
86 {
87         free(bus);
88 }
89
90 int mdio_register(struct mii_dev *bus)
91 {
92         if (!bus || !bus->read || !bus->write)
93                 return -1;
94
95         /* check if we have unique name */
96         if (miiphy_get_dev_by_name(bus->name)) {
97                 printf("mdio_register: non unique device name '%s'\n",
98                         bus->name);
99                 return -1;
100         }
101
102         /* add it to the list */
103         list_add_tail(&bus->link, &mii_devs);
104
105         if (!current_mii)
106                 current_mii = bus;
107
108         return 0;
109 }
110
111 int mdio_register_seq(struct mii_dev *bus, int seq)
112 {
113         int ret;
114
115         /* Setup a unique name for each mdio bus */
116         ret = snprintf(bus->name, MDIO_NAME_LEN, "eth%d", seq);
117         if (ret < 0)
118                 return ret;
119
120         return mdio_register(bus);
121 }
122
123 int mdio_unregister(struct mii_dev *bus)
124 {
125         if (!bus)
126                 return 0;
127
128         /* delete it from the list */
129         list_del(&bus->link);
130
131         if (current_mii == bus)
132                 current_mii = NULL;
133
134         return 0;
135 }
136
137 void mdio_list_devices(void)
138 {
139         struct list_head *entry;
140
141         list_for_each(entry, &mii_devs) {
142                 int i;
143                 struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
144
145                 printf("%s:\n", bus->name);
146
147                 for (i = 0; i < PHY_MAX_ADDR; i++) {
148                         struct phy_device *phydev = bus->phymap[i];
149
150                         if (phydev) {
151                                 printf("%x - %s", i, phydev->drv->name);
152
153                                 if (phydev->dev)
154                                         printf(" <--> %s\n", phydev->dev->name);
155                                 else
156                                         printf("\n");
157                         }
158                 }
159         }
160 }
161
162 int miiphy_set_current_dev(const char *devname)
163 {
164         struct mii_dev *dev;
165
166         dev = miiphy_get_dev_by_name(devname);
167         if (dev) {
168                 current_mii = dev;
169                 return 0;
170         }
171
172         printf("No such device: %s\n", devname);
173
174         return 1;
175 }
176
177 struct mii_dev *mdio_get_current_dev(void)
178 {
179         return current_mii;
180 }
181
182 struct list_head *mdio_get_list_head(void)
183 {
184         return &mii_devs;
185 }
186
187 struct phy_device *mdio_phydev_for_ethname(const char *ethname)
188 {
189         struct list_head *entry;
190         struct mii_dev *bus;
191
192         list_for_each(entry, &mii_devs) {
193                 int i;
194                 bus = list_entry(entry, struct mii_dev, link);
195
196                 for (i = 0; i < PHY_MAX_ADDR; i++) {
197                         if (!bus->phymap[i] || !bus->phymap[i]->dev)
198                                 continue;
199
200                         if (strcmp(bus->phymap[i]->dev->name, ethname) == 0)
201                                 return bus->phymap[i];
202                 }
203         }
204
205         printf("%s is not a known ethernet\n", ethname);
206         return NULL;
207 }
208
209 const char *miiphy_get_current_dev(void)
210 {
211         if (current_mii)
212                 return current_mii->name;
213
214         return NULL;
215 }
216
217 static struct mii_dev *miiphy_get_active_dev(const char *devname)
218 {
219         /* If the current mii is the one we want, return it */
220         if (current_mii)
221                 if (strcmp(current_mii->name, devname) == 0)
222                         return current_mii;
223
224         /* Otherwise, set the active one to the one we want */
225         if (miiphy_set_current_dev(devname))
226                 return NULL;
227         else
228                 return current_mii;
229 }
230
231 /*****************************************************************************
232  *
233  * Read to variable <value> from the PHY attached to device <devname>,
234  * use PHY address <addr> and register <reg>.
235  *
236  * This API is deprecated. Use phy_read on a phy_device found via phy_connect
237  *
238  * Returns:
239  *   0 on success
240  */
241 int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
242                  unsigned short *value)
243 {
244         struct mii_dev *bus;
245         int ret;
246
247         bus = miiphy_get_active_dev(devname);
248         if (!bus)
249                 return 1;
250
251         ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
252         if (ret < 0)
253                 return 1;
254
255         *value = (unsigned short)ret;
256         return 0;
257 }
258
259 /*****************************************************************************
260  *
261  * Write <value> to the PHY attached to device <devname>,
262  * use PHY address <addr> and register <reg>.
263  *
264  * This API is deprecated. Use phy_write on a phy_device found by phy_connect
265  *
266  * Returns:
267  *   0 on success
268  */
269 int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
270                   unsigned short value)
271 {
272         struct mii_dev *bus;
273
274         bus = miiphy_get_active_dev(devname);
275         if (bus)
276                 return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
277
278         return 1;
279 }
280
281 /*****************************************************************************
282  *
283  * Print out list of registered MII capable devices.
284  */
285 void miiphy_listdev(void)
286 {
287         struct list_head *entry;
288         struct mii_dev *dev;
289
290         puts("MII devices: ");
291         list_for_each(entry, &mii_devs) {
292                 dev = list_entry(entry, struct mii_dev, link);
293                 printf("'%s' ", dev->name);
294         }
295         puts("\n");
296
297         if (current_mii)
298                 printf("Current device: '%s'\n", current_mii->name);
299 }
300
301 /*****************************************************************************
302  *
303  * Read the OUI, manufacture's model number, and revision number.
304  *
305  * OUI:     22 bits (unsigned int)
306  * Model:    6 bits (unsigned char)
307  * Revision: 4 bits (unsigned char)
308  *
309  * This API is deprecated.
310  *
311  * Returns:
312  *   0 on success
313  */
314 int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
315                  unsigned char *model, unsigned char *rev)
316 {
317         unsigned int reg = 0;
318         unsigned short tmp;
319
320         if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
321                 debug("PHY ID register 2 read failed\n");
322                 return -1;
323         }
324         reg = tmp;
325
326         debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);
327
328         if (reg == 0xFFFF) {
329                 /* No physical device present at this address */
330                 return -1;
331         }
332
333         if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
334                 debug("PHY ID register 1 read failed\n");
335                 return -1;
336         }
337         reg |= tmp << 16;
338         debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
339
340         *oui = (reg >> 10);
341         *model = (unsigned char)((reg >> 4) & 0x0000003F);
342         *rev = (unsigned char)(reg & 0x0000000F);
343         return 0;
344 }
345
346 #ifndef CONFIG_PHYLIB
347 /*****************************************************************************
348  *
349  * Reset the PHY.
350  *
351  * This API is deprecated. Use PHYLIB.
352  *
353  * Returns:
354  *   0 on success
355  */
356 int miiphy_reset(const char *devname, unsigned char addr)
357 {
358         unsigned short reg;
359         int timeout = 500;
360
361         if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
362                 debug("PHY status read failed\n");
363                 return -1;
364         }
365         if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
366                 debug("PHY reset failed\n");
367                 return -1;
368         }
369 #ifdef CONFIG_PHY_RESET_DELAY
370         udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
371 #endif
372         /*
373          * Poll the control register for the reset bit to go to 0 (it is
374          * auto-clearing).  This should happen within 0.5 seconds per the
375          * IEEE spec.
376          */
377         reg = 0x8000;
378         while (((reg & 0x8000) != 0) && timeout--) {
379                 if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
380                         debug("PHY status read failed\n");
381                         return -1;
382                 }
383                 udelay(1000);
384         }
385         if ((reg & 0x8000) == 0) {
386                 return 0;
387         } else {
388                 puts("PHY reset timed out\n");
389                 return -1;
390         }
391         return 0;
392 }
393 #endif /* !PHYLIB */
394
395 /*****************************************************************************
396  *
397  * Determine the ethernet speed (10/100/1000).  Return 10 on error.
398  */
399 int miiphy_speed(const char *devname, unsigned char addr)
400 {
401         u16 bmcr, anlpar, adv;
402
403 #if defined(CONFIG_PHY_GIGE)
404         u16 btsr;
405
406         /*
407          * Check for 1000BASE-X.  If it is supported, then assume that the speed
408          * is 1000.
409          */
410         if (miiphy_is_1000base_x(devname, addr))
411                 return _1000BASET;
412
413         /*
414          * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
415          */
416         /* Check for 1000BASE-T. */
417         if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
418                 printf("PHY 1000BT status");
419                 goto miiphy_read_failed;
420         }
421         if (btsr != 0xFFFF &&
422                         (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)))
423                 return _1000BASET;
424 #endif /* CONFIG_PHY_GIGE */
425
426         /* Check Basic Management Control Register first. */
427         if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
428                 printf("PHY speed");
429                 goto miiphy_read_failed;
430         }
431         /* Check if auto-negotiation is on. */
432         if (bmcr & BMCR_ANENABLE) {
433                 /* Get auto-negotiation results. */
434                 if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
435                         printf("PHY AN speed");
436                         goto miiphy_read_failed;
437                 }
438
439                 if (miiphy_read(devname, addr, MII_ADVERTISE, &adv)) {
440                         puts("PHY AN adv speed");
441                         goto miiphy_read_failed;
442                 }
443                 return ((anlpar & adv) & LPA_100) ? _100BASET : _10BASET;
444         }
445         /* Get speed from basic control settings. */
446         return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
447
448 miiphy_read_failed:
449         printf(" read failed, assuming 10BASE-T\n");
450         return _10BASET;
451 }
452
453 /*****************************************************************************
454  *
455  * Determine full/half duplex.  Return half on error.
456  */
457 int miiphy_duplex(const char *devname, unsigned char addr)
458 {
459         u16 bmcr, anlpar, adv;
460
461 #if defined(CONFIG_PHY_GIGE)
462         u16 btsr;
463
464         /* Check for 1000BASE-X. */
465         if (miiphy_is_1000base_x(devname, addr)) {
466                 /* 1000BASE-X */
467                 if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
468                         printf("1000BASE-X PHY AN duplex");
469                         goto miiphy_read_failed;
470                 }
471         }
472         /*
473          * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
474          */
475         /* Check for 1000BASE-T. */
476         if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
477                 printf("PHY 1000BT status");
478                 goto miiphy_read_failed;
479         }
480         if (btsr != 0xFFFF) {
481                 if (btsr & PHY_1000BTSR_1000FD) {
482                         return FULL;
483                 } else if (btsr & PHY_1000BTSR_1000HD) {
484                         return HALF;
485                 }
486         }
487 #endif /* CONFIG_PHY_GIGE */
488
489         /* Check Basic Management Control Register first. */
490         if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
491                 puts("PHY duplex");
492                 goto miiphy_read_failed;
493         }
494         /* Check if auto-negotiation is on. */
495         if (bmcr & BMCR_ANENABLE) {
496                 /* Get auto-negotiation results. */
497                 if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
498                         puts("PHY AN duplex");
499                         goto miiphy_read_failed;
500                 }
501
502                 if (miiphy_read(devname, addr, MII_ADVERTISE, &adv)) {
503                         puts("PHY AN adv duplex");
504                         goto miiphy_read_failed;
505                 }
506                 return ((anlpar & adv) & (LPA_10FULL | LPA_100FULL)) ?
507                     FULL : HALF;
508         }
509         /* Get speed from basic control settings. */
510         return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
511
512 miiphy_read_failed:
513         printf(" read failed, assuming half duplex\n");
514         return HALF;
515 }
516
517 /*****************************************************************************
518  *
519  * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
520  * 1000BASE-T, or on error.
521  */
522 int miiphy_is_1000base_x(const char *devname, unsigned char addr)
523 {
524 #if defined(CONFIG_PHY_GIGE)
525         u16 exsr;
526
527         if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
528                 printf("PHY extended status read failed, assuming no "
529                         "1000BASE-X\n");
530                 return 0;
531         }
532         return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
533 #else
534         return 0;
535 #endif
536 }
537
538 #ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
539 /*****************************************************************************
540  *
541  * Determine link status
542  */
543 int miiphy_link(const char *devname, unsigned char addr)
544 {
545         unsigned short reg;
546
547         /* dummy read; needed to latch some phys */
548         (void)miiphy_read(devname, addr, MII_BMSR, &reg);
549         if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
550                 puts("MII_BMSR read failed, assuming no link\n");
551                 return 0;
552         }
553
554         /* Determine if a link is active */
555         if ((reg & BMSR_LSTATUS) != 0) {
556                 return 1;
557         } else {
558                 return 0;
559         }
560 }
561 #endif