uboot/drivers/usb/eth/asix.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2011 The Chromium OS Authors.
   4 *
   5 * Patched for AX88772B by Antmicro Ltd <www.antmicro.com>
   6 */
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <log.h>
  11#include <net.h>
  12#include <usb.h>
  13#include <malloc.h>
  14#include <memalign.h>
  15#include <linux/delay.h>
  16#include <linux/mii.h>
  17#include "usb_ether.h"
  18
  19/* ASIX AX8817X based USB 2.0 Ethernet Devices */
  20
  21#define AX_CMD_SET_SW_MII               0x06
  22#define AX_CMD_READ_MII_REG             0x07
  23#define AX_CMD_WRITE_MII_REG            0x08
  24#define AX_CMD_SET_HW_MII               0x0a
  25#define AX_CMD_READ_EEPROM              0x0b
  26#define AX_CMD_READ_RX_CTL              0x0f
  27#define AX_CMD_WRITE_RX_CTL             0x10
  28#define AX_CMD_WRITE_IPG0               0x12
  29#define AX_CMD_READ_NODE_ID             0x13
  30#define AX_CMD_WRITE_NODE_ID    0x14
  31#define AX_CMD_READ_PHY_ID              0x19
  32#define AX_CMD_WRITE_MEDIUM_MODE        0x1b
  33#define AX_CMD_WRITE_GPIOS              0x1f
  34#define AX_CMD_SW_RESET                 0x20
  35#define AX_CMD_SW_PHY_SELECT            0x22
  36
  37#define AX_SWRESET_CLEAR                0x00
  38#define AX_SWRESET_PRTE                 0x04
  39#define AX_SWRESET_PRL                  0x08
  40#define AX_SWRESET_IPRL                 0x20
  41#define AX_SWRESET_IPPD                 0x40
  42
  43#define AX88772_IPG0_DEFAULT            0x15
  44#define AX88772_IPG1_DEFAULT            0x0c
  45#define AX88772_IPG2_DEFAULT            0x12
  46
  47/* AX88772 & AX88178 Medium Mode Register */
  48#define AX_MEDIUM_PF            0x0080
  49#define AX_MEDIUM_JFE           0x0040
  50#define AX_MEDIUM_TFC           0x0020
  51#define AX_MEDIUM_RFC           0x0010
  52#define AX_MEDIUM_ENCK          0x0008
  53#define AX_MEDIUM_AC            0x0004
  54#define AX_MEDIUM_FD            0x0002
  55#define AX_MEDIUM_GM            0x0001
  56#define AX_MEDIUM_SM            0x1000
  57#define AX_MEDIUM_SBP           0x0800
  58#define AX_MEDIUM_PS            0x0200
  59#define AX_MEDIUM_RE            0x0100
  60
  61#define AX88178_MEDIUM_DEFAULT  \
  62        (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
  63         AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
  64         AX_MEDIUM_RE)
  65
  66#define AX88772_MEDIUM_DEFAULT  \
  67        (AX_MEDIUM_FD | AX_MEDIUM_RFC | \
  68         AX_MEDIUM_TFC | AX_MEDIUM_PS | \
  69         AX_MEDIUM_AC | AX_MEDIUM_RE)
  70
  71/* AX88772 & AX88178 RX_CTL values */
  72#define AX_RX_CTL_SO                    0x0080
  73#define AX_RX_CTL_AB                    0x0008
  74
  75#define AX_DEFAULT_RX_CTL       \
  76        (AX_RX_CTL_SO | AX_RX_CTL_AB)
  77
  78/* GPIO 2 toggles */
  79#define AX_GPIO_GPO2EN          0x10    /* GPIO2 Output enable */
  80#define AX_GPIO_GPO_2           0x20    /* GPIO2 Output value */
  81#define AX_GPIO_RSE             0x80    /* Reload serial EEPROM */
  82
  83/* local defines */
  84#define ASIX_BASE_NAME "asx"
  85#define USB_CTRL_SET_TIMEOUT 5000
  86#define USB_CTRL_GET_TIMEOUT 5000
  87#define USB_BULK_SEND_TIMEOUT 5000
  88#define USB_BULK_RECV_TIMEOUT 5000
  89
  90#define AX_RX_URB_SIZE 2048
  91#define PHY_CONNECT_TIMEOUT 5000
  92
  93/* asix_flags defines */
  94#define FLAG_NONE                       0
  95#define FLAG_TYPE_AX88172       (1U << 0)
  96#define FLAG_TYPE_AX88772       (1U << 1)
  97#define FLAG_TYPE_AX88772B      (1U << 2)
  98#define FLAG_EEPROM_MAC         (1U << 3) /* initial mac address in eeprom */
  99
 100
 101/* driver private */
 102struct asix_private {
 103        int flags;
 104#ifdef CONFIG_DM_ETH
 105        struct ueth_data ueth;
 106#endif
 107};
 108
 109#ifndef CONFIG_DM_ETH
 110/* local vars */
 111static int curr_eth_dev; /* index for name of next device detected */
 112#endif
 113
 114/*
 115 * Asix infrastructure commands
 116 */
 117static int asix_write_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
 118                             u16 size, void *data)
 119{
 120        int len;
 121
 122        debug("asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x "
 123                "size=%d\n", cmd, value, index, size);
 124
 125        len = usb_control_msg(
 126                dev->pusb_dev,
 127                usb_sndctrlpipe(dev->pusb_dev, 0),
 128                cmd,
 129                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 130                value,
 131                index,
 132                data,
 133                size,
 134                USB_CTRL_SET_TIMEOUT);
 135
 136        return len == size ? 0 : -1;
 137}
 138
 139static int asix_read_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
 140                            u16 size, void *data)
 141{
 142        int len;
 143
 144        debug("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
 145                cmd, value, index, size);
 146
 147        len = usb_control_msg(
 148                dev->pusb_dev,
 149                usb_rcvctrlpipe(dev->pusb_dev, 0),
 150                cmd,
 151                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 152                value,
 153                index,
 154                data,
 155                size,
 156                USB_CTRL_GET_TIMEOUT);
 157        return len == size ? 0 : -1;
 158}
 159
 160static inline int asix_set_sw_mii(struct ueth_data *dev)
 161{
 162        int ret;
 163
 164        ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
 165        if (ret < 0)
 166                debug("Failed to enable software MII access\n");
 167        return ret;
 168}
 169
 170static inline int asix_set_hw_mii(struct ueth_data *dev)
 171{
 172        int ret;
 173
 174        ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
 175        if (ret < 0)
 176                debug("Failed to enable hardware MII access\n");
 177        return ret;
 178}
 179
 180static int asix_mdio_read(struct ueth_data *dev, int phy_id, int loc)
 181{
 182        ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
 183
 184        asix_set_sw_mii(dev);
 185        asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, res);
 186        asix_set_hw_mii(dev);
 187
 188        debug("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
 189                        phy_id, loc, le16_to_cpu(*res));
 190
 191        return le16_to_cpu(*res);
 192}
 193
 194static void
 195asix_mdio_write(struct ueth_data *dev, int phy_id, int loc, int val)
 196{
 197        ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
 198        *res = cpu_to_le16(val);
 199
 200        debug("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
 201                        phy_id, loc, val);
 202        asix_set_sw_mii(dev);
 203        asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, res);
 204        asix_set_hw_mii(dev);
 205}
 206
 207/*
 208 * Asix "high level" commands
 209 */
 210static int asix_sw_reset(struct ueth_data *dev, u8 flags)
 211{
 212        int ret;
 213
 214        ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
 215        if (ret < 0)
 216                debug("Failed to send software reset: %02x\n", ret);
 217        else
 218                udelay(150 * 1000);
 219
 220        return ret;
 221}
 222
 223static inline int asix_get_phy_addr(struct ueth_data *dev)
 224{
 225        ALLOC_CACHE_ALIGN_BUFFER(u8, buf, 2);
 226
 227        int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
 228
 229        debug("asix_get_phy_addr()\n");
 230
 231        if (ret < 0) {
 232                debug("Error reading PHYID register: %02x\n", ret);
 233                goto out;
 234        }
 235        debug("asix_get_phy_addr() returning 0x%02x%02x\n", buf[0], buf[1]);
 236        ret = buf[1];
 237
 238out:
 239        return ret;
 240}
 241
 242static int asix_write_medium_mode(struct ueth_data *dev, u16 mode)
 243{
 244        int ret;
 245
 246        debug("asix_write_medium_mode() - mode = 0x%04x\n", mode);
 247        ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode,
 248                        0, 0, NULL);
 249        if (ret < 0) {
 250                debug("Failed to write Medium Mode mode to 0x%04x: %02x\n",
 251                        mode, ret);
 252        }
 253        return ret;
 254}
 255
 256static u16 asix_read_rx_ctl(struct ueth_data *dev)
 257{
 258        ALLOC_CACHE_ALIGN_BUFFER(__le16, v, 1);
 259
 260        int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, v);
 261
 262        if (ret < 0)
 263                debug("Error reading RX_CTL register: %02x\n", ret);
 264        else
 265                ret = le16_to_cpu(*v);
 266        return ret;
 267}
 268
 269static int asix_write_rx_ctl(struct ueth_data *dev, u16 mode)
 270{
 271        int ret;
 272
 273        debug("asix_write_rx_ctl() - mode = 0x%04x\n", mode);
 274        ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
 275        if (ret < 0) {
 276                debug("Failed to write RX_CTL mode to 0x%04x: %02x\n",
 277                                mode, ret);
 278        }
 279        return ret;
 280}
 281
 282static int asix_write_gpio(struct ueth_data *dev, u16 value, int sleep)
 283{
 284        int ret;
 285
 286        debug("asix_write_gpio() - value = 0x%04x\n", value);
 287        ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
 288        if (ret < 0) {
 289                debug("Failed to write GPIO value 0x%04x: %02x\n",
 290                        value, ret);
 291        }
 292        if (sleep)
 293                udelay(sleep * 1000);
 294
 295        return ret;
 296}
 297
 298static int asix_write_hwaddr_common(struct ueth_data *dev, uint8_t *enetaddr)
 299{
 300        int ret;
 301        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
 302
 303        memcpy(buf, enetaddr, ETH_ALEN);
 304
 305        ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf);
 306        if (ret < 0)
 307                debug("Failed to set MAC address: %02x\n", ret);
 308
 309        return ret;
 310}
 311
 312/*
 313 * mii commands
 314 */
 315
 316/*
 317 * mii_nway_restart - restart NWay (autonegotiation) for this interface
 318 *
 319 * Returns 0 on success, negative on error.
 320 */
 321static int mii_nway_restart(struct ueth_data *dev)
 322{
 323        int bmcr;
 324        int r = -1;
 325
 326        /* if autoneg is off, it's an error */
 327        bmcr = asix_mdio_read(dev, dev->phy_id, MII_BMCR);
 328
 329        if (bmcr & BMCR_ANENABLE) {
 330                bmcr |= BMCR_ANRESTART;
 331                asix_mdio_write(dev, dev->phy_id, MII_BMCR, bmcr);
 332                r = 0;
 333        }
 334
 335        return r;
 336}
 337
 338static int asix_read_mac_common(struct ueth_data *dev,
 339                                struct asix_private *priv, uint8_t *enetaddr)
 340{
 341        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
 342        int i;
 343
 344        if (priv->flags & FLAG_EEPROM_MAC) {
 345                for (i = 0; i < (ETH_ALEN >> 1); i++) {
 346                        if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
 347                                          0x04 + i, 0, 2, buf) < 0) {
 348                                debug("Failed to read SROM address 04h.\n");
 349                                return -1;
 350                        }
 351                        memcpy(enetaddr + i * 2, buf, 2);
 352                }
 353        } else {
 354                if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)
 355                     < 0) {
 356                        debug("Failed to read MAC address.\n");
 357                        return -1;
 358                }
 359                memcpy(enetaddr, buf, ETH_ALEN);
 360        }
 361
 362        return 0;
 363}
 364
 365static int asix_basic_reset(struct ueth_data *dev)
 366{
 367        int embd_phy;
 368        u16 rx_ctl;
 369
 370        if (asix_write_gpio(dev,
 371                        AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0)
 372                return -1;
 373
 374        /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
 375        embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
 376        if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
 377                                embd_phy, 0, 0, NULL) < 0) {
 378                debug("Select PHY #1 failed\n");
 379                return -1;
 380        }
 381
 382        if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0)
 383                return -1;
 384
 385        if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0)
 386                return -1;
 387
 388        if (embd_phy) {
 389                if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0)
 390                        return -1;
 391        } else {
 392                if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0)
 393                        return -1;
 394        }
 395
 396        rx_ctl = asix_read_rx_ctl(dev);
 397        debug("RX_CTL is 0x%04x after software reset\n", rx_ctl);
 398        if (asix_write_rx_ctl(dev, 0x0000) < 0)
 399                return -1;
 400
 401        rx_ctl = asix_read_rx_ctl(dev);
 402        debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 403
 404        dev->phy_id = asix_get_phy_addr(dev);
 405        if (dev->phy_id < 0)
 406                debug("Failed to read phy id\n");
 407
 408        asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
 409        asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
 410                        ADVERTISE_ALL | ADVERTISE_CSMA);
 411        mii_nway_restart(dev);
 412
 413        if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
 414                return -1;
 415
 416        if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
 417                                AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
 418                                AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
 419                debug("Write IPG,IPG1,IPG2 failed\n");
 420                return -1;
 421        }
 422
 423        return 0;
 424}
 425
 426static int asix_init_common(struct ueth_data *dev, uint8_t *enetaddr)
 427{
 428        int timeout = 0;
 429#define TIMEOUT_RESOLUTION 50   /* ms */
 430        int link_detected;
 431
 432        debug("** %s()\n", __func__);
 433
 434        if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
 435                goto out_err;
 436
 437        if (asix_write_hwaddr_common(dev, enetaddr) < 0)
 438                goto out_err;
 439
 440        do {
 441                link_detected = asix_mdio_read(dev, dev->phy_id, MII_BMSR) &
 442                        BMSR_LSTATUS;
 443                if (!link_detected) {
 444                        if (timeout == 0)
 445                                printf("Waiting for Ethernet connection... ");
 446                        udelay(TIMEOUT_RESOLUTION * 1000);
 447                        timeout += TIMEOUT_RESOLUTION;
 448                }
 449        } while (!link_detected && timeout < PHY_CONNECT_TIMEOUT);
 450        if (link_detected) {
 451                if (timeout != 0)
 452                        printf("done.\n");
 453        } else {
 454                printf("unable to connect.\n");
 455                goto out_err;
 456        }
 457
 458        /*
 459         * Wait some more to avoid timeout on first transfer
 460         * (e.g. EHCI timed out on TD - token=0x8008d80)
 461         */
 462        mdelay(25);
 463
 464        return 0;
 465out_err:
 466        return -1;
 467}
 468
 469static int asix_send_common(struct ueth_data *dev, void *packet, int length)
 470{
 471        int err;
 472        u32 packet_len;
 473        int actual_len;
 474        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
 475                PKTSIZE + sizeof(packet_len));
 476
 477        debug("** %s(), len %d\n", __func__, length);
 478
 479        packet_len = (((length) ^ 0x0000ffff) << 16) + (length);
 480        cpu_to_le32s(&packet_len);
 481
 482        memcpy(msg, &packet_len, sizeof(packet_len));
 483        memcpy(msg + sizeof(packet_len), (void *)packet, length);
 484
 485        err = usb_bulk_msg(dev->pusb_dev,
 486                                usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
 487                                (void *)msg,
 488                                length + sizeof(packet_len),
 489                                &actual_len,
 490                                USB_BULK_SEND_TIMEOUT);
 491        debug("Tx: len = %zu, actual = %u, err = %d\n",
 492                        length + sizeof(packet_len), actual_len, err);
 493
 494        return err;
 495}
 496
 497#ifndef CONFIG_DM_ETH
 498/*
 499 * Asix callbacks
 500 */
 501static int asix_init(struct eth_device *eth, struct bd_info *bd)
 502{
 503        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 504
 505        return asix_init_common(dev, eth->enetaddr);
 506}
 507
 508static int asix_send(struct eth_device *eth, void *packet, int length)
 509{
 510        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 511
 512        return asix_send_common(dev, packet, length);
 513}
 514
 515static int asix_recv(struct eth_device *eth)
 516{
 517        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 518        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, recv_buf, AX_RX_URB_SIZE);
 519        unsigned char *buf_ptr;
 520        int err;
 521        int actual_len;
 522        u32 packet_len;
 523
 524        debug("** %s()\n", __func__);
 525
 526        err = usb_bulk_msg(dev->pusb_dev,
 527                                usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
 528                                (void *)recv_buf,
 529                                AX_RX_URB_SIZE,
 530                                &actual_len,
 531                                USB_BULK_RECV_TIMEOUT);
 532        debug("Rx: len = %u, actual = %u, err = %d\n", AX_RX_URB_SIZE,
 533                actual_len, err);
 534        if (err != 0) {
 535                debug("Rx: failed to receive\n");
 536                return -1;
 537        }
 538        if (actual_len > AX_RX_URB_SIZE) {
 539                debug("Rx: received too many bytes %d\n", actual_len);
 540                return -1;
 541        }
 542
 543        buf_ptr = recv_buf;
 544        while (actual_len > 0) {
 545                /*
 546                 * 1st 4 bytes contain the length of the actual data as two
 547                 * complementary 16-bit words. Extract the length of the data.
 548                 */
 549                if (actual_len < sizeof(packet_len)) {
 550                        debug("Rx: incomplete packet length\n");
 551                        return -1;
 552                }
 553                memcpy(&packet_len, buf_ptr, sizeof(packet_len));
 554                le32_to_cpus(&packet_len);
 555                if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
 556                        debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
 557                              packet_len, (~packet_len >> 16) & 0x7ff,
 558                              packet_len & 0x7ff);
 559                        return -1;
 560                }
 561                packet_len = packet_len & 0x7ff;
 562                if (packet_len > actual_len - sizeof(packet_len)) {
 563                        debug("Rx: too large packet: %d\n", packet_len);
 564                        return -1;
 565                }
 566
 567                /* Notify net stack */
 568                net_process_received_packet(buf_ptr + sizeof(packet_len),
 569                                            packet_len);
 570
 571                /* Adjust for next iteration. Packets are padded to 16-bits */
 572                if (packet_len & 1)
 573                        packet_len++;
 574                actual_len -= sizeof(packet_len) + packet_len;
 575                buf_ptr += sizeof(packet_len) + packet_len;
 576        }
 577
 578        return err;
 579}
 580
 581static void asix_halt(struct eth_device *eth)
 582{
 583        debug("** %s()\n", __func__);
 584}
 585
 586static int asix_write_hwaddr(struct eth_device *eth)
 587{
 588        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 589
 590        return asix_write_hwaddr_common(dev, eth->enetaddr);
 591}
 592
 593/*
 594 * Asix probing functions
 595 */
 596void asix_eth_before_probe(void)
 597{
 598        curr_eth_dev = 0;
 599}
 600
 601struct asix_dongle {
 602        unsigned short vendor;
 603        unsigned short product;
 604        int flags;
 605};
 606
 607static const struct asix_dongle asix_dongles[] = {
 608        { 0x05ac, 0x1402, FLAG_TYPE_AX88772 },  /* Apple USB Ethernet Adapter */
 609        { 0x07d1, 0x3c05, FLAG_TYPE_AX88772 },  /* D-Link DUB-E100 H/W Ver B1 */
 610        { 0x2001, 0x1a02, FLAG_TYPE_AX88772 },  /* D-Link DUB-E100 H/W Ver C1 */
 611        /* Cables-to-Go USB Ethernet Adapter */
 612        { 0x0b95, 0x772a, FLAG_TYPE_AX88772 },
 613        { 0x0b95, 0x7720, FLAG_TYPE_AX88772 },  /* Trendnet TU2-ET100 V3.0R */
 614        { 0x0b95, 0x1720, FLAG_TYPE_AX88172 },  /* SMC */
 615        { 0x0db0, 0xa877, FLAG_TYPE_AX88772 },  /* MSI - ASIX 88772a */
 616        { 0x13b1, 0x0018, FLAG_TYPE_AX88172 },  /* Linksys 200M v2.1 */
 617        { 0x1557, 0x7720, FLAG_TYPE_AX88772 },  /* 0Q0 cable ethernet */
 618        /* DLink DUB-E100 H/W Ver B1 Alternate */
 619        { 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
 620        /* ASIX 88772B */
 621        { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
 622        { 0x0b95, 0x7e2b, FLAG_TYPE_AX88772B },
 623        { 0x0000, 0x0000, FLAG_NONE }   /* END - Do not remove */
 624};
 625
 626/* Probe to see if a new device is actually an asix device */
 627int asix_eth_probe(struct usb_device *dev, unsigned int ifnum,
 628                      struct ueth_data *ss)
 629{
 630        struct usb_interface *iface;
 631        struct usb_interface_descriptor *iface_desc;
 632        int ep_in_found = 0, ep_out_found = 0;
 633        int i;
 634
 635        /* let's examine the device now */
 636        iface = &dev->config.if_desc[ifnum];
 637        iface_desc = &dev->config.if_desc[ifnum].desc;
 638
 639        for (i = 0; asix_dongles[i].vendor != 0; i++) {
 640                if (dev->descriptor.idVendor == asix_dongles[i].vendor &&
 641                    dev->descriptor.idProduct == asix_dongles[i].product)
 642                        /* Found a supported dongle */
 643                        break;
 644        }
 645
 646        if (asix_dongles[i].vendor == 0)
 647                return 0;
 648
 649        memset(ss, 0, sizeof(struct ueth_data));
 650
 651        /* At this point, we know we've got a live one */
 652        debug("\n\nUSB Ethernet device detected: %#04x:%#04x\n",
 653              dev->descriptor.idVendor, dev->descriptor.idProduct);
 654
 655        /* Initialize the ueth_data structure with some useful info */
 656        ss->ifnum = ifnum;
 657        ss->pusb_dev = dev;
 658        ss->subclass = iface_desc->bInterfaceSubClass;
 659        ss->protocol = iface_desc->bInterfaceProtocol;
 660
 661        /* alloc driver private */
 662        ss->dev_priv = calloc(1, sizeof(struct asix_private));
 663        if (!ss->dev_priv)
 664                return 0;
 665
 666        ((struct asix_private *)ss->dev_priv)->flags = asix_dongles[i].flags;
 667
 668        /*
 669         * We are expecting a minimum of 3 endpoints - in, out (bulk), and
 670         * int. We will ignore any others.
 671         */
 672        for (i = 0; i < iface_desc->bNumEndpoints; i++) {
 673                /* is it an BULK endpoint? */
 674                if ((iface->ep_desc[i].bmAttributes &
 675                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
 676                        u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
 677                        if (ep_addr & USB_DIR_IN) {
 678                                if (!ep_in_found) {
 679                                        ss->ep_in = ep_addr &
 680                                                USB_ENDPOINT_NUMBER_MASK;
 681                                        ep_in_found = 1;
 682                                }
 683                        } else {
 684                                if (!ep_out_found) {
 685                                        ss->ep_out = ep_addr &
 686                                                USB_ENDPOINT_NUMBER_MASK;
 687                                        ep_out_found = 1;
 688                                }
 689                        }
 690                }
 691
 692                /* is it an interrupt endpoint? */
 693                if ((iface->ep_desc[i].bmAttributes &
 694                    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
 695                        ss->ep_int = iface->ep_desc[i].bEndpointAddress &
 696                                USB_ENDPOINT_NUMBER_MASK;
 697                        ss->irqinterval = iface->ep_desc[i].bInterval;
 698                }
 699        }
 700        debug("Endpoints In %d Out %d Int %d\n",
 701                  ss->ep_in, ss->ep_out, ss->ep_int);
 702
 703        /* Do some basic sanity checks, and bail if we find a problem */
 704        if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
 705            !ss->ep_in || !ss->ep_out || !ss->ep_int) {
 706                debug("Problems with device\n");
 707                return 0;
 708        }
 709        dev->privptr = (void *)ss;
 710        return 1;
 711}
 712
 713int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
 714                                struct eth_device *eth)
 715{
 716        struct asix_private *priv = (struct asix_private *)ss->dev_priv;
 717
 718        if (!eth) {
 719                debug("%s: missing parameter.\n", __func__);
 720                return 0;
 721        }
 722        sprintf(eth->name, "%s%d", ASIX_BASE_NAME, curr_eth_dev++);
 723        eth->init = asix_init;
 724        eth->send = asix_send;
 725        eth->recv = asix_recv;
 726        eth->halt = asix_halt;
 727        if (!(priv->flags & FLAG_TYPE_AX88172))
 728                eth->write_hwaddr = asix_write_hwaddr;
 729        eth->priv = ss;
 730
 731        if (asix_basic_reset(ss))
 732                return 0;
 733
 734        /* Get the MAC address */
 735        if (asix_read_mac_common(ss, priv, eth->enetaddr))
 736                return 0;
 737        debug("MAC %pM\n", eth->enetaddr);
 738
 739        return 1;
 740}
 741#endif
 742
 743#ifdef CONFIG_DM_ETH
 744static int asix_eth_start(struct udevice *dev)
 745{
 746        struct eth_pdata *pdata = dev_get_platdata(dev);
 747        struct asix_private *priv = dev_get_priv(dev);
 748
 749        return asix_init_common(&priv->ueth, pdata->enetaddr);
 750}
 751
 752void asix_eth_stop(struct udevice *dev)
 753{
 754        debug("** %s()\n", __func__);
 755}
 756
 757int asix_eth_send(struct udevice *dev, void *packet, int length)
 758{
 759        struct asix_private *priv = dev_get_priv(dev);
 760
 761        return asix_send_common(&priv->ueth, packet, length);
 762}
 763
 764int asix_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 765{
 766        struct asix_private *priv = dev_get_priv(dev);
 767        struct ueth_data *ueth = &priv->ueth;
 768        uint8_t *ptr;
 769        int ret, len;
 770        u32 packet_len;
 771
 772        len = usb_ether_get_rx_bytes(ueth, &ptr);
 773        debug("%s: first try, len=%d\n", __func__, len);
 774        if (!len) {
 775                if (!(flags & ETH_RECV_CHECK_DEVICE))
 776                        return -EAGAIN;
 777                ret = usb_ether_receive(ueth, AX_RX_URB_SIZE);
 778                if (ret == -EAGAIN)
 779                        return ret;
 780
 781                len = usb_ether_get_rx_bytes(ueth, &ptr);
 782                debug("%s: second try, len=%d\n", __func__, len);
 783        }
 784
 785        /*
 786         * 1st 4 bytes contain the length of the actual data as two
 787         * complementary 16-bit words. Extract the length of the data.
 788         */
 789        if (len < sizeof(packet_len)) {
 790                debug("Rx: incomplete packet length\n");
 791                goto err;
 792        }
 793        memcpy(&packet_len, ptr, sizeof(packet_len));
 794        le32_to_cpus(&packet_len);
 795        if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
 796                debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
 797                      packet_len, (~packet_len >> 16) & 0x7ff,
 798                      packet_len & 0x7ff);
 799                goto err;
 800        }
 801        packet_len = packet_len & 0x7ff;
 802        if (packet_len > len - sizeof(packet_len)) {
 803                debug("Rx: too large packet: %d\n", packet_len);
 804                goto err;
 805        }
 806
 807        *packetp = ptr + sizeof(packet_len);
 808        return packet_len;
 809
 810err:
 811        usb_ether_advance_rxbuf(ueth, -1);
 812        return -EINVAL;
 813}
 814
 815static int asix_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
 816{
 817        struct asix_private *priv = dev_get_priv(dev);
 818
 819        if (packet_len & 1)
 820                packet_len++;
 821        usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
 822
 823        return 0;
 824}
 825
 826int asix_write_hwaddr(struct udevice *dev)
 827{
 828        struct eth_pdata *pdata = dev_get_platdata(dev);
 829        struct asix_private *priv = dev_get_priv(dev);
 830
 831        if (priv->flags & FLAG_TYPE_AX88172)
 832                return -ENOSYS;
 833
 834        return asix_write_hwaddr_common(&priv->ueth, pdata->enetaddr);
 835}
 836
 837static int asix_eth_probe(struct udevice *dev)
 838{
 839        struct eth_pdata *pdata = dev_get_platdata(dev);
 840        struct asix_private *priv = dev_get_priv(dev);
 841        struct ueth_data *ss = &priv->ueth;
 842        int ret;
 843
 844        priv->flags = dev->driver_data;
 845        ret = usb_ether_register(dev, ss, AX_RX_URB_SIZE);
 846        if (ret)
 847                return ret;
 848
 849        ret = asix_basic_reset(ss);
 850        if (ret)
 851                goto err;
 852
 853        /* Get the MAC address */
 854        ret = asix_read_mac_common(ss, priv, pdata->enetaddr);
 855        if (ret)
 856                goto err;
 857        debug("MAC %pM\n", pdata->enetaddr);
 858
 859        return 0;
 860
 861err:
 862        return usb_ether_deregister(ss);
 863}
 864
 865static const struct eth_ops asix_eth_ops = {
 866        .start  = asix_eth_start,
 867        .send   = asix_eth_send,
 868        .recv   = asix_eth_recv,
 869        .free_pkt = asix_free_pkt,
 870        .stop   = asix_eth_stop,
 871        .write_hwaddr = asix_write_hwaddr,
 872};
 873
 874U_BOOT_DRIVER(asix_eth) = {
 875        .name   = "asix_eth",
 876        .id     = UCLASS_ETH,
 877        .probe = asix_eth_probe,
 878        .ops    = &asix_eth_ops,
 879        .priv_auto_alloc_size = sizeof(struct asix_private),
 880        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
 881};
 882
 883static const struct usb_device_id asix_eth_id_table[] = {
 884        /* Apple USB Ethernet Adapter */
 885        { USB_DEVICE(0x05ac, 0x1402), .driver_info = FLAG_TYPE_AX88772 },
 886        /* D-Link DUB-E100 H/W Ver B1 */
 887        { USB_DEVICE(0x07d1, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
 888        /* D-Link DUB-E100 H/W Ver C1 */
 889        { USB_DEVICE(0x2001, 0x1a02), .driver_info = FLAG_TYPE_AX88772 },
 890        /* Cables-to-Go USB Ethernet Adapter */
 891        { USB_DEVICE(0x0b95, 0x772a), .driver_info = FLAG_TYPE_AX88772 },
 892        /* Trendnet TU2-ET100 V3.0R */
 893        { USB_DEVICE(0x0b95, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
 894        /* SMC */
 895        { USB_DEVICE(0x0b95, 0x1720), .driver_info = FLAG_TYPE_AX88172 },
 896        /* MSI - ASIX 88772a */
 897        { USB_DEVICE(0x0db0, 0xa877), .driver_info = FLAG_TYPE_AX88772 },
 898        /* Linksys 200M v2.1 */
 899        { USB_DEVICE(0x13b1, 0x0018), .driver_info = FLAG_TYPE_AX88172 },
 900        /* 0Q0 cable ethernet */
 901        { USB_DEVICE(0x1557, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
 902        /* DLink DUB-E100 H/W Ver B1 Alternate */
 903        { USB_DEVICE(0x2001, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
 904        /* ASIX 88772B */
 905        { USB_DEVICE(0x0b95, 0x772b),
 906                .driver_info = FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
 907        { USB_DEVICE(0x0b95, 0x7e2b), .driver_info = FLAG_TYPE_AX88772B },
 908        { }             /* Terminating entry */
 909};
 910
 911U_BOOT_USB_DEVICE(asix_eth, asix_eth_id_table);
 912#endif
 913