The Asix driver takes the link down during init() and then brings it back up.
This commit changes this so that if a link has already been established
successfully we simply check that the link is still good.

Also fix up asix_halt() to actually halt RX on the interface. Previously this
was not done, so the device would continue to operate evern when halted,
violating a U-Boot requirement.

This reduces the delay between successive network commands.
Signed-off-by: Simon Glass <s...@chromium.org>
---
Changes in v2: None

 drivers/usb/eth/asix.c |   40 ++++++++++++++++++++++++++++++++--------
 include/usb_ether.h    |    1 +
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c
index 75ec8f7..a991fea 100644
--- a/drivers/usb/eth/asix.c
+++ b/drivers/usb/eth/asix.c
@@ -84,6 +84,7 @@
 
 #define AX_DEFAULT_RX_CTL      \
        (AX_RX_CTL_SO | AX_RX_CTL_AB)
+#define AX_DISABLE_RX_CTL      AX_RX_CTL_AB
 
 /* GPIO 2 toggles */
 #define AX_GPIO_GPO2EN         0x10    /* GPIO2 Output enable */
@@ -410,17 +411,16 @@ static int asix_basic_reset(struct ueth_data *dev)
        return 0;
 }
 
-/*
- * Asix callbacks
- */
-static int asix_init(struct eth_device *eth, bd_t *bd)
+static int full_init(struct eth_device *eth)
 {
-       struct ueth_data        *dev = (struct ueth_data *)eth->priv;
-       int timeout = 0;
-#define TIMEOUT_RESOLUTION 50  /* ms */
-       int link_detected;
+       struct ueth_data *dev = (struct ueth_data *)eth->priv;
 
        debug("** %s()\n", __func__);
+       if (asix_basic_reset(dev))
+               goto out_err;
+
+       if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
+               goto out_err;
 
        dev->phy_id = asix_get_phy_addr(dev);
        if (dev->phy_id < 0)
@@ -446,6 +446,25 @@ static int asix_init(struct eth_device *eth, bd_t *bd)
                debug("Write IPG,IPG1,IPG2 failed\n");
                goto out_err;
        }
+       return 0;
+out_err:
+       return -1;
+}
+
+/*
+ * Asix callbacks
+ */
+static int asix_init(struct eth_device *eth, bd_t *bd)
+{
+       struct ueth_data *dev = (struct ueth_data *)eth->priv;
+       int timeout = 0;
+#define TIMEOUT_RESOLUTION 50  /* ms */
+       int link_detected;
+
+       debug("** %s()\n", __func__);
+
+       if (!dev->has_been_running && full_init(eth))
+               return -1;
 
        if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
                goto out_err;
@@ -467,6 +486,7 @@ static int asix_init(struct eth_device *eth, bd_t *bd)
                printf("unable to connect.\n");
                goto out_err;
        }
+       dev->has_been_running = 1;
 
        return 0;
 out_err:
@@ -571,7 +591,11 @@ static int asix_recv(struct eth_device *eth)
 
 static void asix_halt(struct eth_device *eth)
 {
+       struct ueth_data *dev = (struct ueth_data *)eth->priv;
+
+       /* Disable packet reception */
        debug("** %s()\n", __func__);
+       (void)asix_write_rx_ctl(dev, AX_DISABLE_RX_CTL);
 }
 
 /*
diff --git a/include/usb_ether.h b/include/usb_ether.h
index 7c7aecb..6145210 100644
--- a/include/usb_ether.h
+++ b/include/usb_ether.h
@@ -49,6 +49,7 @@ struct ueth_data {
        unsigned char   subclass;               /* as in overview */
        unsigned char   protocol;               /* .............. */
        unsigned char   irqinterval;    /* Intervall for IRQ Pipe */
+       char has_been_running;          /* PHY already inited */
 
        /* driver private */
        void *dev_priv;
-- 
1.7.7.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to