From 147271209a9d328203cf1663de17abdad23412b4 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Wed, 5 Aug 2015 17:16:59 +0200 Subject: [PATCH] net: asix: fix operation without eeprom This patch fixes operation of our on-board AX88772B chip without EEPROM but with a ethaddr coming from the regular U-Boot environment. This is a forward port of some remaining parts initially implemented by Antmicro. Signed-off-by: Marcel Ziswiler Acked-by: Marek Vasut --- drivers/usb/eth/asix.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 72ec41ea89..8a43e7c27d 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -1,6 +1,8 @@ /* * Copyright (c) 2011 The Chromium OS Authors. * + * Patched for AX88772B by Antmicro Ltd + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -64,8 +66,11 @@ AX_MEDIUM_AC | AX_MEDIUM_RE) /* AX88772 & AX88178 RX_CTL values */ -#define AX_RX_CTL_SO 0x0080 -#define AX_RX_CTL_AB 0x0008 +#define AX_RX_CTL_RH2M 0x0200 /* 32-bit aligned RX IP header */ +#define AX_RX_CTL_RH1M 0x0100 /* Enable RX header format type 1 */ +#define AX_RX_CTL_SO 0x0080 +#define AX_RX_CTL_AB 0x0008 +#define AX_RX_HEADER_DEFAULT (AX_RX_CTL_RH1M | AX_RX_CTL_RH2M) #define AX_DEFAULT_RX_CTL \ (AX_RX_CTL_SO | AX_RX_CTL_AB) @@ -92,6 +97,8 @@ #define FLAG_TYPE_AX88772B (1U << 2) #define FLAG_EEPROM_MAC (1U << 3) /* initial mac address in eeprom */ +#define ASIX_USB_VENDOR_ID 0x0b95 +#define AX88772B_USB_PRODUCT_ID 0x772b /* driver private */ struct asix_private { @@ -418,15 +425,23 @@ static int asix_basic_reset(struct ueth_data *dev) return 0; } -static int asix_init_common(struct ueth_data *dev) +static int asix_init_common(struct ueth_data *dev, uint8_t *enetaddr) { int timeout = 0; #define TIMEOUT_RESOLUTION 50 /* ms */ int link_detected; + u32 ctl = AX_DEFAULT_RX_CTL; debug("** %s()\n", __func__); - if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0) + if ((dev->pusb_dev->descriptor.idVendor == ASIX_USB_VENDOR_ID) && + (dev->pusb_dev->descriptor.idProduct == AX88772B_USB_PRODUCT_ID)) + ctl |= AX_RX_HEADER_DEFAULT; + + if (asix_write_rx_ctl(dev, ctl) < 0) + goto out_err; + + if (asix_write_hwaddr_common(dev, enetaddr) < 0) goto out_err; do { @@ -447,6 +462,12 @@ static int asix_init_common(struct ueth_data *dev) goto out_err; } + /* + * Wait some more to avoid timeout on first transfer + * (e.g. EHCI timed out on TD - token=0x8008d80) + */ + mdelay(25); + return 0; out_err: return -1; @@ -488,7 +509,7 @@ static int asix_init(struct eth_device *eth, bd_t *bd) { struct ueth_data *dev = (struct ueth_data *)eth->priv; - return asix_init_common(dev); + return asix_init_common(dev, eth->enetaddr); } static int asix_send(struct eth_device *eth, void *packet, int length) @@ -550,6 +571,12 @@ static int asix_recv(struct eth_device *eth) return -1; } + if ((dev->pusb_dev->descriptor.idVendor == + ASIX_USB_VENDOR_ID) && + (dev->pusb_dev->descriptor.idProduct == + AX88772B_USB_PRODUCT_ID)) + buf_ptr += 2; + /* Notify net stack */ net_process_received_packet(buf_ptr + sizeof(packet_len), packet_len); @@ -729,9 +756,10 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, #ifdef CONFIG_DM_ETH static int asix_eth_start(struct udevice *dev) { + struct eth_pdata *pdata = dev_get_platdata(dev); struct asix_private *priv = dev_get_priv(dev); - return asix_init_common(&priv->ueth); + return asix_init_common(&priv->ueth, pdata->enetaddr); } void asix_eth_stop(struct udevice *dev)