]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/glsdk-u-boot.git/blob - drivers/net/phy/phy.c
d0ed7666ed98cbeccee364b38dc31f77cd6ce0d5
[glsdk/glsdk-u-boot.git] / drivers / net / phy / phy.c
1 /*
2  * Generic PHY Management code
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *
19  *
20  * Copyright 2011 Freescale Semiconductor, Inc.
21  * author Andy Fleming
22  *
23  * Based loosely off of Linux's PHY Lib
24  */
26 #include <config.h>
27 #include <common.h>
28 #include <malloc.h>
29 #include <net.h>
30 #include <command.h>
31 #include <miiphy.h>
32 #include <phy.h>
33 #include <errno.h>
34 #include <linux/err.h>
36 /* Generic PHY support and helper functions */
38 /**
39  * genphy_config_advert - sanitize and advertise auto-negotation parameters
40  * @phydev: target phy_device struct
41  *
42  * Description: Writes MII_ADVERTISE with the appropriate values,
43  *   after sanitizing the values to make sure we only advertise
44  *   what is supported.  Returns < 0 on error, 0 if the PHY's advertisement
45  *   hasn't changed, and > 0 if it has changed.
46  */
47 static int genphy_config_advert(struct phy_device *phydev)
48 {
49         u32 advertise;
50         int oldadv, adv;
51         int err, changed = 0;
53         /* Only allow advertising what
54          * this PHY supports */
55         phydev->advertising &= phydev->supported;
56         advertise = phydev->advertising;
58         /* Setup standard advertisement */
59         oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
61         if (adv < 0)
62                 return adv;
64         adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
65                  ADVERTISE_PAUSE_ASYM);
66         if (advertise & ADVERTISED_10baseT_Half)
67                 adv |= ADVERTISE_10HALF;
68         if (advertise & ADVERTISED_10baseT_Full)
69                 adv |= ADVERTISE_10FULL;
70         if (advertise & ADVERTISED_100baseT_Half)
71                 adv |= ADVERTISE_100HALF;
72         if (advertise & ADVERTISED_100baseT_Full)
73                 adv |= ADVERTISE_100FULL;
74         if (advertise & ADVERTISED_Pause)
75                 adv |= ADVERTISE_PAUSE_CAP;
76         if (advertise & ADVERTISED_Asym_Pause)
77                 adv |= ADVERTISE_PAUSE_ASYM;
79         if (adv != oldadv) {
80                 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
82                 if (err < 0)
83                         return err;
84                 changed = 1;
85         }
87         /* Configure gigabit if it's supported */
88         if (phydev->supported & (SUPPORTED_1000baseT_Half |
89                                 SUPPORTED_1000baseT_Full)) {
90                 oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
92                 if (adv < 0)
93                         return adv;
95                 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
96                 if (advertise & SUPPORTED_1000baseT_Half)
97                         adv |= ADVERTISE_1000HALF;
98                 if (advertise & SUPPORTED_1000baseT_Full)
99                         adv |= ADVERTISE_1000FULL;
101                 if (adv != oldadv) {
102                         err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
103                                         adv);
105                         if (err < 0)
106                                 return err;
107                         changed = 1;
108                 }
109         }
111         return changed;
115 /**
116  * genphy_setup_forced - configures/forces speed/duplex from @phydev
117  * @phydev: target phy_device struct
118  *
119  * Description: Configures MII_BMCR to force speed/duplex
120  *   to the values in phydev. Assumes that the values are valid.
121  */
122 static int genphy_setup_forced(struct phy_device *phydev)
124         int err;
125         int ctl = 0;
127         phydev->pause = phydev->asym_pause = 0;
129         if (SPEED_1000 == phydev->speed)
130                 ctl |= BMCR_SPEED1000;
131         else if (SPEED_100 == phydev->speed)
132                 ctl |= BMCR_SPEED100;
134         if (DUPLEX_FULL == phydev->duplex)
135                 ctl |= BMCR_FULLDPLX;
137         err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
139         return err;
143 /**
144  * genphy_restart_aneg - Enable and Restart Autonegotiation
145  * @phydev: target phy_device struct
146  */
147 int genphy_restart_aneg(struct phy_device *phydev)
149         int ctl;
151         ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
153         if (ctl < 0)
154                 return ctl;
156         ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
158         /* Don't isolate the PHY if we're negotiating */
159         ctl &= ~(BMCR_ISOLATE);
161         ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
163         return ctl;
167 /**
168  * genphy_config_aneg - restart auto-negotiation or write BMCR
169  * @phydev: target phy_device struct
170  *
171  * Description: If auto-negotiation is enabled, we configure the
172  *   advertising, and then restart auto-negotiation.  If it is not
173  *   enabled, then we write the BMCR.
174  */
175 int genphy_config_aneg(struct phy_device *phydev)
177         int result;
179         if (AUTONEG_ENABLE != phydev->autoneg)
180                 return genphy_setup_forced(phydev);
182         result = genphy_config_advert(phydev);
184         if (result < 0) /* error */
185                 return result;
187         if (result == 0) {
188                 /* Advertisment hasn't changed, but maybe aneg was never on to
189                  * begin with?  Or maybe phy was isolated? */
190                 int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
192                 if (ctl < 0)
193                         return ctl;
195                 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
196                         result = 1; /* do restart aneg */
197         }
199         /* Only restart aneg if we are advertising something different
200          * than we were before.  */
201         if (result > 0)
202                 result = genphy_restart_aneg(phydev);
204         return result;
207 /**
208  * genphy_update_link - update link status in @phydev
209  * @phydev: target phy_device struct
210  *
211  * Description: Update the value in phydev->link to reflect the
212  *   current link value.  In order to do this, we need to read
213  *   the status register twice, keeping the second value.
214  */
215 int genphy_update_link(struct phy_device *phydev)
217         unsigned int mii_reg;
219         /*
220          * Wait if the link is up, and autonegotiation is in progress
221          * (ie - we're capable and it's not done)
222          */
223         mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
225         /*
226          * If we already saw the link up, and it hasn't gone down, then
227          * we don't need to wait for autoneg again
228          */
229         if (phydev->link && mii_reg & BMSR_LSTATUS)
230                 return 0;
232         if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
233                 int i = 0;
235                 printf("%s Waiting for PHY auto negotiation to complete",
236                         phydev->dev->name);
237                 while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
238                         /*
239                          * Timeout reached ?
240                          */
241                         if (i > PHY_ANEG_TIMEOUT) {
242                                 printf(" TIMEOUT !\n");
243                                 phydev->link = 0;
244                                 return 0;
245                         }
247                         if (ctrlc()) {
248                                 puts("user interrupt!\n");
249                                 phydev->link = 0;
250                                 return -EINTR;
251                         }
253                         if ((i++ % 500) == 0)
254                                 printf(".");
256                         udelay(1000);   /* 1 ms */
257                         mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
258                 }
259                 printf(" done\n");
260                 phydev->link = 1;
261         } else {
262                 /* Read the link a second time to clear the latched state */
263                 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
265                 if (mii_reg & BMSR_LSTATUS)
266                         phydev->link = 1;
267                 else
268                         phydev->link = 0;
269         }
271         return 0;
274 /*
275  * Generic function which updates the speed and duplex.  If
276  * autonegotiation is enabled, it uses the AND of the link
277  * partner's advertised capabilities and our advertised
278  * capabilities.  If autonegotiation is disabled, we use the
279  * appropriate bits in the control register.
280  *
281  * Stolen from Linux's mii.c and phy_device.c
282  */
283 static int genphy_parse_link(struct phy_device *phydev)
285         int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
287         /* We're using autonegotiation */
288         if (mii_reg & BMSR_ANEGCAPABLE) {
289                 u32 lpa = 0;
290                 u32 gblpa = 0;
292                 /* Check for gigabit capability */
293                 if (mii_reg & BMSR_ERCAP) {
294                         /* We want a list of states supported by
295                          * both PHYs in the link
296                          */
297                         gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
298                         gblpa &= phy_read(phydev,
299                                         MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
300                 }
302                 /* Set the baseline so we only have to set them
303                  * if they're different
304                  */
305                 phydev->speed = SPEED_10;
306                 phydev->duplex = DUPLEX_HALF;
308                 /* Check the gigabit fields */
309                 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
310                         phydev->speed = SPEED_1000;
312                         if (gblpa & PHY_1000BTSR_1000FD)
313                                 phydev->duplex = DUPLEX_FULL;
315                         /* We're done! */
316                         return 0;
317                 }
319                 lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
320                 lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
322                 if (lpa & (LPA_100FULL | LPA_100HALF)) {
323                         phydev->speed = SPEED_100;
325                         if (lpa & LPA_100FULL)
326                                 phydev->duplex = DUPLEX_FULL;
328                 } else if (lpa & LPA_10FULL)
329                         phydev->duplex = DUPLEX_FULL;
330         } else {
331                 u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
333                 phydev->speed = SPEED_10;
334                 phydev->duplex = DUPLEX_HALF;
336                 if (bmcr & BMCR_FULLDPLX)
337                         phydev->duplex = DUPLEX_FULL;
339                 if (bmcr & BMCR_SPEED1000)
340                         phydev->speed = SPEED_1000;
341                 else if (bmcr & BMCR_SPEED100)
342                         phydev->speed = SPEED_100;
343         }
345         return 0;
348 int genphy_config(struct phy_device *phydev)
350         int val;
351         u32 features;
353         /* For now, I'll claim that the generic driver supports
354          * all possible port types */
355         features = (SUPPORTED_TP | SUPPORTED_MII
356                         | SUPPORTED_AUI | SUPPORTED_FIBRE |
357                         SUPPORTED_BNC);
359         /* Do we support autonegotiation? */
360         val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
362         if (val < 0)
363                 return val;
365         if (val & BMSR_ANEGCAPABLE)
366                 features |= SUPPORTED_Autoneg;
368         if (val & BMSR_100FULL)
369                 features |= SUPPORTED_100baseT_Full;
370         if (val & BMSR_100HALF)
371                 features |= SUPPORTED_100baseT_Half;
372         if (val & BMSR_10FULL)
373                 features |= SUPPORTED_10baseT_Full;
374         if (val & BMSR_10HALF)
375                 features |= SUPPORTED_10baseT_Half;
377         if (val & BMSR_ESTATEN) {
378                 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
380                 if (val < 0)
381                         return val;
383                 if (val & ESTATUS_1000_TFULL)
384                         features |= SUPPORTED_1000baseT_Full;
385                 if (val & ESTATUS_1000_THALF)
386                         features |= SUPPORTED_1000baseT_Half;
387         }
389         phydev->supported = features;
390         phydev->advertising = features;
392         genphy_config_aneg(phydev);
394         return 0;
397 int genphy_startup(struct phy_device *phydev)
399         genphy_update_link(phydev);
400         genphy_parse_link(phydev);
402         return 0;
405 int genphy_shutdown(struct phy_device *phydev)
407         return 0;
410 static struct phy_driver genphy_driver = {
411         .uid            = 0xffffffff,
412         .mask           = 0xffffffff,
413         .name           = "Generic PHY",
414         .features       = 0,
415         .config         = genphy_config,
416         .startup        = genphy_startup,
417         .shutdown       = genphy_shutdown,
418 };
420 static LIST_HEAD(phy_drivers);
422 int phy_init(void)
424 #ifdef CONFIG_PHY_ATHEROS
425         phy_atheros_init();
426 #endif
427 #ifdef CONFIG_PHY_BROADCOM
428         phy_broadcom_init();
429 #endif
430 #ifdef CONFIG_PHY_DAVICOM
431         phy_davicom_init();
432 #endif
433 #ifdef CONFIG_PHY_LXT
434         phy_lxt_init();
435 #endif
436 #ifdef CONFIG_PHY_MARVELL
437         phy_marvell_init();
438 #endif
439 #ifdef CONFIG_PHY_MICREL
440         phy_micrel_init();
441 #endif
442 #ifdef CONFIG_PHY_NATSEMI
443         phy_natsemi_init();
444 #endif
445 #ifdef CONFIG_PHY_REALTEK
446         phy_realtek_init();
447 #endif
448 #ifdef CONFIG_PHY_SMSC
449         phy_smsc_init();
450 #endif
451 #ifdef CONFIG_PHY_TERANETICS
452         phy_teranetics_init();
453 #endif
454 #ifdef CONFIG_PHY_VITESSE
455         phy_vitesse_init();
456 #endif
458         return 0;
461 int phy_register(struct phy_driver *drv)
463         INIT_LIST_HEAD(&drv->list);
464         list_add_tail(&drv->list, &phy_drivers);
466         return 0;
469 static int phy_probe(struct phy_device *phydev)
471         int err = 0;
473         phydev->advertising = phydev->supported = phydev->drv->features;
474         phydev->mmds = phydev->drv->mmds;
476         if (phydev->drv->probe)
477                 err = phydev->drv->probe(phydev);
479         return err;
482 static struct phy_driver *generic_for_interface(phy_interface_t interface)
484 #ifdef CONFIG_PHYLIB_10G
485         if (is_10g_interface(interface))
486                 return &gen10g_driver;
487 #endif
489         return &genphy_driver;
492 static struct phy_driver *get_phy_driver(struct phy_device *phydev,
493                                 phy_interface_t interface)
495         struct list_head *entry;
496         int phy_id = phydev->phy_id;
497         struct phy_driver *drv = NULL;
499         list_for_each(entry, &phy_drivers) {
500                 drv = list_entry(entry, struct phy_driver, list);
501                 if ((drv->uid & drv->mask) == (phy_id & drv->mask))
502                         return drv;
503         }
505         /* If we made it here, there's no driver for this PHY */
506         return generic_for_interface(interface);
509 static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
510                                             int phy_id,
511                                             phy_interface_t interface)
513         struct phy_device *dev;
515         /* We allocate the device, and initialize the
516          * default values */
517         dev = malloc(sizeof(*dev));
518         if (!dev) {
519                 printf("Failed to allocate PHY device for %s:%d\n",
520                         bus->name, addr);
521                 return NULL;
522         }
524         memset(dev, 0, sizeof(*dev));
526         dev->duplex = -1;
527         dev->link = 1;
528         dev->interface = interface;
530         dev->autoneg = AUTONEG_ENABLE;
532         dev->addr = addr;
533         dev->phy_id = phy_id;
534         dev->bus = bus;
536         dev->drv = get_phy_driver(dev, interface);
538         phy_probe(dev);
540         bus->phymap[addr] = dev;
542         return dev;
545 /**
546  * get_phy_id - reads the specified addr for its ID.
547  * @bus: the target MII bus
548  * @addr: PHY address on the MII bus
549  * @phy_id: where to store the ID retrieved.
550  *
551  * Description: Reads the ID registers of the PHY at @addr on the
552  *   @bus, stores it in @phy_id and returns zero on success.
553  */
554 static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
556         int phy_reg;
558         /* Grab the bits from PHYIR1, and put them
559          * in the upper half */
560         phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
562         if (phy_reg < 0)
563                 return -EIO;
565         *phy_id = (phy_reg & 0xffff) << 16;
567         /* Grab the bits from PHYIR2, and put them in the lower half */
568         phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
570         if (phy_reg < 0)
571                 return -EIO;
573         *phy_id |= (phy_reg & 0xffff);
575         return 0;
578 static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
579                 unsigned phy_mask, int devad, phy_interface_t interface)
581         u32 phy_id = 0xffffffff;
582         while (phy_mask) {
583                 int addr = ffs(phy_mask) - 1;
584                 int r = get_phy_id(bus, addr, devad, &phy_id);
585                 if (r < 0)
586                         return ERR_PTR(r);
587                 /* If the PHY ID is mostly f's, we didn't find anything */
588                 if ((phy_id & 0x1fffffff) != 0x1fffffff)
589                         return phy_device_create(bus, addr, phy_id, interface);
590                 phy_mask &= ~(1 << addr);
591         }
592         return NULL;
595 static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
596                 unsigned phy_mask, phy_interface_t interface)
598         /* If we have one, return the existing device, with new interface */
599         while (phy_mask) {
600                 int addr = ffs(phy_mask) - 1;
601                 if (bus->phymap[addr]) {
602                         bus->phymap[addr]->interface = interface;
603                         return bus->phymap[addr];
604                 }
605                 phy_mask &= ~(1 << addr);
606         }
607         return NULL;
610 static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
611                 unsigned phy_mask, phy_interface_t interface)
613         int i;
614         struct phy_device *phydev;
616         phydev = search_for_existing_phy(bus, phy_mask, interface);
617         if (phydev)
618                 return phydev;
619         /* Try Standard (ie Clause 22) access */
620         /* Otherwise we have to try Clause 45 */
621         for (i = 0; i < 5; i++) {
622                 phydev = create_phy_by_mask(bus, phy_mask,
623                                 i ? i : MDIO_DEVAD_NONE, interface);
624                 if (IS_ERR(phydev))
625                         return NULL;
626                 if (phydev)
627                         return phydev;
628         }
629         printf("Phy not found\n");
630         return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
633 /**
634  * get_phy_device - reads the specified PHY device and returns its @phy_device struct
635  * @bus: the target MII bus
636  * @addr: PHY address on the MII bus
637  *
638  * Description: Reads the ID registers of the PHY at @addr on the
639  *   @bus, then allocates and returns the phy_device to represent it.
640  */
641 static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
642                                          phy_interface_t interface)
644         return get_phy_device_by_mask(bus, 1 << addr, interface);
647 int phy_reset(struct phy_device *phydev)
649         int reg;
650         int timeout = 500;
651         int devad = MDIO_DEVAD_NONE;
653 #ifdef CONFIG_PHYLIB_10G
654         /* If it's 10G, we need to issue reset through one of the MMDs */
655         if (is_10g_interface(phydev->interface)) {
656                 if (!phydev->mmds)
657                         gen10g_discover_mmds(phydev);
659                 devad = ffs(phydev->mmds) - 1;
660         }
661 #endif
663         reg = phy_read(phydev, devad, MII_BMCR);
664         if (reg < 0) {
665                 debug("PHY status read failed\n");
666                 return -1;
667         }
669         reg |= BMCR_RESET;
671         if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
672                 debug("PHY reset failed\n");
673                 return -1;
674         }
676 #ifdef CONFIG_PHY_RESET_DELAY
677         udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
678 #endif
679         /*
680          * Poll the control register for the reset bit to go to 0 (it is
681          * auto-clearing).  This should happen within 0.5 seconds per the
682          * IEEE spec.
683          */
684         while ((reg & BMCR_RESET) && timeout--) {
685                 reg = phy_read(phydev, devad, MII_BMCR);
687                 if (reg < 0) {
688                         debug("PHY status read failed\n");
689                         return -1;
690                 }
691                 udelay(1000);
692         }
694         if (reg & BMCR_RESET) {
695                 puts("PHY reset timed out\n");
696                 return -1;
697         }
699         return 0;
702 int miiphy_reset(const char *devname, unsigned char addr)
704         struct mii_dev *bus = miiphy_get_dev_by_name(devname);
705         struct phy_device *phydev;
707         /*
708          * miiphy_reset was only used on standard PHYs, so we'll fake it here.
709          * If later code tries to connect with the right interface, this will
710          * be corrected by get_phy_device in phy_connect()
711          */
712         phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
714         return phy_reset(phydev);
717 struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
718                 phy_interface_t interface)
720         /* Reset the bus */
721         if (bus->reset)
722                 bus->reset(bus);
724         /* Wait 15ms to make sure the PHY has come out of hard reset */
725         udelay(15000);
726         return get_phy_device_by_mask(bus, phy_mask, interface);
729 void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
731         /* Soft Reset the PHY */
732         phy_reset(phydev);
733         if (phydev->dev) {
734                 printf("%s:%d is connected to %s.  Reconnecting to %s\n",
735                                 phydev->bus->name, phydev->addr,
736                                 phydev->dev->name, dev->name);
737         }
738         phydev->dev = dev;
739         debug("%s connected to %s\n", dev->name, phydev->drv->name);
742 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
743                 struct eth_device *dev, phy_interface_t interface)
745         struct phy_device *phydev;
747         phydev = phy_find_by_mask(bus, 1 << addr, interface);
748         if (phydev)
749                 phy_connect_dev(phydev, dev);
750         else
751                 printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
752         return phydev;
755 /*
756  * Start the PHY.  Returns 0 on success, or a negative error code.
757  */
758 int phy_startup(struct phy_device *phydev)
760         if (phydev->drv->startup)
761                 return phydev->drv->startup(phydev);
763         return 0;
766 static int __board_phy_config(struct phy_device *phydev)
768         if (phydev->drv->config)
769                 return phydev->drv->config(phydev);
770         return 0;
773 int board_phy_config(struct phy_device *phydev)
774         __attribute__((weak, alias("__board_phy_config")));
776 int phy_config(struct phy_device *phydev)
778         /* Invoke an optional board-specific helper */
779         board_phy_config(phydev);
781         return 0;
784 int phy_shutdown(struct phy_device *phydev)
786         if (phydev->drv->shutdown)
787                 phydev->drv->shutdown(phydev);
789         return 0;