Patchwork [U-Boot,01/11] usb: net: asix: Do a fast init if link already established

login
register
mail settings
Submitter Simon Glass
Date Dec. 13, 2012, 1:55 a.m.
Message ID <1355363731-10103-2-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/205710/
State Superseded, archived
Delegated to: Marek Vasut
Headers show

Comments

Simon Glass - Dec. 13, 2012, 1:55 a.m.
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 <sjg@chromium.org>
---
 drivers/usb/eth/asix.c |   40 ++++++++++++++++++++++++++++++++--------
 include/usb_ether.h    |    1 +
 2 files changed, 33 insertions(+), 8 deletions(-)
Marek Vasut - Dec. 13, 2012, 5:26 p.m.
Dear Simon Glass,

> 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 <sjg@chromium.org>

Joe, this is yours. Gimme a go/no-go and an Ack ;-)

Best regards,
Marek Vasut
Joe Hershberger - Dec. 15, 2012, 7:28 a.m.
Hi Simon,

On Wed, Dec 12, 2012 at 7:55 PM, Simon Glass <sjg@chromium.org> wrote:
> 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 <sjg@chromium.org>
> ---
>  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;

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

Patch

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;