X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Feepro100.c;h=738146e6618e08e05656ca28ab879e38e0ff6fb2;hb=81735b2568cf634d601c0d4a1bbc3a3882bc8eda;hp=0054e87571fb6819159979f01a10430c950ed6db;hpb=c570b2fdf5da2e05c2707a112a1238913b6c4c23;p=oweals%2Fu-boot.git diff --git a/drivers/eepro100.c b/drivers/eepro100.c index 0054e87571..738146e661 100644 --- a/drivers/eepro100.c +++ b/drivers/eepro100.c @@ -26,11 +26,12 @@ #include #include #include +#include #undef DEBUG -#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_EEPRO100) +#if defined(CONFIG_CMD_NET) \ + && defined(CONFIG_NET_MULTI) && defined(CONFIG_EEPRO100) /* Ethernet chip registers. */ @@ -271,49 +272,124 @@ static inline void OUTL (struct eth_device *dev, int command, u_long addr) *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command); } -#if defined (CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) static inline int INL (struct eth_device *dev, u_long addr) { return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase)); } -int miiphy_read (unsigned char addr, - unsigned char reg, - unsigned short *value) +static int get_phyreg (struct eth_device *dev, unsigned char addr, + unsigned char reg, unsigned short *value) { - int cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - - struct eth_device *dev = eth_get_dev (); + int cmd; + int timeout = 50; + /* read requested data */ + cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); OUTL (dev, cmd, SCBCtrlMDI); do { + udelay(1000); cmd = INL (dev, SCBCtrlMDI); - } while (!(cmd & (1 << 28))); + } while (!(cmd & (1 << 28)) && (--timeout)); + + if (timeout == 0) + return -1; *value = (unsigned short) (cmd & 0xffff); return 0; } -int miiphy_write (unsigned char addr, - unsigned char reg, - unsigned short value) +static int set_phyreg (struct eth_device *dev, unsigned char addr, + unsigned char reg, unsigned short value) { - int cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - - struct eth_device *dev = eth_get_dev (); + int cmd; + int timeout = 50; + /* write requested data */ + cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); OUTL (dev, cmd | value, SCBCtrlMDI); - while (!(INL (dev, SCBCtrlMDI) & (1 << 28))); + while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) + udelay(1000); + + if (timeout == 0) + return -1; return 0; } -#endif /* (CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) */ - /* Wait for the chip get the command. - */ +/* Check if given phyaddr is valid, i.e. there is a PHY connected. + * Do this by checking model value field from ID2 register. + */ +static struct eth_device* verify_phyaddr (char *devname, unsigned char addr) +{ + struct eth_device *dev; + unsigned short value; + unsigned char model; + + dev = eth_get_dev_by_name(devname); + if (dev == NULL) { + printf("%s: no such device\n", devname); + return NULL; + } + + /* read id2 register */ + if (get_phyreg(dev, addr, PHY_PHYIDR2, &value) != 0) { + printf("%s: mii read timeout!\n", devname); + return NULL; + } + + /* get model */ + model = (unsigned char)((value >> 4) & 0x003f); + + if (model == 0) { + printf("%s: no PHY at address %d\n", devname, addr); + return NULL; + } + + return dev; +} + +static int eepro100_miiphy_read (char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + struct eth_device *dev; + + dev = verify_phyaddr(devname, addr); + if (dev == NULL) + return -1; + + if (get_phyreg(dev, addr, reg, value) != 0) { + printf("%s: mii read timeout!\n", devname); + return -1; + } + + return 0; +} + +static int eepro100_miiphy_write (char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + struct eth_device *dev; + + dev = verify_phyaddr(devname, addr); + if (dev == NULL) + return -1; + + if (set_phyreg(dev, addr, reg, value) != 0) { + printf("%s: mii write timeout!\n", devname); + return -1; + } + + return 0; +} + +#endif + +/* Wait for the chip get the command. +*/ static int wait_for_eepro100 (struct eth_device *dev) { int i; @@ -386,6 +462,12 @@ int eepro100_initialize (bd_t * bis) eth_register (dev); +#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) + /* register mii command access routines */ + miiphy_register(dev->name, + eepro100_miiphy_read, eepro100_miiphy_write); +#endif + card_number++; /* Set the latency timer for value.