Hi David, Thanks for the patch - I have tried this and things still work, but I don't think I have a Belkin F5D5055 Gig USB to test with. No matter.
Please see below form comments. On Tue, May 31, 2011 at 5:58 AM, David Jander <da...@protonic.nl> wrote: > Completed command definitions copied from linux driver source. > Implemented support for AX88178 by copying and rewriting bits and pieces > from the linux asix driver. > > Signed-off-by: David Jander <da...@protonic.nl> > --- > drivers/usb/eth/asix.c | 236 > +++++++++++++++++++++++++++++++++++++++++++++--- > include/usb_ether.h | 1 + > 2 files changed, 224 insertions(+), 13 deletions(-) > > diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c > index 9b012e4..cecbc76 100644 > --- a/drivers/usb/eth/asix.c > +++ b/drivers/usb/eth/asix.c > @@ -310,7 +331,7 @@ static int mii_nway_restart(struct ueth_data *dev) > /* > * Asix callbacks > */ > -static int asix_init(struct eth_device *eth, bd_t *bd) > +static int asix_init_ax88772(struct eth_device *eth, bd_t *bd) > { > int embd_phy; > unsigned char buf[ETH_ALEN]; > @@ -419,6 +440,190 @@ out_err: > return -1; > } > > +/** > + * mii_check_media - check the MII interface for a duplex change > + * @mii: the MII interface > + * @ok_to_print: OK to print link up/down messages > + * @init_media: OK to save duplex mode in @mii > + * > + * Returns 1 if the duplex mode changed, 0 if not. > + * If the media type is forced, always returns 0. > + */ > +unsigned int mii_check_media (struct eth_device *eth, Please remove space before ( > + unsigned int ok_to_print, > + unsigned int init_media) > +{ > + int advertise, lpa, media, duplex; > + int lpa2 = 0; > + struct ueth_data *dev = (struct ueth_data *)eth->priv; > + > + /* get MII advertise and LPA values */ > + advertise = asix_mdio_read(dev, dev->phy_id, MII_ADVERTISE); > + lpa = asix_mdio_read(dev, dev->phy_id, MII_LPA); > + lpa2 = asix_mdio_read(dev, dev->phy_id, MII_STAT1000); > + > + /* figure out media and duplex from advertise and LPA values */ > + media = mii_nway_result(lpa & advertise); > + duplex = (media & ADVERTISE_FULL) ? 1 : 0; > + if (lpa2 & LPA_1000FULL) > + duplex = 1; > + > + printf("link up, %uMbps, %s-duplex, lpa 0x%04X\n", > + lpa2 & (LPA_1000FULL | LPA_1000HALF) ? 1000 : > + media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? > + 100 : 10, > + duplex ? "full" : "half", > + lpa); > + > + return 0; /* duplex did not change */ > +} > + > +static int ax88178_link_reset(struct eth_device *eth) > +{ > + u16 mode; > + struct ueth_data *dev = (struct ueth_data *)eth->priv; > + > + debug("ax88178_link_reset()\n"); > + > + mii_check_media(eth, 1, 1); > + mode = AX88178_MEDIUM_DEFAULT; > + > + /* All supported ax88178 dongles have GMII */ > + mode |= AX_MEDIUM_GM; > + mode |= AX_MEDIUM_ENCK; > + mode |= AX_MEDIUM_FD; > + > + asix_write_medium_mode(dev, mode); > + > + return 0; > +} > + > +static int asix_init_ax88178(struct eth_device *eth, bd_t *bd) > +{ > + unsigned char buf[ETH_ALEN]; > + int phymode, ledmode; > + int gpio0 = 0; > + u8 status; > + __le16 eeprom; > + struct ueth_data *dev = (struct ueth_data *)eth->priv; > + int timeout = 0; > +#define TIMEOUT_RESOLUTION 50 /* ms */ > + int link_detected; > + > + debug("** %s()\n", __func__); > + > + asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status); > + debug("GPIO Status: 0x%04x\n", status); > + > + asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); > + asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); > + asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL); > + > + debug("EEPROM index 0x17 is 0x%04x\n", eeprom); > + if (eeprom == cpu_to_le16(0xffff)) { > + printf("Error: Marvell phy not supported\n"); > + return -1; > + } else { > + phymode = le16_to_cpu(eeprom) & 7; > + ledmode = le16_to_cpu(eeprom) >> 8; > + gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1; > + } > + debug("GPIO0: %d, PhyMode: %d\n", gpio0, phymode); > + > + asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, > 40); > + if ((le16_to_cpu(eeprom) >> 8) != 1) { > + asix_write_gpio(dev, 0x003c, 30); > + asix_write_gpio(dev, 0x001c, 300); > + asix_write_gpio(dev, 0x003c, 30); > + } else { > + debug("gpio phymode == 1 path\n"); > + asix_write_gpio(dev, AX_GPIO_GPO1EN, 30); > + asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30); > + } > + > + asix_sw_reset(dev, 0); > + udelay(150000); > + > + asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); > + udelay(150000); > + > + asix_write_rx_ctl(dev, 0); > + > + /* Get the MAC address */ > + if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, > + 0, 0, ETH_ALEN, buf) < 0) { > + debug("Failed to read MAC address.\n"); > + goto out_err; > + } > + memcpy(eth->enetaddr, buf, ETH_ALEN); > + debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", > + eth->enetaddr[0], eth->enetaddr[1], > + eth->enetaddr[2], eth->enetaddr[3], > + eth->enetaddr[4], eth->enetaddr[5]); > + > + dev->phy_id = asix_get_phy_addr(dev); > + if (dev->phy_id < 0) > + debug("Failed to read phy id\n"); > + > + asix_mdio_write(dev, dev->phy_id, MII_BMCR, > + BMCR_RESET | BMCR_ANENABLE); > + asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE, > + ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); > + asix_mdio_write(dev, dev->phy_id, MII_CTRL1000, > + ADVERTISE_1000FULL); > + > + mii_nway_restart(dev); > + > + if (asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT) < 0) > + goto out_err; > + > + if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0) > + goto out_err; > + > + do { > + link_detected = asix_mdio_read(dev, dev->phy_id, MII_BMSR) & > + BMSR_LSTATUS; > + if (!link_detected) { > + if (timeout == 0) > + printf("Waiting for Ethernet connection... "); > + udelay(TIMEOUT_RESOLUTION * 1000); > + timeout += TIMEOUT_RESOLUTION; > + } > + } while (!link_detected && timeout < PHY_CONNECT_TIMEOUT); > + if (link_detected) { > + if (timeout != 0) > + printf("done.\n"); > + } else { > + printf("unable to connect.\n"); > + goto out_err; > + } > + > + udelay(50000); > + ax88178_link_reset(eth); > + udelay(50000); > + > + return 0; > +out_err: > + return -1; > +} > + > +static int asix_init(struct eth_device *eth, bd_t *bd) > +{ > + struct ueth_data *dev = (struct ueth_data *)eth->priv; > + > + switch (dev->asix_model) { > + case ASIX_MODEL_AX88772 : I don't think you should have space before : here > + return asix_init_ax88772(eth, bd); > + break; > + case ASIX_MODEL_AX88178 : and here > + return asix_init_ax88178(eth, bd); > + break; > + default: > + printf("Unsupported asix model!\n"); > + return -1; > + } > +} > + > static int asix_send(struct eth_device *eth, volatile void *packet, int > length) > { > struct ueth_data *dev = (struct ueth_data *)eth->priv; > @@ -530,19 +735,21 @@ void asix_eth_before_probe(void) > struct asix_dongle { > unsigned short vendor; > unsigned short product; > + unsigned int asix_model; > }; > > static struct asix_dongle asix_dongles[] = { > - { 0x05ac, 0x1402 }, /* Apple USB Ethernet Adapter */ > - { 0x07d1, 0x3c05 }, /* D-Link DUB-E100 H/W Ver B1 */ > - { 0x0b95, 0x772a }, /* Cables-to-Go USB Ethernet Adapter */ > - { 0x0b95, 0x7720 }, /* Trendnet TU2-ET100 V3.0R */ > - { 0x0b95, 0x1720 }, /* SMC */ > - { 0x0db0, 0xa877 }, /* MSI - ASIX 88772a */ > - { 0x13b1, 0x0018 }, /* Linksys 200M v2.1 */ > - { 0x1557, 0x7720 }, /* 0Q0 cable ethernet */ > - { 0x2001, 0x3c05 }, /* DLink DUB-E100 H/W Ver B1 Alternate */ > - { 0x0000, 0x0000 } /* END - Do not remove */ > + { 0x05ac, 0x1402, ASIX_MODEL_AX88772 }, /* Apple USB Ethernet Adapter > */ > + { 0x07d1, 0x3c05, ASIX_MODEL_AX88772 }, /* D-Link DUB-E100 H/W Ver B1 > */ > + { 0x0b95, 0x772a, ASIX_MODEL_AX88772 }, /* Cables-to-Go USB Ethernet > Adapter */ A few lines over 80cols here - can you reduce? Maybe ASIX_MODEL_AX... to MODEL_AX...? > + { 0x0b95, 0x7720, ASIX_MODEL_AX88772 }, /* Trendnet TU2-ET100 V3.0R */ > + { 0x0b95, 0x1720, ASIX_MODEL_AX88772 }, /* SMC FIXME: isn't this > AX88178? */ > + { 0x0db0, 0xa877, ASIX_MODEL_AX88772 }, /* MSI - ASIX 88772a */ > + { 0x13b1, 0x0018, ASIX_MODEL_AX88772 }, /* Linksys 200M v2.1 */ > + { 0x1557, 0x7720, ASIX_MODEL_AX88772 }, /* 0Q0 cable ethernet */ > + { 0x2001, 0x3c05, ASIX_MODEL_AX88772 }, /* DLink DUB-E100 H/W Ver B1 > Alternate */ > + { 0x050d, 0x5055, ASIX_MODEL_AX88178 }, /* Belkin F5D5055 Gig USB */ > + { 0x0000, 0x0000, 0 } /* END - Do not remove */ > }; > > /* Probe to see if a new device is actually an asix device */ > @@ -569,9 +776,12 @@ int asix_eth_probe(struct usb_device *dev, unsigned int > ifnum, > > memset(ss, 0, sizeof(struct ueth_data)); > > + ss->asix_model = asix_dongles[i].asix_model; > + > /* At this point, we know we've got a live one */ > - debug("\n\nUSB Ethernet device detected: %#04x:%#04x\n", > - dev->descriptor.idVendor, dev->descriptor.idProduct); > + debug("\n\nUSB Ethernet device detected: %#04x:%#04x model AX88%s\n", > + dev->descriptor.idVendor, dev->descriptor.idProduct, > + ss->asix_model? "772" : "178"); Space before ? ... Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot