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