asix.c 36.9 KB
Newer Older
1
2
/*
 * ASIX AX8817X based USB 2.0 Ethernet Devices
3
 * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com>
4
 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
5
 * Copyright (C) 2006 James Painter <jamie.painter@iname.com>
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * Copyright (c) 2002-2003 TiVo Inc.
 *
 * 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
 */

// #define	DEBUG			// error path messages, extra info
// #define	VERBOSE			// more; success messages

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/crc32.h>

#include "usbnet.h"

39
40
41
#define DRIVER_VERSION "14-Jun-2006"
static const char driver_name [] = "asix";

42
43
44
45
46
47
48
49
50
51
/* ASIX AX8817X based USB 2.0 Ethernet Devices */

#define AX_CMD_SET_SW_MII		0x06
#define AX_CMD_READ_MII_REG		0x07
#define AX_CMD_WRITE_MII_REG		0x08
#define AX_CMD_SET_HW_MII		0x0a
#define AX_CMD_READ_EEPROM		0x0b
#define AX_CMD_WRITE_EEPROM		0x0c
#define AX_CMD_WRITE_ENABLE		0x0d
#define AX_CMD_WRITE_DISABLE		0x0e
52
#define AX_CMD_READ_RX_CTL		0x0f
53
54
55
56
#define AX_CMD_WRITE_RX_CTL		0x10
#define AX_CMD_READ_IPG012		0x11
#define AX_CMD_WRITE_IPG0		0x12
#define AX_CMD_WRITE_IPG1		0x13
57
#define AX_CMD_READ_NODE_ID		0x13
58
59
#define AX_CMD_WRITE_IPG2		0x14
#define AX_CMD_WRITE_MULTI_FILTER	0x16
60
#define AX88172_CMD_READ_NODE_ID	0x17
61
62
63
64
65
#define AX_CMD_READ_PHY_ID		0x19
#define AX_CMD_READ_MEDIUM_STATUS	0x1a
#define AX_CMD_WRITE_MEDIUM_MODE	0x1b
#define AX_CMD_READ_MONITOR_MODE	0x1c
#define AX_CMD_WRITE_MONITOR_MODE	0x1d
66
#define AX_CMD_READ_GPIOS		0x1e
67
68
69
70
71
72
73
74
75
76
77
#define AX_CMD_WRITE_GPIOS		0x1f
#define AX_CMD_SW_RESET			0x20
#define AX_CMD_SW_PHY_STATUS		0x21
#define AX_CMD_SW_PHY_SELECT		0x22

#define AX_MONITOR_MODE			0x01
#define AX_MONITOR_LINK			0x02
#define AX_MONITOR_MAGIC		0x04
#define AX_MONITOR_HSFS			0x10

/* AX88172 Medium Status Register values */
78
79
80
81
82
#define AX88172_MEDIUM_FD		0x02
#define AX88172_MEDIUM_TX		0x04
#define AX88172_MEDIUM_FC		0x10
#define AX88172_MEDIUM_DEFAULT \
		( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC )
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#define AX_MCAST_FILTER_SIZE		8
#define AX_MAX_MCAST			64

#define AX_SWRESET_CLEAR		0x00
#define AX_SWRESET_RR			0x01
#define AX_SWRESET_RT			0x02
#define AX_SWRESET_PRTE			0x04
#define AX_SWRESET_PRL			0x08
#define AX_SWRESET_BZ			0x10
#define AX_SWRESET_IPRL			0x20
#define AX_SWRESET_IPPD			0x40

#define AX88772_IPG0_DEFAULT		0x15
#define AX88772_IPG1_DEFAULT		0x0c
#define AX88772_IPG2_DEFAULT		0x12

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* AX88772 & AX88178 Medium Mode Register */
#define AX_MEDIUM_PF		0x0080
#define AX_MEDIUM_JFE		0x0040
#define AX_MEDIUM_TFC		0x0020
#define AX_MEDIUM_RFC		0x0010
#define AX_MEDIUM_ENCK		0x0008
#define AX_MEDIUM_AC		0x0004
#define AX_MEDIUM_FD		0x0002
#define AX_MEDIUM_GM		0x0001
#define AX_MEDIUM_SM		0x1000
#define AX_MEDIUM_SBP		0x0800
#define AX_MEDIUM_PS		0x0200
#define AX_MEDIUM_RE		0x0100

#define AX88178_MEDIUM_DEFAULT	\
	(AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
	 AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
	 AX_MEDIUM_RE )
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#define AX88772_MEDIUM_DEFAULT	\
	(AX_MEDIUM_FD | AX_MEDIUM_RFC | \
	 AX_MEDIUM_TFC | AX_MEDIUM_PS | \
	 AX_MEDIUM_AC | AX_MEDIUM_RE )

/* AX88772 & AX88178 RX_CTL values */
#define AX_RX_CTL_SO			0x0080
#define AX_RX_CTL_AP			0x0020
#define AX_RX_CTL_AM			0x0010
#define AX_RX_CTL_AB			0x0008
#define AX_RX_CTL_SEP			0x0004
#define AX_RX_CTL_AMALL			0x0002
#define AX_RX_CTL_PRO			0x0001
#define AX_RX_CTL_MFB_2048		0x0000
#define AX_RX_CTL_MFB_4096		0x0100
#define AX_RX_CTL_MFB_8192		0x0200
#define AX_RX_CTL_MFB_16384		0x0300

#define AX_DEFAULT_RX_CTL	\
	(AX_RX_CTL_SO | AX_RX_CTL_AB )

/* GPIO 0 .. 2 toggles */
#define AX_GPIO_GPO0EN		0x01	/* GPIO0 Output enable */
#define AX_GPIO_GPO_0		0x02	/* GPIO0 Output value */
#define AX_GPIO_GPO1EN		0x04	/* GPIO1 Output enable */
#define AX_GPIO_GPO_1		0x08	/* GPIO1 Output value */
#define AX_GPIO_GPO2EN		0x10	/* GPIO2 Output enable */
#define AX_GPIO_GPO_2		0x20	/* GPIO2 Output value */
#define AX_GPIO_RESERVED	0x40	/* Reserved */
#define AX_GPIO_RSE		0x80	/* Reload serial EEPROM */

#define AX_EEPROM_MAGIC		0xdeadbeef
#define AX88172_EEPROM_LEN	0x40
#define AX88772_EEPROM_LEN	0xff

#define PHY_MODE_MARVELL	0x0000
#define MII_MARVELL_LED_CTRL	0x0018
#define MII_MARVELL_STATUS	0x001b
#define MII_MARVELL_CTRL	0x0014

#define MARVELL_LED_MANUAL	0x0019

#define MARVELL_STATUS_HWCFG	0x0004

#define MARVELL_CTRL_TXDELAY	0x0002
#define MARVELL_CTRL_RXDELAY	0x0080
165
166

/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
167
struct asix_data {
168
	u8 multi_filter[AX_MCAST_FILTER_SIZE];
169
170
171
	u8 phymode;
	u8 ledmode;
	u8 eeprom_len;
172
173
174
175
176
177
178
179
180
181
};

struct ax88172_int_data {
	u16 res1;
	u8 link;
	u16 res2;
	u8 status;
	u16 res3;
} __attribute__ ((packed));

182
static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
183
184
			    u16 size, void *data)
{
185
186
	devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
		cmd, value, index, size);
187
188
189
190
191
192
193
194
195
196
197
198
	return usb_control_msg(
		dev->udev,
		usb_rcvctrlpipe(dev->udev, 0),
		cmd,
		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		value,
		index,
		data,
		size,
		USB_CTRL_GET_TIMEOUT);
}

199
static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
200
201
			     u16 size, void *data)
{
202
203
	devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
		cmd, value, index, size);
204
205
206
207
208
209
210
211
212
213
214
215
	return usb_control_msg(
		dev->udev,
		usb_sndctrlpipe(dev->udev, 0),
		cmd,
		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		value,
		index,
		data,
		size,
		USB_CTRL_SET_TIMEOUT);
}

216
static void asix_async_cmd_callback(struct urb *urb)
217
218
219
220
{
	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;

	if (urb->status < 0)
221
		printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d",
222
223
224
225
226
227
			urb->status);

	kfree(req);
	usb_free_urb(urb);
}

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
static void
asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
				    u16 size, void *data)
{
	struct usb_ctrlrequest *req;
	int status;
	struct urb *urb;

	devdbg(dev,"asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
		cmd, value, index, size);
	if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
		deverr(dev, "Error allocating URB in write_cmd_async!");
		return;
	}

	if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
		deverr(dev, "Failed to allocate memory for control request");
		usb_free_urb(urb);
		return;
	}

	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
	req->bRequest = cmd;
Oliver Neukum's avatar
Oliver Neukum committed
251
252
253
	req->wValue = cpu_to_le16(value);
	req->wIndex = cpu_to_le16(index);
	req->wLength = cpu_to_le16(size);
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

	usb_fill_control_urb(urb, dev->udev,
			     usb_sndctrlpipe(dev->udev, 0),
			     (void *)req, data, size,
			     asix_async_cmd_callback, req);

	if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
		deverr(dev, "Error submitting the control message: status=%d",
				status);
		kfree(req);
		usb_free_urb(urb);
	}
}

static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
	u8  *head;
	u32  header;
	char *packet;
	struct sk_buff *ax_skb;
	u16 size;

	head = (u8 *) skb->data;
	memcpy(&header, head, sizeof(header));
	le32_to_cpus(&header);
	packet = head + sizeof(header);

	skb_pull(skb, 4);

	while (skb->len > 0) {
		if ((short)(header & 0x0000ffff) !=
		    ~((short)((header & 0xffff0000) >> 16))) {
			deverr(dev,"asix_rx_fixup() Bad Header Length");
		}
		/* get the packet length */
		size = (u16) (header & 0x0000ffff);

		if ((skb->len) - ((size + 1) & 0xfffe) == 0)
			return 2;
		if (size > ETH_FRAME_LEN) {
			deverr(dev,"asix_rx_fixup() Bad RX Length %d", size);
			return 0;
		}
		ax_skb = skb_clone(skb, GFP_ATOMIC);
		if (ax_skb) {
			ax_skb->len = size;
			ax_skb->data = packet;
301
			skb_set_tail_pointer(ax_skb, size);
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
			usbnet_skb_return(dev, ax_skb);
		} else {
			return 0;
		}

		skb_pull(skb, (size + 1) & 0xfffe);

		if (skb->len == 0)
			break;

		head = (u8 *) skb->data;
		memcpy(&header, head, sizeof(header));
		le32_to_cpus(&header);
		packet = head + sizeof(header);
		skb_pull(skb, 4);
	}

	if (skb->len < 0) {
		deverr(dev,"asix_rx_fixup() Bad SKB Length %d", skb->len);
		return 0;
	}
	return 1;
}

static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
					gfp_t flags)
{
	int padlen;
	int headroom = skb_headroom(skb);
	int tailroom = skb_tailroom(skb);
	u32 packet_len;
	u32 padbytes = 0xffff0000;

	padlen = ((skb->len + 4) % 512) ? 0 : 4;

	if ((!skb_cloned(skb))
	    && ((headroom + tailroom) >= (4 + padlen))) {
		if ((headroom < 4) || (tailroom < padlen)) {
			skb->data = memmove(skb->head + 4, skb->data, skb->len);
341
			skb_set_tail_pointer(skb, skb->len);
342
343
344
345
346
347
348
349
350
351
352
353
		}
	} else {
		struct sk_buff *skb2;
		skb2 = skb_copy_expand(skb, 4, padlen, flags);
		dev_kfree_skb_any(skb);
		skb = skb2;
		if (!skb)
			return NULL;
	}

	skb_push(skb, 4);
	packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
354
	cpu_to_le32s(&packet_len);
355
	skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
356
357

	if ((skb->len % 512) == 0) {
358
		cpu_to_le32s(&padbytes);
359
		memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
		skb_put(skb, sizeof(padbytes));
	}
	return skb;
}

static void asix_status(struct usbnet *dev, struct urb *urb)
{
	struct ax88172_int_data *event;
	int link;

	if (urb->actual_length < 8)
		return;

	event = urb->transfer_buffer;
	link = event->link & 0x01;
	if (netif_carrier_ok(dev->net) != link) {
		if (link) {
			netif_carrier_on(dev->net);
			usbnet_defer_kevent (dev, EVENT_LINK_RESET );
		} else
			netif_carrier_off(dev->net);
		devdbg(dev, "Link Status is: %d", link);
	}
}

385
386
387
388
389
static inline int asix_set_sw_mii(struct usbnet *dev)
{
	int ret;
	ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
	if (ret < 0)
390
		deverr(dev, "Failed to enable software MII access");
391
392
393
394
395
396
397
398
	return ret;
}

static inline int asix_set_hw_mii(struct usbnet *dev)
{
	int ret;
	ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
	if (ret < 0)
399
		deverr(dev, "Failed to enable hardware MII access");
400
401
402
	return ret;
}

403
static inline int asix_get_phy_addr(struct usbnet *dev)
404
405
406
407
{
	int ret = 0;
	void *buf;

408
409
	devdbg(dev, "asix_get_phy_addr()");

410
411
412
413
414
415
	buf = kmalloc(2, GFP_KERNEL);
	if (!buf)
		goto out1;

	if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID,
				    0, 0, 2, buf)) < 2) {
416
		deverr(dev, "Error reading PHYID register: %02x", ret);
417
418
		goto out2;
	}
419
	devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((u16 *)buf));
420
421
422
423
424
425
426
427
428
429
430
431
432
	ret = *((u8 *)buf + 1);
out2:
	kfree(buf);
out1:
	return ret;
}

static int asix_sw_reset(struct usbnet *dev, u8 flags)
{
	int ret;

        ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
	if (ret < 0)
433
434
435
436
		deverr(dev,"Failed to send software reset: %02x", ret);

	return ret;
}
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
static u16 asix_read_rx_ctl(struct usbnet *dev)
{
	u16 ret = 0;
	void *buf;

	buf = kmalloc(2, GFP_KERNEL);
	if (!buf)
		goto out1;

	if ((ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL,
				    0, 0, 2, buf)) < 2) {
		deverr(dev, "Error reading RX_CTL register: %02x", ret);
		goto out2;
	}
	ret = le16_to_cpu(*((u16 *)buf));
out2:
	kfree(buf);
out1:
456
457
458
459
460
461
462
	return ret;
}

static int asix_write_rx_ctl(struct usbnet *dev, u16 mode)
{
	int ret;

463
	devdbg(dev,"asix_write_rx_ctl() - mode = 0x%04x", mode);
464
465
	ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
	if (ret < 0)
466
467
		deverr(dev, "Failed to write RX_CTL mode to 0x%04x: %02x",
		       mode, ret);
468
469
470
471

	return ret;
}

472
static u16 asix_read_medium_status(struct usbnet *dev)
473
{
474
475
	u16 ret = 0;
	void *buf;
476

477
478
479
	buf = kmalloc(2, GFP_KERNEL);
	if (!buf)
		goto out1;
480

481
482
483
484
	if ((ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS,
				    0, 0, 2, buf)) < 2) {
		deverr(dev, "Error reading Medium Status register: %02x", ret);
		goto out2;
485
	}
486
487
488
489
490
	ret = le16_to_cpu(*((u16 *)buf));
out2:
	kfree(buf);
out1:
	return ret;
491
492
}

493
static int asix_write_medium_mode(struct usbnet *dev, u16 mode)
494
{
495
	int ret;
496

497
498
499
500
501
	devdbg(dev,"asix_write_medium_mode() - mode = 0x%04x", mode);
	ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
	if (ret < 0)
		deverr(dev, "Failed to write Medium Mode mode to 0x%04x: %02x",
			mode, ret);
502

503
504
	return ret;
}
505

506
507
508
static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep)
{
	int ret;
509

510
511
512
513
514
	devdbg(dev,"asix_write_gpio() - value = 0x%04x", value);
	ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
	if (ret < 0)
		deverr(dev, "Failed to write GPIO value 0x%04x: %02x",
			value, ret);
515

516
517
518
519
	if (sleep)
		msleep(sleep);

	return ret;
520
521
}

522
523
524
/*
 * AX88772 & AX88178 have a 16-bit RX_CTL value
 */
525
static void asix_set_multicast(struct net_device *net)
526
527
{
	struct usbnet *dev = netdev_priv(net);
528
	struct asix_data *data = (struct asix_data *)&dev->data;
529
	u16 rx_ctl = AX_DEFAULT_RX_CTL;
530
531

	if (net->flags & IFF_PROMISC) {
532
		rx_ctl |= AX_RX_CTL_PRO;
533
534
	} else if (net->flags & IFF_ALLMULTI
		   || net->mc_count > AX_MAX_MCAST) {
535
		rx_ctl |= AX_RX_CTL_AMALL;
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
	} else if (net->mc_count == 0) {
		/* just broadcast and directed */
	} else {
		/* We use the 20 byte dev->data
		 * for our 8 byte filter buffer
		 * to avoid allocating memory that
		 * is tricky to free later */
		struct dev_mc_list *mc_list = net->mc_list;
		u32 crc_bits;
		int i;

		memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);

		/* Build the multicast hash filter. */
		for (i = 0; i < net->mc_count; i++) {
			crc_bits =
			    ether_crc(ETH_ALEN,
				      mc_list->dmi_addr) >> 26;
			data->multi_filter[crc_bits >> 3] |=
			    1 << (crc_bits & 7);
			mc_list = mc_list->next;
		}

559
		asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
560
561
				   AX_MCAST_FILTER_SIZE, data->multi_filter);

562
		rx_ctl |= AX_RX_CTL_AM;
563
564
	}

565
	asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
566
567
}

568
static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
569
570
571
572
{
	struct usbnet *dev = netdev_priv(netdev);
	u16 res;

573
	mutex_lock(&dev->phy_mutex);
574
575
	asix_set_sw_mii(dev);
	asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
576
				(__u16)loc, 2, (u16 *)&res);
577
	asix_set_hw_mii(dev);
578
	mutex_unlock(&dev->phy_mutex);
579

580
	devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff));
581

582
	return le16_to_cpu(res & 0xffff);
583
584
585
}

static void
586
asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
587
588
{
	struct usbnet *dev = netdev_priv(netdev);
589
	u16 res = cpu_to_le16(val);
590

591
	devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
592
	mutex_lock(&dev->phy_mutex);
593
594
	asix_set_sw_mii(dev);
	asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
595
				(__u16)loc, 2, (u16 *)&res);
596
	asix_set_hw_mii(dev);
597
	mutex_unlock(&dev->phy_mutex);
598
599
}

600
601
/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
static u32 asix_get_phyid(struct usbnet *dev)
602
{
603
604
	int phy_reg;
	u32 phy_id;
605

606
607
608
	phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
	if (phy_reg < 0)
		return 0;
609

610
	phy_id = (phy_reg & 0xffff) << 16;
611

612
613
614
615
616
617
618
	phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2);
	if (phy_reg < 0)
		return 0;

	phy_id |= (phy_reg & 0xffff);

	return phy_id;
619
620
621
}

static void
622
asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
623
624
625
626
{
	struct usbnet *dev = netdev_priv(net);
	u8 opt;

627
	if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
		wolinfo->supported = 0;
		wolinfo->wolopts = 0;
		return;
	}
	wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
	wolinfo->wolopts = 0;
	if (opt & AX_MONITOR_MODE) {
		if (opt & AX_MONITOR_LINK)
			wolinfo->wolopts |= WAKE_PHY;
		if (opt & AX_MONITOR_MAGIC)
			wolinfo->wolopts |= WAKE_MAGIC;
	}
}

static int
643
asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
644
645
646
647
648
649
650
651
652
653
654
655
{
	struct usbnet *dev = netdev_priv(net);
	u8 opt = 0;
	u8 buf[1];

	if (wolinfo->wolopts & WAKE_PHY)
		opt |= AX_MONITOR_LINK;
	if (wolinfo->wolopts & WAKE_MAGIC)
		opt |= AX_MONITOR_MAGIC;
	if (opt != 0)
		opt |= AX_MONITOR_MODE;

656
	if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
657
658
659
660
661
662
			      opt, 0, 0, &buf) < 0)
		return -EINVAL;

	return 0;
}

663
static int asix_get_eeprom_len(struct net_device *net)
664
{
665
666
667
668
	struct usbnet *dev = netdev_priv(net);
	struct asix_data *data = (struct asix_data *)&dev->data;

	return data->eeprom_len;
669
670
}

671
static int asix_get_eeprom(struct net_device *net,
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
			      struct ethtool_eeprom *eeprom, u8 *data)
{
	struct usbnet *dev = netdev_priv(net);
	u16 *ebuf = (u16 *)data;
	int i;

	/* Crude hack to ensure that we don't overwrite memory
	 * if an odd length is supplied
	 */
	if (eeprom->len % 2)
		return -EINVAL;

	eeprom->magic = AX_EEPROM_MAGIC;

	/* ax8817x returns 2 bytes from eeprom on read */
	for (i=0; i < eeprom->len / 2; i++) {
688
		if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
689
690
691
692
693
694
			eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
			return -EINVAL;
	}
	return 0;
}

695
static void asix_get_drvinfo (struct net_device *net,
696
697
				 struct ethtool_drvinfo *info)
{
698
699
700
	struct usbnet *dev = netdev_priv(net);
	struct asix_data *data = (struct asix_data *)&dev->data;

701
702
	/* Inherit standard device info */
	usbnet_get_drvinfo(net, info);
703
704
705
	strncpy (info->driver, driver_name, sizeof info->driver);
	strncpy (info->version, DRIVER_VERSION, sizeof info->version);
	info->eedump_len = data->eeprom_len;
706
707
}

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
static u32 asix_get_link(struct net_device *net)
{
	struct usbnet *dev = netdev_priv(net);

	return mii_link_ok(&dev->mii);
}

static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
{
	struct usbnet *dev = netdev_priv(net);

	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}

/* We need to override some ethtool_ops so we require our
   own structure so we don't interfere with other usbnet
   devices that may be connected at the same time. */
static struct ethtool_ops ax88172_ethtool_ops = {
	.get_drvinfo		= asix_get_drvinfo,
	.get_link		= asix_get_link,
	.get_msglevel		= usbnet_get_msglevel,
729
	.set_msglevel		= usbnet_set_msglevel,
730
731
732
733
	.get_wol		= asix_get_wol,
	.set_wol		= asix_set_wol,
	.get_eeprom_len		= asix_get_eeprom_len,
	.get_eeprom		= asix_get_eeprom,
734
735
736
	.get_settings		= usbnet_get_settings,
	.set_settings		= usbnet_set_settings,
	.nway_reset		= usbnet_nway_reset,
737
738
};

739
static void ax88172_set_multicast(struct net_device *net)
740
741
{
	struct usbnet *dev = netdev_priv(net);
742
743
	struct asix_data *data = (struct asix_data *)&dev->data;
	u8 rx_ctl = 0x8c;
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
	if (net->flags & IFF_PROMISC) {
		rx_ctl |= 0x01;
	} else if (net->flags & IFF_ALLMULTI
		   || net->mc_count > AX_MAX_MCAST) {
		rx_ctl |= 0x02;
	} else if (net->mc_count == 0) {
		/* just broadcast and directed */
	} else {
		/* We use the 20 byte dev->data
		 * for our 8 byte filter buffer
		 * to avoid allocating memory that
		 * is tricky to free later */
		struct dev_mc_list *mc_list = net->mc_list;
		u32 crc_bits;
		int i;

		memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);

		/* Build the multicast hash filter. */
		for (i = 0; i < net->mc_count; i++) {
			crc_bits =
			    ether_crc(ETH_ALEN,
				      mc_list->dmi_addr) >> 26;
			data->multi_filter[crc_bits >> 3] |=
			    1 << (crc_bits & 7);
			mc_list = mc_list->next;
		}

		asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
				   AX_MCAST_FILTER_SIZE, data->multi_filter);

		rx_ctl |= 0x10;
	}

	asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
}

static int ax88172_link_reset(struct usbnet *dev)
{
	u8 mode;
	struct ethtool_cmd ecmd;

	mii_check_media(&dev->mii, 1, 1);
	mii_ethtool_gset(&dev->mii, &ecmd);
	mode = AX88172_MEDIUM_DEFAULT;

	if (ecmd.duplex != DUPLEX_FULL)
		mode |= ~AX88172_MEDIUM_FD;

	devdbg(dev, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);

	asix_write_medium_mode(dev, mode);

	return 0;
799
800
}

801
static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
802
803
804
805
806
{
	int ret = 0;
	void *buf;
	int i;
	unsigned long gpio_bits = dev->driver_info->data;
807
808
809
	struct asix_data *data = (struct asix_data *)&dev->data;

	data->eeprom_len = AX88172_EEPROM_LEN;
810
811
812
813
814
815
816
817
818
819
820

	usbnet_get_endpoints(dev,intf);

	buf = kmalloc(ETH_ALEN, GFP_KERNEL);
	if(!buf) {
		ret = -ENOMEM;
		goto out1;
	}

	/* Toggle the GPIOs in a manufacturer/model specific way */
	for (i = 2; i >= 0; i--) {
821
		if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS,
822
823
824
825
826
827
					(gpio_bits >> (i * 8)) & 0xff, 0, 0,
					buf)) < 0)
			goto out2;
		msleep(5);
	}

828
	if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0)
829
830
831
832
		goto out2;

	/* Get the MAC address */
	memset(buf, 0, ETH_ALEN);
833
	if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID,
834
835
836
837
838
839
840
841
				0, 0, 6, buf)) < 0) {
		dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
		goto out2;
	}
	memcpy(dev->net->dev_addr, buf, ETH_ALEN);

	/* Initialize MII structure */
	dev->mii.dev = dev->net;
842
843
	dev->mii.mdio_read = asix_mdio_read;
	dev->mii.mdio_write = asix_mdio_write;
844
845
	dev->mii.phy_id_mask = 0x3f;
	dev->mii.reg_num_mask = 0x1f;
846
	dev->mii.phy_id = asix_get_phy_addr(dev);
847
	dev->net->do_ioctl = asix_ioctl;
848

849
	dev->net->set_multicast_list = ax88172_set_multicast;
850
	dev->net->ethtool_ops = &ax88172_ethtool_ops;
851

852
853
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
854
855
856
857
858
859
860
861
862
863
864
		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
	mii_nway_restart(&dev->mii);

	return 0;
out2:
	kfree(buf);
out1:
	return ret;
}

static struct ethtool_ops ax88772_ethtool_ops = {
865
	.get_drvinfo		= asix_get_drvinfo,
866
	.get_link		= asix_get_link,
867
868
	.get_msglevel		= usbnet_get_msglevel,
	.set_msglevel		= usbnet_set_msglevel,
869
870
871
872
	.get_wol		= asix_get_wol,
	.set_wol		= asix_set_wol,
	.get_eeprom_len		= asix_get_eeprom_len,
	.get_eeprom		= asix_get_eeprom,
873
874
875
	.get_settings		= usbnet_get_settings,
	.set_settings		= usbnet_set_settings,
	.nway_reset		= usbnet_nway_reset,
876
877
};

878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
static int ax88772_link_reset(struct usbnet *dev)
{
	u16 mode;
	struct ethtool_cmd ecmd;

	mii_check_media(&dev->mii, 1, 1);
	mii_ethtool_gset(&dev->mii, &ecmd);
	mode = AX88772_MEDIUM_DEFAULT;

	if (ecmd.speed != SPEED_100)
		mode &= ~AX_MEDIUM_PS;

	if (ecmd.duplex != DUPLEX_FULL)
		mode &= ~AX_MEDIUM_FD;

	devdbg(dev, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);

	asix_write_medium_mode(dev, mode);

	return 0;
}

900
901
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
902
	int ret, embd_phy;
903
	void *buf;
904
905
906
907
908
	u16 rx_ctl;
	struct asix_data *data = (struct asix_data *)&dev->data;
	u32 phyid;

	data->eeprom_len = AX88772_EEPROM_LEN;
909
910
911
912
913
914
915
916
917
918

	usbnet_get_endpoints(dev,intf);

	buf = kmalloc(6, GFP_KERNEL);
	if(!buf) {
		dbg ("Cannot allocate memory for buffer");
		ret = -ENOMEM;
		goto out1;
	}

919
920
	if ((ret = asix_write_gpio(dev,
			AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
921
922
		goto out2;

923
924
	/* 0x10 is the phy id of the embedded 10/100 ethernet phy */
	embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
925
	if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
926
				embd_phy, 0, 0, buf)) < 0) {
927
928
929
930
		dbg("Select PHY #1 failed: %d", ret);
		goto out2;
	}

931
	if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0)
932
933
934
		goto out2;

	msleep(150);
935
	if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0)
936
937
938
		goto out2;

	msleep(150);
939
940
941
942
943
944
945
946
	if (embd_phy) {
		if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0)
			goto out2;
	}
	else {
		if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0)
			goto out2;
	}
947
948

	msleep(150);
949
950
951
	rx_ctl = asix_read_rx_ctl(dev);
	dbg("RX_CTL is 0x%04x after software reset", rx_ctl);
	if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0)
952
953
		goto out2;

954
955
956
	rx_ctl = asix_read_rx_ctl(dev);
	dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);

957
958
	/* Get the MAC address */
	memset(buf, 0, ETH_ALEN);
959
	if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
960
961
962
963
964
965
966
967
				0, 0, ETH_ALEN, buf)) < 0) {
		dbg("Failed to read MAC address: %d", ret);
		goto out2;
	}
	memcpy(dev->net->dev_addr, buf, ETH_ALEN);

	/* Initialize MII structure */
	dev->mii.dev = dev->net;
968
969
	dev->mii.mdio_read = asix_mdio_read;
	dev->mii.mdio_write = asix_mdio_write;
970
971
	dev->mii.phy_id_mask = 0x1f;
	dev->mii.reg_num_mask = 0x1f;
972
	dev->net->do_ioctl = asix_ioctl;
973
974
975
976
	dev->mii.phy_id = asix_get_phy_addr(dev);

	phyid = asix_get_phyid(dev);
	dbg("PHYID=0x%08x", phyid);
977

978
	if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0)
979
980
981
		goto out2;

	msleep(150);
982
983

	if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0)
984
985
		goto out2;

986
	msleep(150);
987

988
	dev->net->set_multicast_list = asix_set_multicast;
989
990
	dev->net->ethtool_ops = &ax88772_ethtool_ops;

991
992
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
993
994
995
			ADVERTISE_ALL | ADVERTISE_CSMA);
	mii_nway_restart(&dev->mii);

996
	if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0)
997
998
		goto out2;

999
	if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
1000
1001
1002
1003
1004
1005
1006
				AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
				AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
		dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
		goto out2;
	}

	/* Set RX_CTL to default values with 2k buffer, and enable cactus */
1007
	if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
1008
1009
		goto out2;

1010
1011
1012
1013
1014
1015
	rx_ctl = asix_read_rx_ctl(dev);
	dbg("RX_CTL is 0x%04x after all initializations", rx_ctl);

	rx_ctl = asix_read_medium_status(dev);
	dbg("Medium Status is 0x%04x after all initializations", rx_ctl);

1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
	kfree(buf);

	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
	if (dev->driver_info->flags & FLAG_FRAMING_AX) {
		/* hard_mtu  is still the default - the device does not support
		   jumbo eth frames */
		dev->rx_urb_size = 2048;
	}

	return 0;

out2:
	kfree(buf);
out1:
	return ret;
}

1033
1034
1035
1036
1037
1038
1039
1040
1041
static struct ethtool_ops ax88178_ethtool_ops = {
	.get_drvinfo		= asix_get_drvinfo,
	.get_link		= asix_get_link,
	.get_msglevel		= usbnet_get_msglevel,
	.set_msglevel		= usbnet_set_msglevel,
	.get_wol		= asix_get_wol,
	.set_wol		= asix_set_wol,
	.get_eeprom_len		= asix_get_eeprom_len,
	.get_eeprom		= asix_get_eeprom,
1042
1043
1044
	.get_settings		= usbnet_get_settings,
	.set_settings		= usbnet_set_settings,
	.nway_reset		= usbnet_nway_reset,
1045
1046
1047
};

static int marvell_phy_init(struct usbnet *dev)
1048
{
1049
1050
	struct asix_data *data = (struct asix_data *)&dev->data;
	u16 reg;
1051

1052
	devdbg(dev,"marvell_phy_init()");
1053

1054
1055
	reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS);
	devdbg(dev,"MII_MARVELL_STATUS = 0x%04x", reg);
1056

1057
1058
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL,
			MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);
1059

1060
1061
1062
1063
	if (data->ledmode) {
		reg = asix_mdio_read(dev->net, dev->mii.phy_id,
			MII_MARVELL_LED_CTRL);
		devdbg(dev,"MII_MARVELL_LED_CTRL (1) = 0x%04x", reg);
1064

1065
1066
1067
1068
		reg &= 0xf8ff;
		reg |= (1 + 0x0100);
		asix_mdio_write(dev->net, dev->mii.phy_id,
			MII_MARVELL_LED_CTRL, reg);
1069

1070
1071
1072
1073
1074
		reg = asix_mdio_read(dev->net, dev->mii.phy_id,
			MII_MARVELL_LED_CTRL);
		devdbg(dev,"MII_MARVELL_LED_CTRL (2) = 0x%04x", reg);
		reg &= 0xfc0f;
	}
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
	return 0;
}

static int marvell_led_status(struct usbnet *dev, u16 speed)
{
	u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL);

	devdbg(dev, "marvell_led_status() read 0x%04x", reg);

	/* Clear out the center LED bits - 0x03F0 */
	reg &= 0xfc0f;

	switch (speed) {
		case SPEED_1000:
			reg |= 0x03e0;
			break;
		case SPEED_100:
			reg |= 0x03b0;
			break;
		default:
			reg |= 0x02f0;
1097
1098
	}

1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
	devdbg(dev, "marvell_led_status() writing 0x%04x", reg);
	asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg);

	return 0;
}

static int ax88178_link_reset(struct usbnet *dev)
{
	u16 mode;
	struct ethtool_cmd ecmd;
	struct asix_data *data = (struct asix_data *)&dev->data;

	devdbg(dev,"ax88178_link_reset()");

	mii_check_media(&dev->mii, 1, 1);
	mii_ethtool_gset(&dev->mii, &ecmd);
	mode = AX88178_MEDIUM_DEFAULT;

	if (ecmd.speed == SPEED_1000)
		mode |= AX_MEDIUM_GM | AX_MEDIUM_ENCK;
	else if (ecmd.speed == SPEED_100)
		mode |= AX_MEDIUM_PS;
	else
		mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);

	if (ecmd.duplex == DUPLEX_FULL)
		mode |= AX_MEDIUM_FD;
	else
		mode &= ~AX_MEDIUM_FD;

	devdbg(dev, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode);

	asix_write_medium_mode(dev, mode);

	if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
		marvell_led_status(dev, ecmd.speed);

	return 0;
}

static void ax88178_set_mfb(struct usbnet *dev)
{
	u16 mfb = AX_RX_CTL_MFB_16384;
	u16 rxctl;
	u16 medium;
	int old_rx_urb_size = dev->rx_urb_size;

	if (dev->hard_mtu < 2048) {
		dev->rx_urb_size = 2048;
		mfb = AX_RX_CTL_MFB_2048;
	} else if (dev->hard_mtu < 4096) {
		dev->rx_urb_size = 4096;
		mfb = AX_RX_CTL_MFB_4096;
	} else if (dev->hard_mtu < 8192) {
		dev->rx_urb_size = 8192;
		mfb = AX_RX_CTL_MFB_8192;
	} else if (dev->hard_mtu < 16384) {
		dev->rx_urb_size = 16384;
		mfb = AX_RX_CTL_MFB_16384;
1158
	}
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

	rxctl = asix_read_rx_ctl(dev);
	asix_write_rx_ctl(dev, (rxctl & ~AX_RX_CTL_MFB_16384) | mfb);

	medium = asix_read_medium_status(dev);
	if (dev->net->mtu > 1500)
		medium |= AX_MEDIUM_JFE;
	else
		medium &= ~AX_MEDIUM_JFE;
	asix_write_medium_mode(dev, medium);

	if (dev->rx_urb_size > old_rx_urb_size)
		usbnet_unlink_rx_urbs(dev);
1172
1173
}

1174
static int ax88178_change_mtu(struct net_device *net, int new_mtu)
1175
{
1176
1177
	struct usbnet *dev = netdev_priv(net);
	int ll_mtu = new_mtu + net->hard_header_len + 4;
1178

1179
	devdbg(dev, "ax88178_change_mtu() new_mtu=%d", new_mtu);
1180

1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
	if (new_mtu <= 0 || ll_mtu > 16384)
		return -EINVAL;

	if ((ll_mtu % dev->maxpacket) == 0)
		return -EDOM;

	net->mtu = new_mtu;
	dev->hard_mtu = net->mtu + net->hard_header_len;
	ax88178_set_mfb(dev);

	return 0;
}

static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
{
	struct asix_data *data = (struct asix_data *)&dev->data;
	int ret;
	void *buf;
	u16 eeprom;
	int gpio0 = 0;
	u32 phyid;

	usbnet_get_endpoints(dev,intf);

	buf = kmalloc(6, GFP_KERNEL);
	if(!buf) {
		dbg ("Cannot allocate memory for buffer");
		ret = -ENOMEM;
		goto out1;
	}

	eeprom = 0;
	asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &eeprom);
	dbg("GPIO Status: 0x%04x", eeprom);

	asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
	asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
	asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);

	dbg("EEPROM index 0x17 is 0x%04x", eeprom);

	if (eeprom == 0xffff) {
		data->phymode = PHY_MODE_MARVELL;
		data->ledmode = 0;
		gpio0 = 1;
1226
	} else {
1227
1228
1229
		data->phymode = eeprom & 7;
		data->ledmode = eeprom >> 8;
		gpio0 = (eeprom & 0x80) ? 0 : 1;
1230
	}
1231
	dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
1232

1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
	asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
	if ((eeprom >> 8) != 1) {
		asix_write_gpio(dev, 0x003c, 30);
		asix_write_gpio(dev, 0x001c, 300);
		asix_write_gpio(dev, 0x003c, 30);
	} else {
		dbg("gpio phymode == 1 path");
		asix_write_gpio(dev, AX_GPIO_GPO1EN, 30);
		asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
	}
1243

1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
	asix_sw_reset(dev, 0);
	msleep(150);

	asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
	msleep(150);

	asix_write_rx_ctl(dev, 0);

	/* Get the MAC address */
	memset(buf, 0, ETH_ALEN);
	if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
				0, 0, ETH_ALEN, buf)) < 0) {
		dbg("Failed to read MAC address: %d", ret);
		goto out2;
1258
	}
1259
	memcpy(dev->net->dev_addr, buf, ETH_ALEN);
1260

1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
	/* Initialize MII structure */
	dev->mii.dev = dev->net;
	dev->mii.mdio_read = asix_mdio_read;
	dev->mii.mdio_write = asix_mdio_write;
	dev->mii.phy_id_mask = 0x1f;
	dev->mii.reg_num_mask = 0xff;
	dev->mii.supports_gmii = 1;
	dev->net->do_ioctl = asix_ioctl;
	dev->mii.phy_id = asix_get_phy_addr(dev);
	dev->net->set_multicast_list = asix_set_multicast;
	dev->net->ethtool_ops = &ax88178_ethtool_ops;
	dev->net->change_mtu = &ax88178_change_mtu;
1273

1274
1275
	phyid = asix_get_phyid(dev);
	dbg("PHYID=0x%08x", phyid);
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
	if (data->phymode == PHY_MODE_MARVELL) {
		marvell_phy_init(dev);
		msleep(60);
	}

	asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
			BMCR_RESET | BMCR_ANENABLE);
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
			ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
	asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
			ADVERTISE_1000FULL);

	mii_nway_restart(&dev->mii);

	if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0)
		goto out2;

	if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
		goto out2;

	kfree(buf);

	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
	if (dev->driver_info->flags & FLAG_FRAMING_AX) {
		/* hard_mtu  is still the default - the device does not support
		   jumbo eth frames */
		dev->rx_urb_size = 2048;
	}
1305
1306

	return 0;
1307
1308
1309
1310
1311

out2:
	kfree(buf);
out1:
	return ret;
1312
1313
1314
1315
}

static const struct driver_info ax8817x_info = {
	.description = "ASIX AX8817x USB 2.0 Ethernet",
1316
1317
	.bind = ax88172_bind,
	.status = asix_status,
1318
1319
1320
1321
1322
1323
1324
1325
	.link_reset = ax88172_link_reset,
	.reset = ax88172_link_reset,
	.flags =  FLAG_ETHER,
	.data = 0x00130103,
};

static const struct driver_info dlink_dub_e100_info = {
	.description = "DLink DUB-E100 USB Ethernet",
1326
1327
	.bind = ax88172_bind,
	.status = asix_status,
1328
1329
1330
1331
1332
1333
1334
1335
	.link_reset = ax88172_link_reset,
	.reset = ax88172_link_reset,
	.flags =  FLAG_ETHER,
	.data = 0x009f9d9f,
};

static const struct driver_info netgear_fa120_info = {
	.description = "Netgear FA-120 USB Ethernet",
1336
1337
	.bind = ax88172_bind,
	.status = asix_status,
1338
1339
1340
1341
1342
1343
1344
1345
	.link_reset = ax88172_link_reset,
	.reset = ax88172_link_reset,
	.flags =  FLAG_ETHER,
	.data = 0x00130103,
};

static const struct driver_info hawking_uf200_info = {
	.description = "Hawking UF200 USB Ethernet",
1346
1347
	.bind = ax88172_bind,
	.status = asix_status,
1348
1349
1350
1351
1352
1353
1354
1355
1356
	.link_reset = ax88172_link_reset,
	.reset = ax88172_link_reset,
	.flags =  FLAG_ETHER,
	.data = 0x001f1d1f,
};

static const struct driver_info ax88772_info = {
	.description = "ASIX AX88772 USB 2.0 Ethernet",
	.bind = ax88772_bind,
1357
	.status = asix_status,
1358
1359
1360
	.link_reset = ax88772_link_reset,
	.reset = ax88772_link_reset,
	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
	.rx_fixup = asix_rx_fixup,
	.tx_fixup = asix_tx_fixup,
};

static const struct driver_info ax88178_info = {
	.description = "ASIX AX88178 USB 2.0 Ethernet",
	.bind = ax88178_bind,
	.status = asix_status,
	.link_reset = ax88178_link_reset,
	.reset = ax88178_link_reset,
	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
	.rx_fixup = asix_rx_fixup,
	.tx_fixup = asix_tx_fixup,
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
};

static const struct usb_device_id	products [] = {
{
	// Linksys USB200M
	USB_DEVICE (0x077b, 0x2226),
	.driver_info =	(unsigned long) &ax8817x_info,
}, {
	// Netgear FA120
	USB_DEVICE (0x0846, 0x1040),
	.driver_info =  (unsigned long) &netgear_fa120_info,
}, {
	// DLink DUB-E100
	USB_DEVICE (0x2001, 0x1a00),
	.driver_info =  (unsigned long) &dlink_dub_e100_info,
}, {
	// Intellinet, ST Lab USB Ethernet
	USB_DEVICE (0x0b95, 0x1720),
	.driver_info =  (unsigned long) &ax8817x_info,
}, {
	// Hawking UF200, TrendNet TU2-ET100
	USB_DEVICE (0x07b8, 0x420a),
	.driver_info =  (unsigned long) &hawking_uf200_info,
}, {
David Hollis's avatar
David Hollis committed
1398
1399
1400
	// Billionton Systems, USB2AR
	USB_DEVICE (0x08dd, 0x90ff),
	.driver_info =  (unsigned long) &ax8817x_info,
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
}, {
	// ATEN UC210T
	USB_DEVICE (0x0557, 0x2009),
	.driver_info =  (unsigned long) &ax8817x_info,
}, {
	// Buffalo LUA-U2-KTX
	USB_DEVICE (0x0411, 0x003d),
	.driver_info =  (unsigned long) &ax8817x_info,
}, {
	// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
	USB_DEVICE (0x6189, 0x182d),
	.driver_info =  (unsigned long) &ax8817x_info,
}, {
	// corega FEther USB2-TX
	USB_DEVICE (0x07aa, 0x0017),
	.driver_info =  (unsigned long) &ax8817x_info,
}, {
	// Surecom EP-1427X-2
	USB_DEVICE (0x1189, 0x0893),
	.driver_info = (unsigned long) &ax8817x_info,
}, {
	// goodway corp usb gwusb2e
	USB_DEVICE (0x1631, 0x6200),
	.driver_info = (unsigned long) &ax8817x_info,
David Hollis's avatar
David Hollis committed
1425
1426
1427
1428
}, {
	// JVC MP-PRX1 Port Replicator
	USB_DEVICE (0x04f1, 0x3008),
	.driver_info = (unsigned long) &ax8817x_info,
1429
1430
}, {
	// ASIX AX88772 10/100
David Hollis's avatar
David Hollis committed
1431
1432
	USB_DEVICE (0x0b95, 0x7720),
	.driver_info = (unsigned long) &ax88772_info,
1433
1434
1435
}, {
	// ASIX AX88178 10/100/1000
	USB_DEVICE (0x0b95, 0x1780),
1436
	.driver_info = (unsigned long) &ax88178_info,
1437
1438
1439
1440
}, {
	// Linksys USB200M Rev 2
	USB_DEVICE (0x13b1, 0x0018),
	.driver_info = (unsigned long) &ax88772_info,
1441
1442
1443
1444
}, {
	// 0Q0 cable ethernet
	USB_DEVICE (0x1557, 0x7720),
	.driver_info = (unsigned long) &ax88772_info,
1445
1446
1447
1448
}, {
	// DLink DUB-E100 H/W Ver B1
	USB_DEVICE (0x07d1, 0x3c05),
	.driver_info = (unsigned long) &ax88772_info,
1449
1450
1451
1452
}, {
	// DLink DUB-E100 H/W Ver B1 Alternate
	USB_DEVICE (0x2001, 0x3c05),
	.driver_info = (unsigned long) &ax88772_info,
1453
1454
1455
1456
}, {
	// Linksys USB1000
	USB_DEVICE (0x1737, 0x0039),
	.driver_info = (unsigned long) &ax88178_info,
1457
1458
1459
1460
}, {
	// IO-DATA ETG-US2
	USB_DEVICE (0x04bb, 0x0930),
	.driver_info = (unsigned long) &ax88178_info,
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
},
	{ },		// END
};
MODULE_DEVICE_TABLE(usb, products);

static struct usb_driver asix_driver = {
	.name =		"asix",
	.id_table =	products,
	.probe =	usbnet_probe,
	.suspend =	usbnet_suspend,
	.resume =	usbnet_resume,
	.disconnect =	usbnet_disconnect,
};

static int __init asix_init(void)
{
 	return usb_register(&asix_driver);
}
module_init(asix_init);

static void __exit asix_exit(void)
{
 	usb_deregister(&asix_driver);
}
module_exit(asix_exit);

MODULE_AUTHOR("David Hollis");
MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
MODULE_LICENSE("GPL");