X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fmiiphyutil.c;h=9cf845f605dca3940c821976247b647847a91636;hb=a80603598cef13ab8031b514a603ef1a6169d249;hp=281f0b29e3bc1c006e312ee6188e9892b7ef5ab5;hpb=890e9413c0af74a3d74f37d9ab6d19784990fa0c;p=u-boot diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 281f0b29e3..9cf845f605 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -29,14 +29,12 @@ #include #include -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #include #include #include #include /* local debug macro */ -#define MII_DEBUG #undef MII_DEBUG #undef debug @@ -48,21 +46,45 @@ struct mii_dev { struct list_head link; - char *name; - int (*read) (char *devname, unsigned char addr, + const char *name; + int (*read) (const char *devname, unsigned char addr, unsigned char reg, unsigned short *value); - int (*write) (char *devname, unsigned char addr, + 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 list_head *entry; + struct mii_dev *dev; + + if (!devname) { + printf("NULL device name!\n"); + return NULL; + } + + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + if (strcmp(dev->name, devname) == 0) + return dev; + } + + if (!quiet) + printf("No such device: %s\n", devname); + return NULL; +} + /***************************************************************************** * * Initialize global data. Need to be called before any other miiphy routine. */ -void miiphy_init () +void miiphy_init(void) { INIT_LIST_HEAD (&mii_devs); current_mii = NULL; @@ -72,25 +94,21 @@ void miiphy_init () * * Register read and write MII access routines for the device . */ -void miiphy_register (char *name, - int (*read) (char *devname, unsigned char addr, +void miiphy_register(const char *name, + int (*read) (const char *devname, unsigned char addr, unsigned char reg, unsigned short *value), - int (*write) (char *devname, unsigned char addr, + int (*write) (const char *devname, unsigned char addr, unsigned char reg, unsigned short value)) { - struct list_head *entry; struct mii_dev *new_dev; - struct mii_dev *miidev; unsigned int name_len; + char *new_name; /* check if we have unique name */ - list_for_each (entry, &mii_devs) { - miidev = list_entry (entry, struct mii_dev, link); - if (strcmp (miidev->name, name) == 0) { - printf ("miiphy_register: non unique device name " - "'%s'\n", name); - return; - } + new_dev = miiphy_get_dev_by_name(name, 1); + if (new_dev) { + printf("miiphy_register: non unique device name '%s'\n", name); + return; } /* allocate memory */ @@ -109,9 +127,9 @@ void miiphy_register (char *name, INIT_LIST_HEAD (&new_dev->link); new_dev->read = read; new_dev->write = write; - new_dev->name = (char *)(new_dev + 1); - strncpy (new_dev->name, name, name_len); - new_dev->name[name_len] = '\0'; + new_dev->name = new_name = (char *)(new_dev + 1); + strncpy (new_name, name, name_len); + new_name[name_len] = '\0'; debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", new_dev->name, new_dev->read, new_dev->write); @@ -123,25 +141,20 @@ void miiphy_register (char *name, current_mii = new_dev; } -int miiphy_set_current_dev (char *devname) +int miiphy_set_current_dev(const char *devname) { - struct list_head *entry; struct mii_dev *dev; - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - current_mii = dev; - return 0; - } + dev = miiphy_get_dev_by_name(devname, 0); + if (dev) { + current_mii = dev; + return 0; } - printf ("No such device: %s\n", devname); return 1; } -char *miiphy_get_current_dev () +const char *miiphy_get_current_dev(void) { if (current_mii) return current_mii->name; @@ -149,6 +162,20 @@ char *miiphy_get_current_dev () return NULL; } +static struct mii_dev *miiphy_get_active_dev(const char *devname) +{ + /* If the current mii is the one we want, return it */ + if (current_mii) + if (strcmp(current_mii->name, devname) == 0) + return current_mii; + + /* Otherwise, set the active one to the one we want */ + if (miiphy_set_current_dev(devname)) + return NULL; + else + return current_mii; +} + /***************************************************************************** * * Read to variable from the PHY attached to device , @@ -157,33 +184,16 @@ char *miiphy_get_current_dev () * Returns: * 0 on success */ -int miiphy_read (char *devname, unsigned char addr, unsigned char reg, +int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { - struct list_head *entry; struct mii_dev *dev; - int found_dev = 0; - int read_ret = 0; - if (!devname) { - printf ("NULL device name!\n"); - return 1; - } - - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - found_dev = 1; - read_ret = dev->read (devname, addr, reg, value); - break; - } - } + dev = miiphy_get_active_dev(devname); + if (dev) + return dev->read(devname, addr, reg, value); - if (found_dev == 0) - printf ("No such device: %s\n", devname); - - return ((found_dev) ? read_ret : 1); + return 1; } /***************************************************************************** @@ -194,33 +204,16 @@ int miiphy_read (char *devname, unsigned char addr, unsigned char reg, * Returns: * 0 on success */ -int miiphy_write (char *devname, unsigned char addr, unsigned char reg, +int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) { - struct list_head *entry; struct mii_dev *dev; - int found_dev = 0; - int write_ret = 0; - if (!devname) { - printf ("NULL device name!\n"); - return 1; - } + dev = miiphy_get_active_dev(devname); + if (dev) + return dev->write(devname, addr, reg, value); - list_for_each (entry, &mii_devs) { - dev = list_entry (entry, struct mii_dev, link); - - if (strcmp (devname, dev->name) == 0) { - found_dev = 1; - write_ret = dev->write (devname, addr, reg, value); - break; - } - } - - if (found_dev == 0) - printf ("No such device: %s\n", devname); - - return ((found_dev) ? write_ret : 1); + return 1; } /***************************************************************************** @@ -254,38 +247,32 @@ void miiphy_listdev (void) * Returns: * 0 on success */ -int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, +int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui, unsigned char *model, unsigned char *rev) { unsigned int reg = 0; unsigned short tmp; if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) { -#ifdef DEBUG - puts ("PHY ID register 2 read failed\n"); -#endif + debug ("PHY ID register 2 read failed\n"); return (-1); } reg = tmp; -#ifdef DEBUG - printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg); -#endif + debug ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg); + if (reg == 0xFFFF) { /* No physical device present at this address */ return (-1); } if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) { -#ifdef DEBUG - puts ("PHY ID register 1 read failed\n"); -#endif + debug ("PHY ID register 1 read failed\n"); return (-1); } reg |= tmp << 16; -#ifdef DEBUG - printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg); -#endif + debug ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg); + *oui = (reg >> 10); *model = (unsigned char)((reg >> 4) & 0x0000003F); *rev = (unsigned char)(reg & 0x0000000F); @@ -298,21 +285,17 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, * Returns: * 0 on success */ -int miiphy_reset (char *devname, unsigned char addr) +int miiphy_reset(const char *devname, unsigned char addr) { unsigned short reg; - int loop_cnt; + int timeout = 500; if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { -#ifdef DEBUG - printf ("PHY status read failed\n"); -#endif + debug ("PHY status read failed\n"); return (-1); } - if (miiphy_write (devname, addr, PHY_BMCR, reg | 0x8000) != 0) { -#ifdef DEBUG - puts ("PHY reset failed\n"); -#endif + if (miiphy_write (devname, addr, PHY_BMCR, reg | PHY_BMCR_RESET) != 0) { + debug ("PHY reset failed\n"); return (-1); } #ifdef CONFIG_PHY_RESET_DELAY @@ -323,15 +306,13 @@ int miiphy_reset (char *devname, unsigned char addr) * auto-clearing). This should happen within 0.5 seconds per the * IEEE spec. */ - loop_cnt = 0; reg = 0x8000; - while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) { - if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { -# ifdef DEBUG - puts ("PHY status read failed\n"); -# endif - return (-1); + while (((reg & 0x8000) != 0) && timeout--) { + if (miiphy_read(devname, addr, PHY_BMCR, ®) != 0) { + debug("PHY status read failed\n"); + return -1; } + udelay(1000); } if ((reg & 0x8000) == 0) { return (0); @@ -346,7 +327,7 @@ int miiphy_reset (char *devname, unsigned char addr) * * Determine the ethernet speed (10/100/1000). Return 10 on error. */ -int miiphy_speed (char *devname, unsigned char addr) +int miiphy_speed(const char *devname, unsigned char addr) { u16 bmcr, anlpar; @@ -391,7 +372,7 @@ int miiphy_speed (char *devname, unsigned char addr) /* Get speed from basic control settings. */ return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET; - miiphy_read_failed: +miiphy_read_failed: printf (" read failed, assuming 10BASE-T\n"); return _10BASET; } @@ -400,7 +381,7 @@ int miiphy_speed (char *devname, unsigned char addr) * * Determine full/half duplex. Return half on error. */ -int miiphy_duplex (char *devname, unsigned char addr) +int miiphy_duplex(const char *devname, unsigned char addr) { u16 bmcr, anlpar; @@ -450,7 +431,7 @@ int miiphy_duplex (char *devname, unsigned char addr) /* Get speed from basic control settings. */ return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF; - miiphy_read_failed: +miiphy_read_failed: printf (" read failed, assuming half duplex\n"); return HALF; } @@ -460,7 +441,7 @@ int miiphy_duplex (char *devname, unsigned char addr) * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/ * 1000BASE-T, or on error. */ -int miiphy_is_1000base_x (char *devname, unsigned char addr) +int miiphy_is_1000base_x(const char *devname, unsigned char addr) { #if defined(CONFIG_PHY_GIGE) u16 exsr; @@ -476,12 +457,12 @@ int miiphy_is_1000base_x (char *devname, unsigned char addr) #endif } -#ifdef CFG_FAULT_ECHO_LINK_DOWN +#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN /***************************************************************************** * * Determine link status */ -int miiphy_link (char *devname, unsigned char addr) +int miiphy_link(const char *devname, unsigned char addr) { unsigned short reg; @@ -500,4 +481,3 @@ int miiphy_link (char *devname, unsigned char addr) } } #endif -#endif /* CONFIG_MII */