]> git.sur5r.net Git - u-boot/blobdiff - drivers/usb/eth/asix.c
Merge branch 'u-boot-sunxi/master' into 'u-boot-arm/master'
[u-boot] / drivers / usb / eth / asix.c
index 604d720ea516e5aa081a99d5079a40eeff59af4b..6557055e02b8ea130cc592b6425af0e54b0ca8d8 100644 (file)
@@ -1,22 +1,7 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
- * See file CREDITS for list of people who contributed to this
- * project.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #define FLAG_NONE                      0
 #define FLAG_TYPE_AX88172      (1U << 0)
 #define FLAG_TYPE_AX88772      (1U << 1)
-#define FLAG_EEPROM_MAC                (1U << 2) /* initial mac address in eeprom */
+#define FLAG_TYPE_AX88772B     (1U << 2)
+#define FLAG_EEPROM_MAC                (1U << 3) /* initial mac address in eeprom */
 
 /* local vars */
 static int curr_eth_dev; /* index for name of next device detected */
@@ -406,46 +392,40 @@ static int asix_basic_reset(struct ueth_data *dev)
        rx_ctl = asix_read_rx_ctl(dev);
        debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 
-       return 0;
-}
-
-/*
- * 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__);
-
        dev->phy_id = asix_get_phy_addr(dev);
        if (dev->phy_id < 0)
                debug("Failed to read phy id\n");
 
-       if (asix_sw_reset(dev, AX_SWRESET_PRL) < 0)
-               goto out_err;
-
-       if (asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL) < 0)
-               goto out_err;
-
        asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
        asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
                        ADVERTISE_ALL | ADVERTISE_CSMA);
        mii_nway_restart(dev);
 
        if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
-               goto out_err;
+               return -1;
 
        if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
                                AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
                                AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
                debug("Write IPG,IPG1,IPG2 failed\n");
-               goto out_err;
+               return -1;
        }
 
+       return 0;
+}
+
+/*
+ * 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 (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
                goto out_err;
 
@@ -488,8 +468,6 @@ static int asix_send(struct eth_device *eth, void *packet, int length)
 
        memcpy(msg, &packet_len, sizeof(packet_len));
        memcpy(msg + sizeof(packet_len), (void *)packet, length);
-       if (length & 1)
-               length++;
 
        err = usb_bulk_msg(dev->pusb_dev,
                                usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
@@ -543,13 +521,13 @@ static int asix_recv(struct eth_device *eth)
                }
                memcpy(&packet_len, buf_ptr, sizeof(packet_len));
                le32_to_cpus(&packet_len);
-               if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) {
+               if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
                        debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
-                             packet_len, (packet_len >> 16) ^ 0xffff,
-                             packet_len & 0xffff);
+                             packet_len, (~packet_len >> 16) & 0x7ff,
+                             packet_len & 0x7ff);
                        return -1;
                }
-               packet_len = packet_len & 0xffff;
+               packet_len = packet_len & 0x7ff;
                if (packet_len > actual_len - sizeof(packet_len)) {
                        debug("Rx: too large packet: %d\n", packet_len);
                        return -1;
@@ -587,9 +565,10 @@ struct asix_dongle {
        int flags;
 };
 
-static const struct asix_dongle const asix_dongles[] = {
+static const struct asix_dongle asix_dongles[] = {
        { 0x05ac, 0x1402, FLAG_TYPE_AX88772 },  /* Apple USB Ethernet Adapter */
        { 0x07d1, 0x3c05, FLAG_TYPE_AX88772 },  /* D-Link DUB-E100 H/W Ver B1 */
+       { 0x2001, 0x1a02, FLAG_TYPE_AX88772 },  /* D-Link DUB-E100 H/W Ver C1 */
        /* Cables-to-Go USB Ethernet Adapter */
        { 0x0b95, 0x772a, FLAG_TYPE_AX88772 },
        { 0x0b95, 0x7720, FLAG_TYPE_AX88772 },  /* Trendnet TU2-ET100 V3.0R */
@@ -599,6 +578,8 @@ static const struct asix_dongle const asix_dongles[] = {
        { 0x1557, 0x7720, FLAG_TYPE_AX88772 },  /* 0Q0 cable ethernet */
        /* DLink DUB-E100 H/W Ver B1 Alternate */
        { 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
+       /* ASIX 88772B */
+       { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
        { 0x0000, 0x0000, FLAG_NONE }   /* END - Do not remove */
 };
 
@@ -608,6 +589,7 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum,
 {
        struct usb_interface *iface;
        struct usb_interface_descriptor *iface_desc;
+       int ep_in_found = 0, ep_out_found = 0;
        int i;
 
        /* let's examine the device now */
@@ -651,13 +633,20 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum,
                /* is it an BULK endpoint? */
                if ((iface->ep_desc[i].bmAttributes &
                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
-                       if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
-                               ss->ep_in = iface->ep_desc[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
-                       else
-                               ss->ep_out =
-                                       iface->ep_desc[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
+                       u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
+                       if (ep_addr & USB_DIR_IN) {
+                               if (!ep_in_found) {
+                                       ss->ep_in = ep_addr &
+                                               USB_ENDPOINT_NUMBER_MASK;
+                                       ep_in_found = 1;
+                               }
+                       } else {
+                               if (!ep_out_found) {
+                                       ss->ep_out = ep_addr &
+                                               USB_ENDPOINT_NUMBER_MASK;
+                                       ep_out_found = 1;
+                               }
+                       }
                }
 
                /* is it an interrupt endpoint? */