uboot/drivers/usb/eth/asix.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2011 The Chromium OS Authors.
   3 * See file CREDITS for list of people who contributed to this
   4 * project.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation; either version 2 of
   9 * the License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19 * MA 02111-1307 USA
  20 */
  21
  22#include <common.h>
  23#include <usb.h>
  24#include <linux/mii.h>
  25#include "usb_ether.h"
  26
  27
  28/* ASIX AX8817X based USB 2.0 Ethernet Devices */
  29
  30#define AX_CMD_SET_SW_MII               0x06
  31#define AX_CMD_READ_MII_REG             0x07
  32#define AX_CMD_WRITE_MII_REG            0x08
  33#define AX_CMD_SET_HW_MII               0x0a
  34#define AX_CMD_READ_RX_CTL              0x0f
  35#define AX_CMD_WRITE_RX_CTL             0x10
  36#define AX_CMD_WRITE_IPG0               0x12
  37#define AX_CMD_READ_NODE_ID             0x13
  38#define AX_CMD_READ_PHY_ID              0x19
  39#define AX_CMD_WRITE_MEDIUM_MODE        0x1b
  40#define AX_CMD_WRITE_GPIOS              0x1f
  41#define AX_CMD_SW_RESET                 0x20
  42#define AX_CMD_SW_PHY_SELECT            0x22
  43
  44#define AX_SWRESET_CLEAR                0x00
  45#define AX_SWRESET_PRTE                 0x04
  46#define AX_SWRESET_PRL                  0x08
  47#define AX_SWRESET_IPRL                 0x20
  48#define AX_SWRESET_IPPD                 0x40
  49
  50#define AX88772_IPG0_DEFAULT            0x15
  51#define AX88772_IPG1_DEFAULT            0x0c
  52#define AX88772_IPG2_DEFAULT            0x12
  53
  54/* AX88772 & AX88178 Medium Mode Register */
  55#define AX_MEDIUM_PF            0x0080
  56#define AX_MEDIUM_JFE           0x0040
  57#define AX_MEDIUM_TFC           0x0020
  58#define AX_MEDIUM_RFC           0x0010
  59#define AX_MEDIUM_ENCK          0x0008
  60#define AX_MEDIUM_AC            0x0004
  61#define AX_MEDIUM_FD            0x0002
  62#define AX_MEDIUM_GM            0x0001
  63#define AX_MEDIUM_SM            0x1000
  64#define AX_MEDIUM_SBP           0x0800
  65#define AX_MEDIUM_PS            0x0200
  66#define AX_MEDIUM_RE            0x0100
  67
  68#define AX88178_MEDIUM_DEFAULT  \
  69        (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
  70         AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
  71         AX_MEDIUM_RE)
  72
  73#define AX88772_MEDIUM_DEFAULT  \
  74        (AX_MEDIUM_FD | AX_MEDIUM_RFC | \
  75         AX_MEDIUM_TFC | AX_MEDIUM_PS | \
  76         AX_MEDIUM_AC | AX_MEDIUM_RE)
  77
  78/* AX88772 & AX88178 RX_CTL values */
  79#define AX_RX_CTL_SO                    0x0080
  80#define AX_RX_CTL_AB                    0x0008
  81
  82#define AX_DEFAULT_RX_CTL       \
  83        (AX_RX_CTL_SO | AX_RX_CTL_AB)
  84
  85/* GPIO 2 toggles */
  86#define AX_GPIO_GPO2EN          0x10    /* GPIO2 Output enable */
  87#define AX_GPIO_GPO_2           0x20    /* GPIO2 Output value */
  88#define AX_GPIO_RSE             0x80    /* Reload serial EEPROM */
  89
  90/* local defines */
  91#define ASIX_BASE_NAME "asx"
  92#define USB_CTRL_SET_TIMEOUT 5000
  93#define USB_CTRL_GET_TIMEOUT 5000
  94#define USB_BULK_SEND_TIMEOUT 5000
  95#define USB_BULK_RECV_TIMEOUT 5000
  96
  97#define AX_RX_URB_SIZE 2048
  98#define PHY_CONNECT_TIMEOUT 5000
  99
 100/* local vars */
 101static int curr_eth_dev; /* index for name of next device detected */
 102
 103/*
 104 * Asix infrastructure commands
 105 */
 106static int asix_write_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
 107                             u16 size, void *data)
 108{
 109        int len;
 110
 111        debug("asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x "
 112                "size=%d\n", cmd, value, index, size);
 113
 114        len = usb_control_msg(
 115                dev->pusb_dev,
 116                usb_sndctrlpipe(dev->pusb_dev, 0),
 117                cmd,
 118                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 119                value,
 120                index,
 121                data,
 122                size,
 123                USB_CTRL_SET_TIMEOUT);
 124
 125        return len == size ? 0 : -1;
 126}
 127
 128static int asix_read_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
 129                            u16 size, void *data)
 130{
 131        int len;
 132
 133        debug("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
 134                cmd, value, index, size);
 135
 136        len = usb_control_msg(
 137                dev->pusb_dev,
 138                usb_rcvctrlpipe(dev->pusb_dev, 0),
 139                cmd,
 140                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 141                value,
 142                index,
 143                data,
 144                size,
 145                USB_CTRL_GET_TIMEOUT);
 146        return len == size ? 0 : -1;
 147}
 148
 149static inline int asix_set_sw_mii(struct ueth_data *dev)
 150{
 151        int ret;
 152
 153        ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
 154        if (ret < 0)
 155                debug("Failed to enable software MII access\n");
 156        return ret;
 157}
 158
 159static inline int asix_set_hw_mii(struct ueth_data *dev)
 160{
 161        int ret;
 162
 163        ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
 164        if (ret < 0)
 165                debug("Failed to enable hardware MII access\n");
 166        return ret;
 167}
 168
 169static int asix_mdio_read(struct ueth_data *dev, int phy_id, int loc)
 170{
 171        __le16 res;
 172
 173        asix_set_sw_mii(dev);
 174        asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res);
 175        asix_set_hw_mii(dev);
 176
 177        debug("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
 178                        phy_id, loc, le16_to_cpu(res));
 179
 180        return le16_to_cpu(res);
 181}
 182
 183static void
 184asix_mdio_write(struct ueth_data *dev, int phy_id, int loc, int val)
 185{
 186        __le16 res = cpu_to_le16(val);
 187
 188        debug("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
 189                        phy_id, loc, val);
 190        asix_set_sw_mii(dev);
 191        asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
 192        asix_set_hw_mii(dev);
 193}
 194
 195/*
 196 * Asix "high level" commands
 197 */
 198static int asix_sw_reset(struct ueth_data *dev, u8 flags)
 199{
 200        int ret;
 201
 202        ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
 203        if (ret < 0)
 204                debug("Failed to send software reset: %02x\n", ret);
 205        else
 206                udelay(150 * 1000);
 207
 208        return ret;
 209}
 210
 211static inline int asix_get_phy_addr(struct ueth_data *dev)
 212{
 213        u8 buf[2];
 214        int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
 215
 216        debug("asix_get_phy_addr()\n");
 217
 218        if (ret < 0) {
 219                debug("Error reading PHYID register: %02x\n", ret);
 220                goto out;
 221        }
 222        debug("asix_get_phy_addr() returning 0x%02x%02x\n", buf[0], buf[1]);
 223        ret = buf[1];
 224
 225out:
 226        return ret;
 227}
 228
 229static int asix_write_medium_mode(struct ueth_data *dev, u16 mode)
 230{
 231        int ret;
 232
 233        debug("asix_write_medium_mode() - mode = 0x%04x\n", mode);
 234        ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode,
 235                        0, 0, NULL);
 236        if (ret < 0) {
 237                debug("Failed to write Medium Mode mode to 0x%04x: %02x\n",
 238                        mode, ret);
 239        }
 240        return ret;
 241}
 242
 243static u16 asix_read_rx_ctl(struct ueth_data *dev)
 244{
 245        __le16 v;
 246        int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
 247
 248        if (ret < 0)
 249                debug("Error reading RX_CTL register: %02x\n", ret);
 250        else
 251                ret = le16_to_cpu(v);
 252        return ret;
 253}
 254
 255static int asix_write_rx_ctl(struct ueth_data *dev, u16 mode)
 256{
 257        int ret;
 258
 259        debug("asix_write_rx_ctl() - mode = 0x%04x\n", mode);
 260        ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
 261        if (ret < 0) {
 262                debug("Failed to write RX_CTL mode to 0x%04x: %02x\n",
 263                                mode, ret);
 264        }
 265        return ret;
 266}
 267
 268static int asix_write_gpio(struct ueth_data *dev, u16 value, int sleep)
 269{
 270        int ret;
 271
 272        debug("asix_write_gpio() - value = 0x%04x\n", value);
 273        ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
 274        if (ret < 0) {
 275                debug("Failed to write GPIO value 0x%04x: %02x\n",
 276                        value, ret);
 277        }
 278        if (sleep)
 279                udelay(sleep * 1000);
 280
 281        return ret;
 282}
 283
 284/*
 285 * mii commands
 286 */
 287
 288/*
 289 * mii_nway_restart - restart NWay (autonegotiation) for this interface
 290 *
 291 * Returns 0 on success, negative on error.
 292 */
 293static int mii_nway_restart(struct ueth_data *dev)
 294{
 295        int bmcr;
 296        int r = -1;
 297
 298        /* if autoneg is off, it's an error */
 299        bmcr = asix_mdio_read(dev, dev->phy_id, MII_BMCR);
 300
 301        if (bmcr & BMCR_ANENABLE) {
 302                bmcr |= BMCR_ANRESTART;
 303                asix_mdio_write(dev, dev->phy_id, MII_BMCR, bmcr);
 304                r = 0;
 305        }
 306
 307        return r;
 308}
 309
 310/*
 311 * Asix callbacks
 312 */
 313static int asix_init(struct eth_device *eth, bd_t *bd)
 314{
 315        int embd_phy;
 316        unsigned char buf[ETH_ALEN];
 317        u16 rx_ctl;
 318        struct ueth_data        *dev = (struct ueth_data *)eth->priv;
 319        int timeout = 0;
 320#define TIMEOUT_RESOLUTION 50   /* ms */
 321        int link_detected;
 322
 323        debug("** %s()\n", __func__);
 324
 325        if (asix_write_gpio(dev,
 326                        AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0)
 327                goto out_err;
 328
 329        /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
 330        embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
 331        if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
 332                                embd_phy, 0, 0, NULL) < 0) {
 333                debug("Select PHY #1 failed\n");
 334                goto out_err;
 335        }
 336
 337        if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0)
 338                goto out_err;
 339
 340        if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0)
 341                goto out_err;
 342
 343        if (embd_phy) {
 344                if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0)
 345                        goto out_err;
 346        } else {
 347                if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0)
 348                        goto out_err;
 349        }
 350
 351        rx_ctl = asix_read_rx_ctl(dev);
 352        debug("RX_CTL is 0x%04x after software reset\n", rx_ctl);
 353        if (asix_write_rx_ctl(dev, 0x0000) < 0)
 354                goto out_err;
 355
 356        rx_ctl = asix_read_rx_ctl(dev);
 357        debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 358
 359        /* Get the MAC address */
 360        if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
 361                                0, 0, ETH_ALEN, buf) < 0) {
 362                debug("Failed to read MAC address.\n");
 363                goto out_err;
 364        }
 365        memcpy(eth->enetaddr, buf, ETH_ALEN);
 366        debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
 367                eth->enetaddr[0], eth->enetaddr[1],
 368                eth->enetaddr[2], eth->enetaddr[3],
 369                eth->enetaddr[4], eth->enetaddr[5]);
 370
 371        dev->phy_id = asix_get_phy_addr(dev);
 372        if (dev->phy_id < 0)
 373                debug("Failed to read phy id\n");
 374
 375        if (asix_sw_reset(dev, AX_SWRESET_PRL) < 0)
 376                goto out_err;
 377
 378        if (asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL) < 0)
 379                goto out_err;
 380
 381        asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
 382        asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
 383                        ADVERTISE_ALL | ADVERTISE_CSMA);
 384        mii_nway_restart(dev);
 385
 386        if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
 387                goto out_err;
 388
 389        if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
 390                                AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
 391                                AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
 392                debug("Write IPG,IPG1,IPG2 failed\n");
 393                goto out_err;
 394        }
 395
 396        if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
 397                goto out_err;
 398
 399        do {
 400                link_detected = asix_mdio_read(dev, dev->phy_id, MII_BMSR) &
 401                        BMSR_LSTATUS;
 402                if (!link_detected) {
 403                        if (timeout == 0)
 404                                printf("Waiting for Ethernet connection... ");
 405                        udelay(TIMEOUT_RESOLUTION * 1000);
 406                        timeout += TIMEOUT_RESOLUTION;
 407                }
 408        } while (!link_detected && timeout < PHY_CONNECT_TIMEOUT);
 409        if (link_detected) {
 410                if (timeout != 0)
 411                        printf("done.\n");
 412        } else {
 413                printf("unable to connect.\n");
 414                goto out_err;
 415        }
 416
 417        return 0;
 418out_err:
 419        return -1;
 420}
 421
 422static int asix_send(struct eth_device *eth, volatile void *packet, int length)
 423{
 424        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 425        int err;
 426        u32 packet_len;
 427        int actual_len;
 428        unsigned char msg[PKTSIZE + sizeof(packet_len)];
 429
 430        debug("** %s(), len %d\n", __func__, length);
 431
 432        packet_len = (((length) ^ 0x0000ffff) << 16) + (length);
 433        cpu_to_le32s(&packet_len);
 434
 435        memcpy(msg, &packet_len, sizeof(packet_len));
 436        memcpy(msg + sizeof(packet_len), (void *)packet, length);
 437        if (length & 1)
 438                length++;
 439
 440        err = usb_bulk_msg(dev->pusb_dev,
 441                                usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
 442                                (void *)msg,
 443                                length + sizeof(packet_len),
 444                                &actual_len,
 445                                USB_BULK_SEND_TIMEOUT);
 446        debug("Tx: len = %u, actual = %u, err = %d\n",
 447                        length + sizeof(packet_len), actual_len, err);
 448
 449        return err;
 450}
 451
 452static int asix_recv(struct eth_device *eth)
 453{
 454        struct ueth_data *dev = (struct ueth_data *)eth->priv;
 455        static unsigned char  recv_buf[AX_RX_URB_SIZE];
 456        unsigned char *buf_ptr;
 457        int err;
 458        int actual_len;
 459        u32 packet_len;
 460
 461        debug("** %s()\n", __func__);
 462
 463        err = usb_bulk_msg(dev->pusb_dev,
 464                                usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
 465                                (void *)recv_buf,
 466                                AX_RX_URB_SIZE,
 467                                &actual_len,
 468                                USB_BULK_RECV_TIMEOUT);
 469        debug("Rx: len = %u, actual = %u, err = %d\n", AX_RX_URB_SIZE,
 470                actual_len, err);
 471        if (err != 0) {
 472                debug("Rx: failed to receive\n");
 473                return -1;
 474        }
 475        if (actual_len > AX_RX_URB_SIZE) {
 476                debug("Rx: received too many bytes %d\n", actual_len);
 477                return -1;
 478        }
 479
 480        buf_ptr = recv_buf;
 481        while (actual_len > 0) {
 482                /*
 483                 * 1st 4 bytes contain the length of the actual data as two
 484                 * complementary 16-bit words. Extract the length of the data.
 485                 */
 486                if (actual_len < sizeof(packet_len)) {
 487                        debug("Rx: incomplete packet length\n");
 488                        return -1;
 489                }
 490                memcpy(&packet_len, buf_ptr, sizeof(packet_len));
 491                le32_to_cpus(&packet_len);
 492                if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) {
 493                        debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
 494                              packet_len, (packet_len >> 16) ^ 0xffff,
 495                              packet_len & 0xffff);
 496                        return -1;
 497                }
 498                packet_len = packet_len & 0xffff;
 499                if (packet_len > actual_len - sizeof(packet_len)) {
 500                        debug("Rx: too large packet: %d\n", packet_len);
 501                        return -1;
 502                }
 503
 504                /* Notify net stack */
 505                NetReceive(buf_ptr + sizeof(packet_len), packet_len);
 506
 507                /* Adjust for next iteration. Packets are padded to 16-bits */
 508                if (packet_len & 1)
 509                        packet_len++;
 510                actual_len -= sizeof(packet_len) + packet_len;
 511                buf_ptr += sizeof(packet_len) + packet_len;
 512        }
 513
 514        return err;
 515}
 516
 517static void asix_halt(struct eth_device *eth)
 518{
 519        debug("** %s()\n", __func__);
 520}
 521
 522/*
 523 * Asix probing functions
 524 */
 525void asix_eth_before_probe(void)
 526{
 527        curr_eth_dev = 0;
 528}
 529
 530struct asix_dongle {
 531        unsigned short vendor;
 532        unsigned short product;
 533};
 534
 535static struct asix_dongle asix_dongles[] = {
 536        { 0x05ac, 0x1402 },     /* Apple USB Ethernet Adapter */
 537        { 0x07d1, 0x3c05 },     /* D-Link DUB-E100 H/W Ver B1 */
 538        { 0x0b95, 0x772a },     /* Cables-to-Go USB Ethernet Adapter */
 539        { 0x0b95, 0x7720 },     /* Trendnet TU2-ET100 V3.0R */
 540        { 0x0b95, 0x1720 },     /* SMC */
 541        { 0x0db0, 0xa877 },     /* MSI - ASIX 88772a */
 542        { 0x13b1, 0x0018 },     /* Linksys 200M v2.1 */
 543        { 0x1557, 0x7720 },     /* 0Q0 cable ethernet */
 544        { 0x2001, 0x3c05 },     /* DLink DUB-E100 H/W Ver B1 Alternate */
 545        { 0x0000, 0x0000 }      /* END - Do not remove */
 546};
 547
 548/* Probe to see if a new device is actually an asix device */
 549int asix_eth_probe(struct usb_device *dev, unsigned int ifnum,
 550                      struct ueth_data *ss)
 551{
 552        struct usb_interface *iface;
 553        struct usb_interface_descriptor *iface_desc;
 554        int i;
 555
 556        /* let's examine the device now */
 557        iface = &dev->config.if_desc[ifnum];
 558        iface_desc = &dev->config.if_desc[ifnum].desc;
 559
 560        for (i = 0; asix_dongles[i].vendor != 0; i++) {
 561                if (dev->descriptor.idVendor == asix_dongles[i].vendor &&
 562                    dev->descriptor.idProduct == asix_dongles[i].product)
 563                        /* Found a supported dongle */
 564                        break;
 565        }
 566
 567        if (asix_dongles[i].vendor == 0)
 568                return 0;
 569
 570        memset(ss, 0, sizeof(struct ueth_data));
 571
 572        /* At this point, we know we've got a live one */
 573        debug("\n\nUSB Ethernet device detected: %#04x:%#04x\n",
 574              dev->descriptor.idVendor, dev->descriptor.idProduct);
 575
 576        /* Initialize the ueth_data structure with some useful info */
 577        ss->ifnum = ifnum;
 578        ss->pusb_dev = dev;
 579        ss->subclass = iface_desc->bInterfaceSubClass;
 580        ss->protocol = iface_desc->bInterfaceProtocol;
 581
 582        /*
 583         * We are expecting a minimum of 3 endpoints - in, out (bulk), and
 584         * int. We will ignore any others.
 585         */
 586        for (i = 0; i < iface_desc->bNumEndpoints; i++) {
 587                /* is it an BULK endpoint? */
 588                if ((iface->ep_desc[i].bmAttributes &
 589                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
 590                        if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
 591                                ss->ep_in = iface->ep_desc[i].bEndpointAddress &
 592                                        USB_ENDPOINT_NUMBER_MASK;
 593                        else
 594                                ss->ep_out =
 595                                        iface->ep_desc[i].bEndpointAddress &
 596                                        USB_ENDPOINT_NUMBER_MASK;
 597                }
 598
 599                /* is it an interrupt endpoint? */
 600                if ((iface->ep_desc[i].bmAttributes &
 601                    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
 602                        ss->ep_int = iface->ep_desc[i].bEndpointAddress &
 603                                USB_ENDPOINT_NUMBER_MASK;
 604                        ss->irqinterval = iface->ep_desc[i].bInterval;
 605                }
 606        }
 607        debug("Endpoints In %d Out %d Int %d\n",
 608                  ss->ep_in, ss->ep_out, ss->ep_int);
 609
 610        /* Do some basic sanity checks, and bail if we find a problem */
 611        if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
 612            !ss->ep_in || !ss->ep_out || !ss->ep_int) {
 613                debug("Problems with device\n");
 614                return 0;
 615        }
 616        dev->privptr = (void *)ss;
 617        return 1;
 618}
 619
 620int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
 621                                struct eth_device *eth)
 622{
 623        if (!eth) {
 624                debug("%s: missing parameter.\n", __func__);
 625                return 0;
 626        }
 627        sprintf(eth->name, "%s%d", ASIX_BASE_NAME, curr_eth_dev++);
 628        eth->init = asix_init;
 629        eth->send = asix_send;
 630        eth->recv = asix_recv;
 631        eth->halt = asix_halt;
 632        eth->priv = ss;
 633
 634        return 1;
 635}
 636