~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/usb/eth/asix.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

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