net: asix: Fix ASIX 88772B with driver model
[pandora-u-boot.git] / drivers / usb / eth / asix.c
index 72ec41e..1c6e967 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
  *
+ * Patched for AX88772B by Antmicro Ltd <www.antmicro.com>
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
@@ -8,6 +10,7 @@
 #include <dm.h>
 #include <usb.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <linux/mii.h>
 #include "usb_ether.h"
 
@@ -418,7 +421,7 @@ 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 */
@@ -429,6 +432,9 @@ static int asix_init_common(struct ueth_data *dev)
        if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
                goto out_err;
 
+       if (asix_write_hwaddr_common(dev, enetaddr) < 0)
+               goto out_err;
+
        do {
                link_detected = asix_mdio_read(dev, dev->phy_id, MII_BMSR) &
                        BMSR_LSTATUS;
@@ -447,6 +453,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 +500,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)
@@ -729,9 +741,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)