[U-Boot] [PATCH] USB: Ethernet: asix.c: Added support for AX88178 based devices
Simon Glass
sjg at chromium.org
Fri Jun 24 02:03:19 CEST 2011
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 <david at 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 <david at 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
More information about the U-Boot
mailing list