X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fmiiphyutil.c;h=2cc23b410a22bf38ed1d55eecf4f4915fa8e2082;hb=784ab7c545d25288a82216d18e2b0ca3beae470b;hp=6944ea773031bf5927c6f3676aa89bed0e53ae18;hpb=16a5323833cc3536fac4c6aa3c6c4cf681679952;p=u-boot diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 6944ea7730..2cc23b410a 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -44,22 +45,13 @@ #define debug(fmt, args...) #endif /* MII_DEBUG */ -struct mii_dev { - struct list_head link; - const char *name; - int (*read)(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); - int (*write)(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value); -}; - static struct list_head mii_devs; static struct mii_dev *current_mii; /* * Lookup the mii_dev struct by the registered device name. */ -static struct mii_dev *miiphy_get_dev_by_name(const char *devname, int quiet) +struct mii_dev *miiphy_get_dev_by_name(const char *devname) { struct list_head *entry; struct mii_dev *dev; @@ -75,8 +67,6 @@ static struct mii_dev *miiphy_get_dev_by_name(const char *devname, int quiet) return dev; } - if (!quiet) - printf("No such device: %s\n", devname); return NULL; } @@ -90,9 +80,29 @@ void miiphy_init(void) current_mii = NULL; } +static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + unsigned short val; + int ret; + struct legacy_mii_dev *ldev = bus->priv; + + ret = ldev->read(bus->name, addr, reg, &val); + + return ret ? -1 : (int)val; +} + +static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad, + int reg, u16 val) +{ + struct legacy_mii_dev *ldev = bus->priv; + + return ldev->write(bus->name, addr, reg, val); +} + /***************************************************************************** * * Register read and write MII access routines for the device . + * This API is now deprecated. Please use mdio_alloc and mdio_register, instead. */ void miiphy_register(const char *name, int (*read)(const char *devname, unsigned char addr, @@ -101,38 +111,38 @@ void miiphy_register(const char *name, unsigned char reg, unsigned short value)) { struct mii_dev *new_dev; - unsigned int name_len; - char *new_name; + struct legacy_mii_dev *ldev; + + BUG_ON(strlen(name) >= MDIO_NAME_LEN); /* check if we have unique name */ - new_dev = miiphy_get_dev_by_name(name, 1); + new_dev = miiphy_get_dev_by_name(name); if (new_dev) { printf("miiphy_register: non unique device name '%s'\n", name); return; } /* allocate memory */ - name_len = strlen(name); - new_dev = - (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1); + new_dev = mdio_alloc(); + ldev = malloc(sizeof(*ldev)); - if (new_dev == NULL) { + if (new_dev == NULL || ldev == NULL) { printf("miiphy_register: cannot allocate memory for '%s'\n", name); return; } - memset(new_dev, 0, sizeof(struct mii_dev) + name_len); /* initalize mii_dev struct fields */ - INIT_LIST_HEAD(&new_dev->link); - new_dev->read = read; - new_dev->write = write; - new_dev->name = new_name = (char *)(new_dev + 1); - strncpy(new_name, name, name_len); - new_name[name_len] = '\0'; + new_dev->read = legacy_miiphy_read; + new_dev->write = legacy_miiphy_write; + strncpy(new_dev->name, name, MDIO_NAME_LEN); + new_dev->name[MDIO_NAME_LEN - 1] = 0; + ldev->read = read; + ldev->write = write; + new_dev->priv = ldev; debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", - new_dev->name, new_dev->read, new_dev->write); + new_dev->name, ldev->read, ldev->write); /* add it to the list */ list_add_tail(&new_dev->link, &mii_devs); @@ -141,19 +151,110 @@ void miiphy_register(const char *name, current_mii = new_dev; } +struct mii_dev *mdio_alloc(void) +{ + struct mii_dev *bus; + + bus = malloc(sizeof(*bus)); + if (!bus) + return bus; + + memset(bus, 0, sizeof(*bus)); + + /* initalize mii_dev struct fields */ + INIT_LIST_HEAD(&bus->link); + + return bus; +} + +int mdio_register(struct mii_dev *bus) +{ + if (!bus || !bus->name || !bus->read || !bus->write) + return -1; + + /* check if we have unique name */ + if (miiphy_get_dev_by_name(bus->name)) { + printf("mdio_register: non unique device name '%s'\n", + bus->name); + return -1; + } + + /* add it to the list */ + list_add_tail(&bus->link, &mii_devs); + + if (!current_mii) + current_mii = bus; + + return 0; +} + +void mdio_list_devices(void) +{ + struct list_head *entry; + + list_for_each(entry, &mii_devs) { + int i; + struct mii_dev *bus = list_entry(entry, struct mii_dev, link); + + printf("%s:\n", bus->name); + + for (i = 0; i < PHY_MAX_ADDR; i++) { + struct phy_device *phydev = bus->phymap[i]; + + if (phydev) { + printf("%d - %s", i, phydev->drv->name); + + if (phydev->dev) + printf(" <--> %s\n", phydev->dev->name); + else + printf("\n"); + } + } + } +} + int miiphy_set_current_dev(const char *devname) { struct mii_dev *dev; - dev = miiphy_get_dev_by_name(devname, 0); + dev = miiphy_get_dev_by_name(devname); if (dev) { current_mii = dev; return 0; } + printf("No such device: %s\n", devname); + return 1; } +struct mii_dev *mdio_get_current_dev(void) +{ + return current_mii; +} + +struct phy_device *mdio_phydev_for_ethname(const char *ethname) +{ + struct list_head *entry; + struct mii_dev *bus; + + list_for_each(entry, &mii_devs) { + int i; + bus = list_entry(entry, struct mii_dev, link); + + for (i = 0; i < PHY_MAX_ADDR; i++) { + if (!bus->phymap[i] || !bus->phymap[i]->dev) + continue; + + if (strcmp(bus->phymap[i]->dev->name, ethname) == 0) + return bus->phymap[i]; + } + } + + printf("%s is not a known ethernet\n", ethname); + return NULL; +} + const char *miiphy_get_current_dev(void) { if (current_mii) @@ -181,19 +282,27 @@ static struct mii_dev *miiphy_get_active_dev(const char *devname) * Read to variable from the PHY attached to device , * use PHY address and register . * + * This API is deprecated. Use phy_read on a phy_device found via phy_connect + * * Returns: * 0 on success */ int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { - struct mii_dev *dev; + struct mii_dev *bus; + int ret; - dev = miiphy_get_active_dev(devname); - if (dev) - return dev->read(devname, addr, reg, value); + bus = miiphy_get_active_dev(devname); + if (!bus) + return 1; - return 1; + ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg); + if (ret < 0) + return 1; + + *value = (unsigned short)ret; + return 0; } /***************************************************************************** @@ -201,17 +310,19 @@ int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, * Write to the PHY attached to device , * use PHY address and register . * + * This API is deprecated. Use phy_write on a phy_device found by phy_connect + * * Returns: * 0 on success */ int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) { - struct mii_dev *dev; + struct mii_dev *bus; - dev = miiphy_get_active_dev(devname); - if (dev) - return dev->write(devname, addr, reg, value); + bus = miiphy_get_active_dev(devname); + if (bus) + return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value); return 1; } @@ -244,6 +355,8 @@ void miiphy_listdev(void) * Model: 6 bits (unsigned char) * Revision: 4 bits (unsigned char) * + * This API is deprecated. + * * Returns: * 0 on success */ @@ -279,9 +392,13 @@ int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui, return 0; } +#ifndef CONFIG_PHYLIB /***************************************************************************** * * Reset the PHY. + * + * This API is deprecated. Use PHYLIB. + * * Returns: * 0 on success */ @@ -322,6 +439,7 @@ int miiphy_reset(const char *devname, unsigned char addr) } return 0; } +#endif /* !PHYLIB */ /***************************************************************************** * @@ -352,7 +470,6 @@ int miiphy_speed(const char *devname, unsigned char addr) if (btsr != 0xFFFF && (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) return _1000BASET; - #endif /* CONFIG_PHY_GIGE */ /* Check Basic Management Control Register first. */