+#endif
+
+#ifdef CONFIG_DM_ETH
+static int asix_eth_start(struct udevice *dev)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ return asix_init_common(&priv->ueth);
+}
+
+void asix_eth_stop(struct udevice *dev)
+{
+ debug("** %s()\n", __func__);
+}
+
+int asix_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ return asix_send_common(&priv->ueth, packet, length);
+}
+
+int asix_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+ struct ueth_data *ueth = &priv->ueth;
+ uint8_t *ptr;
+ int ret, len;
+ u32 packet_len;
+
+ len = usb_ether_get_rx_bytes(ueth, &ptr);
+ debug("%s: first try, len=%d\n", __func__, len);
+ if (!len) {
+ if (!(flags & ETH_RECV_CHECK_DEVICE))
+ return -EAGAIN;
+ ret = usb_ether_receive(ueth, AX_RX_URB_SIZE);
+ if (ret == -EAGAIN)
+ return ret;
+
+ len = usb_ether_get_rx_bytes(ueth, &ptr);
+ debug("%s: second try, len=%d\n", __func__, len);
+ }
+
+ /*
+ * 1st 4 bytes contain the length of the actual data as two
+ * complementary 16-bit words. Extract the length of the data.
+ */
+ if (len < sizeof(packet_len)) {
+ debug("Rx: incomplete packet length\n");
+ goto err;
+ }
+ memcpy(&packet_len, ptr, sizeof(packet_len));
+ le32_to_cpus(&packet_len);
+ if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
+ debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
+ packet_len, (~packet_len >> 16) & 0x7ff,
+ packet_len & 0x7ff);
+ goto err;
+ }
+ packet_len = packet_len & 0x7ff;
+ if (packet_len > len - sizeof(packet_len)) {
+ debug("Rx: too large packet: %d\n", packet_len);
+ goto err;
+ }
+
+ *packetp = ptr + sizeof(packet_len);
+ return packet_len;
+
+err:
+ usb_ether_advance_rxbuf(ueth, -1);
+ return -EINVAL;
+}
+
+static int asix_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ if (packet_len & 1)
+ packet_len++;
+ usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
+
+ return 0;
+}
+
+int asix_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct asix_private *priv = dev_get_priv(dev);
+
+ if (priv->flags & FLAG_TYPE_AX88172)
+ return -ENOSYS;
+
+ return asix_write_hwaddr_common(&priv->ueth, pdata->enetaddr);
+}
+
+static int asix_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct asix_private *priv = dev_get_priv(dev);
+ struct ueth_data *ss = &priv->ueth;
+ int ret;
+
+ priv->flags = dev->driver_data;
+ ret = usb_ether_register(dev, ss, AX_RX_URB_SIZE);
+ if (ret)
+ return ret;
+
+ ret = asix_basic_reset(ss);
+ if (ret)
+ goto err;
+
+ /* Get the MAC address */
+ ret = asix_read_mac_common(ss, priv, pdata->enetaddr);
+ if (ret)
+ goto err;
+ debug("MAC %pM\n", pdata->enetaddr);
+
+ return 0;
+
+err:
+ return usb_ether_deregister(ss);
+}
+
+static const struct eth_ops asix_eth_ops = {
+ .start = asix_eth_start,
+ .send = asix_eth_send,
+ .recv = asix_eth_recv,
+ .free_pkt = asix_free_pkt,
+ .stop = asix_eth_stop,
+ .write_hwaddr = asix_write_hwaddr,
+};
+
+U_BOOT_DRIVER(asix_eth) = {
+ .name = "asix_eth",
+ .id = UCLASS_ETH,
+ .probe = asix_eth_probe,
+ .ops = &asix_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct asix_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+static const struct usb_device_id asix_eth_id_table[] = {
+ /* Apple USB Ethernet Adapter */
+ { USB_DEVICE(0x05ac, 0x1402), .driver_info = FLAG_TYPE_AX88772 },
+ /* D-Link DUB-E100 H/W Ver B1 */
+ { USB_DEVICE(0x07d1, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
+ /* D-Link DUB-E100 H/W Ver C1 */
+ { USB_DEVICE(0x2001, 0x1a02), .driver_info = FLAG_TYPE_AX88772 },
+ /* Cables-to-Go USB Ethernet Adapter */
+ { USB_DEVICE(0x0b95, 0x772a), .driver_info = FLAG_TYPE_AX88772 },
+ /* Trendnet TU2-ET100 V3.0R */
+ { USB_DEVICE(0x0b95, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
+ /* SMC */
+ { USB_DEVICE(0x0b95, 0x1720), .driver_info = FLAG_TYPE_AX88172 },
+ /* MSI - ASIX 88772a */
+ { USB_DEVICE(0x0db0, 0xa877), .driver_info = FLAG_TYPE_AX88772 },
+ /* Linksys 200M v2.1 */
+ { USB_DEVICE(0x13b1, 0x0018), .driver_info = FLAG_TYPE_AX88172 },
+ /* 0Q0 cable ethernet */
+ { USB_DEVICE(0x1557, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
+ /* DLink DUB-E100 H/W Ver B1 Alternate */
+ { USB_DEVICE(0x2001, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
+ /* ASIX 88772B */
+ { USB_DEVICE(0x0b95, 0x772b),
+ .driver_info = FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+ { USB_DEVICE(0x0b95, 0x7e2b), .driver_info = FLAG_TYPE_AX88772B },
+ { } /* Terminating entry */
+};
+
+U_BOOT_USB_DEVICE(asix_eth, asix_eth_id_table);
+#endif