1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2011 The Chromium OS Authors.
5 * Patched for AX88772B by Antmicro Ltd <www.antmicro.com>
15 #include <linux/delay.h>
16 #include <linux/mii.h>
17 #include "usb_ether.h"
19 /* ASIX AX8817X based USB 2.0 Ethernet Devices */
21 #define AX_CMD_SET_SW_MII 0x06
22 #define AX_CMD_READ_MII_REG 0x07
23 #define AX_CMD_WRITE_MII_REG 0x08
24 #define AX_CMD_SET_HW_MII 0x0a
25 #define AX_CMD_READ_EEPROM 0x0b
26 #define AX_CMD_READ_RX_CTL 0x0f
27 #define AX_CMD_WRITE_RX_CTL 0x10
28 #define AX_CMD_WRITE_IPG0 0x12
29 #define AX_CMD_READ_NODE_ID 0x13
30 #define AX_CMD_WRITE_NODE_ID 0x14
31 #define AX_CMD_READ_PHY_ID 0x19
32 #define AX_CMD_WRITE_MEDIUM_MODE 0x1b
33 #define AX_CMD_WRITE_GPIOS 0x1f
34 #define AX_CMD_SW_RESET 0x20
35 #define AX_CMD_SW_PHY_SELECT 0x22
37 #define AX_SWRESET_CLEAR 0x00
38 #define AX_SWRESET_PRTE 0x04
39 #define AX_SWRESET_PRL 0x08
40 #define AX_SWRESET_IPRL 0x20
41 #define AX_SWRESET_IPPD 0x40
43 #define AX88772_IPG0_DEFAULT 0x15
44 #define AX88772_IPG1_DEFAULT 0x0c
45 #define AX88772_IPG2_DEFAULT 0x12
47 /* AX88772 & AX88178 Medium Mode Register */
48 #define AX_MEDIUM_PF 0x0080
49 #define AX_MEDIUM_JFE 0x0040
50 #define AX_MEDIUM_TFC 0x0020
51 #define AX_MEDIUM_RFC 0x0010
52 #define AX_MEDIUM_ENCK 0x0008
53 #define AX_MEDIUM_AC 0x0004
54 #define AX_MEDIUM_FD 0x0002
55 #define AX_MEDIUM_GM 0x0001
56 #define AX_MEDIUM_SM 0x1000
57 #define AX_MEDIUM_SBP 0x0800
58 #define AX_MEDIUM_PS 0x0200
59 #define AX_MEDIUM_RE 0x0100
61 #define AX88178_MEDIUM_DEFAULT \
62 (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
63 AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
66 #define AX88772_MEDIUM_DEFAULT \
67 (AX_MEDIUM_FD | AX_MEDIUM_RFC | \
68 AX_MEDIUM_TFC | AX_MEDIUM_PS | \
69 AX_MEDIUM_AC | AX_MEDIUM_RE)
71 /* AX88772 & AX88178 RX_CTL values */
72 #define AX_RX_CTL_SO 0x0080
73 #define AX_RX_CTL_AB 0x0008
75 #define AX_DEFAULT_RX_CTL \
76 (AX_RX_CTL_SO | AX_RX_CTL_AB)
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 */
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
90 #define AX_RX_URB_SIZE 2048
91 #define PHY_CONNECT_TIMEOUT 5000
93 /* asix_flags defines */
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 */
102 struct asix_private {
104 struct ueth_data ueth;
108 * Asix infrastructure commands
110 static int asix_write_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
111 u16 size, void *data)
115 debug("asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x "
116 "size=%d\n", cmd, value, index, size);
118 len = usb_control_msg(
120 usb_sndctrlpipe(dev->pusb_dev, 0),
122 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
127 USB_CTRL_SET_TIMEOUT);
129 return len == size ? 0 : -1;
132 static int asix_read_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
133 u16 size, void *data)
137 debug("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
138 cmd, value, index, size);
140 len = usb_control_msg(
142 usb_rcvctrlpipe(dev->pusb_dev, 0),
144 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
149 USB_CTRL_GET_TIMEOUT);
150 return len == size ? 0 : -1;
153 static inline int asix_set_sw_mii(struct ueth_data *dev)
157 ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
159 debug("Failed to enable software MII access\n");
163 static inline int asix_set_hw_mii(struct ueth_data *dev)
167 ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
169 debug("Failed to enable hardware MII access\n");
173 static int asix_mdio_read(struct ueth_data *dev, int phy_id, int loc)
175 ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
177 asix_set_sw_mii(dev);
178 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, res);
179 asix_set_hw_mii(dev);
181 debug("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
182 phy_id, loc, le16_to_cpu(*res));
184 return le16_to_cpu(*res);
188 asix_mdio_write(struct ueth_data *dev, int phy_id, int loc, int val)
190 ALLOC_CACHE_ALIGN_BUFFER(__le16, res, 1);
191 *res = cpu_to_le16(val);
193 debug("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
195 asix_set_sw_mii(dev);
196 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, res);
197 asix_set_hw_mii(dev);
201 * Asix "high level" commands
203 static int asix_sw_reset(struct ueth_data *dev, u8 flags)
207 ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
209 debug("Failed to send software reset: %02x\n", ret);
216 static inline int asix_get_phy_addr(struct ueth_data *dev)
218 ALLOC_CACHE_ALIGN_BUFFER(u8, buf, 2);
220 int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
222 debug("asix_get_phy_addr()\n");
225 debug("Error reading PHYID register: %02x\n", ret);
228 debug("asix_get_phy_addr() returning 0x%02x%02x\n", buf[0], buf[1]);
235 static int asix_write_medium_mode(struct ueth_data *dev, u16 mode)
239 debug("asix_write_medium_mode() - mode = 0x%04x\n", mode);
240 ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode,
243 debug("Failed to write Medium Mode mode to 0x%04x: %02x\n",
249 static u16 asix_read_rx_ctl(struct ueth_data *dev)
251 ALLOC_CACHE_ALIGN_BUFFER(__le16, v, 1);
253 int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, v);
256 debug("Error reading RX_CTL register: %02x\n", ret);
258 ret = le16_to_cpu(*v);
262 static int asix_write_rx_ctl(struct ueth_data *dev, u16 mode)
266 debug("asix_write_rx_ctl() - mode = 0x%04x\n", mode);
267 ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
269 debug("Failed to write RX_CTL mode to 0x%04x: %02x\n",
275 static int asix_write_gpio(struct ueth_data *dev, u16 value, int sleep)
279 debug("asix_write_gpio() - value = 0x%04x\n", value);
280 ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
282 debug("Failed to write GPIO value 0x%04x: %02x\n",
286 udelay(sleep * 1000);
291 static int asix_write_hwaddr_common(struct ueth_data *dev, uint8_t *enetaddr)
294 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
296 memcpy(buf, enetaddr, ETH_ALEN);
298 ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf);
300 debug("Failed to set MAC address: %02x\n", ret);
310 * mii_nway_restart - restart NWay (autonegotiation) for this interface
312 * Returns 0 on success, negative on error.
314 static int mii_nway_restart(struct ueth_data *dev)
319 /* if autoneg is off, it's an error */
320 bmcr = asix_mdio_read(dev, dev->phy_id, MII_BMCR);
322 if (bmcr & BMCR_ANENABLE) {
323 bmcr |= BMCR_ANRESTART;
324 asix_mdio_write(dev, dev->phy_id, MII_BMCR, bmcr);
331 static int asix_read_mac_common(struct ueth_data *dev,
332 struct asix_private *priv, uint8_t *enetaddr)
334 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
337 if (priv->flags & FLAG_EEPROM_MAC) {
338 for (i = 0; i < (ETH_ALEN >> 1); i++) {
339 if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
340 0x04 + i, 0, 2, buf) < 0) {
341 debug("Failed to read SROM address 04h.\n");
344 memcpy(enetaddr + i * 2, buf, 2);
347 if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)
349 debug("Failed to read MAC address.\n");
352 memcpy(enetaddr, buf, ETH_ALEN);
358 static int asix_basic_reset(struct ueth_data *dev)
363 if (asix_write_gpio(dev,
364 AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0)
367 /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
368 embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
369 if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
370 embd_phy, 0, 0, NULL) < 0) {
371 debug("Select PHY #1 failed\n");
375 if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0)
378 if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0)
382 if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0)
385 if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0)
389 rx_ctl = asix_read_rx_ctl(dev);
390 debug("RX_CTL is 0x%04x after software reset\n", rx_ctl);
391 if (asix_write_rx_ctl(dev, 0x0000) < 0)
394 rx_ctl = asix_read_rx_ctl(dev);
395 debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
397 dev->phy_id = asix_get_phy_addr(dev);
399 debug("Failed to read phy id\n");
401 asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
402 asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
403 ADVERTISE_ALL | ADVERTISE_CSMA);
404 mii_nway_restart(dev);
406 if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
409 if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
410 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
411 AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
412 debug("Write IPG,IPG1,IPG2 failed\n");
419 static int asix_init_common(struct ueth_data *dev, uint8_t *enetaddr)
422 #define TIMEOUT_RESOLUTION 50 /* ms */
425 debug("** %s()\n", __func__);
427 if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
430 if (asix_write_hwaddr_common(dev, enetaddr) < 0)
434 link_detected = asix_mdio_read(dev, dev->phy_id, MII_BMSR) &
436 if (!link_detected) {
438 printf("Waiting for Ethernet connection... ");
439 udelay(TIMEOUT_RESOLUTION * 1000);
440 timeout += TIMEOUT_RESOLUTION;
442 } while (!link_detected && timeout < PHY_CONNECT_TIMEOUT);
447 printf("unable to connect.\n");
452 * Wait some more to avoid timeout on first transfer
453 * (e.g. EHCI timed out on TD - token=0x8008d80)
462 static int asix_send_common(struct ueth_data *dev, void *packet, int length)
467 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
468 PKTSIZE + sizeof(packet_len));
470 debug("** %s(), len %d\n", __func__, length);
472 packet_len = (((length) ^ 0x0000ffff) << 16) + (length);
473 cpu_to_le32s(&packet_len);
475 memcpy(msg, &packet_len, sizeof(packet_len));
476 memcpy(msg + sizeof(packet_len), (void *)packet, length);
478 err = usb_bulk_msg(dev->pusb_dev,
479 usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
481 length + sizeof(packet_len),
483 USB_BULK_SEND_TIMEOUT);
484 debug("Tx: len = %zu, actual = %u, err = %d\n",
485 length + sizeof(packet_len), actual_len, err);
490 static int asix_eth_start(struct udevice *dev)
492 struct eth_pdata *pdata = dev_get_plat(dev);
493 struct asix_private *priv = dev_get_priv(dev);
495 return asix_init_common(&priv->ueth, pdata->enetaddr);
498 void asix_eth_stop(struct udevice *dev)
500 debug("** %s()\n", __func__);
503 int asix_eth_send(struct udevice *dev, void *packet, int length)
505 struct asix_private *priv = dev_get_priv(dev);
507 return asix_send_common(&priv->ueth, packet, length);
510 int asix_eth_recv(struct udevice *dev, int flags, uchar **packetp)
512 struct asix_private *priv = dev_get_priv(dev);
513 struct ueth_data *ueth = &priv->ueth;
518 len = usb_ether_get_rx_bytes(ueth, &ptr);
519 debug("%s: first try, len=%d\n", __func__, len);
521 if (!(flags & ETH_RECV_CHECK_DEVICE))
523 ret = usb_ether_receive(ueth, AX_RX_URB_SIZE);
527 len = usb_ether_get_rx_bytes(ueth, &ptr);
528 debug("%s: second try, len=%d\n", __func__, len);
532 * 1st 4 bytes contain the length of the actual data as two
533 * complementary 16-bit words. Extract the length of the data.
535 if (len < sizeof(packet_len)) {
536 debug("Rx: incomplete packet length\n");
539 memcpy(&packet_len, ptr, sizeof(packet_len));
540 le32_to_cpus(&packet_len);
541 if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
542 debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
543 packet_len, (~packet_len >> 16) & 0x7ff,
547 packet_len = packet_len & 0x7ff;
548 if (packet_len > len - sizeof(packet_len)) {
549 debug("Rx: too large packet: %d\n", packet_len);
553 *packetp = ptr + sizeof(packet_len);
557 usb_ether_advance_rxbuf(ueth, -1);
561 static int asix_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
563 struct asix_private *priv = dev_get_priv(dev);
567 usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
572 int asix_write_hwaddr(struct udevice *dev)
574 struct eth_pdata *pdata = dev_get_plat(dev);
575 struct asix_private *priv = dev_get_priv(dev);
577 if (priv->flags & FLAG_TYPE_AX88172)
580 return asix_write_hwaddr_common(&priv->ueth, pdata->enetaddr);
583 static int asix_eth_probe(struct udevice *dev)
585 struct eth_pdata *pdata = dev_get_plat(dev);
586 struct asix_private *priv = dev_get_priv(dev);
587 struct ueth_data *ss = &priv->ueth;
590 priv->flags = dev->driver_data;
591 ret = usb_ether_register(dev, ss, AX_RX_URB_SIZE);
595 ret = asix_basic_reset(ss);
599 /* Get the MAC address */
600 ret = asix_read_mac_common(ss, priv, pdata->enetaddr);
603 debug("MAC %pM\n", pdata->enetaddr);
608 return usb_ether_deregister(ss);
611 static const struct eth_ops asix_eth_ops = {
612 .start = asix_eth_start,
613 .send = asix_eth_send,
614 .recv = asix_eth_recv,
615 .free_pkt = asix_free_pkt,
616 .stop = asix_eth_stop,
617 .write_hwaddr = asix_write_hwaddr,
620 U_BOOT_DRIVER(asix_eth) = {
623 .probe = asix_eth_probe,
624 .ops = &asix_eth_ops,
625 .priv_auto = sizeof(struct asix_private),
626 .plat_auto = sizeof(struct eth_pdata),
629 static const struct usb_device_id asix_eth_id_table[] = {
630 /* Apple USB Ethernet Adapter */
631 { USB_DEVICE(0x05ac, 0x1402), .driver_info = FLAG_TYPE_AX88772 },
632 /* D-Link DUB-E100 H/W Ver B1 */
633 { USB_DEVICE(0x07d1, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
634 /* D-Link DUB-E100 H/W Ver C1 */
635 { USB_DEVICE(0x2001, 0x1a02), .driver_info = FLAG_TYPE_AX88772 },
636 /* Cables-to-Go USB Ethernet Adapter */
637 { USB_DEVICE(0x0b95, 0x772a), .driver_info = FLAG_TYPE_AX88772 },
638 /* Trendnet TU2-ET100 V3.0R */
639 { USB_DEVICE(0x0b95, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
641 { USB_DEVICE(0x0b95, 0x1720), .driver_info = FLAG_TYPE_AX88172 },
642 /* MSI - ASIX 88772a */
643 { USB_DEVICE(0x0db0, 0xa877), .driver_info = FLAG_TYPE_AX88772 },
644 /* Linksys 200M v2.1 */
645 { USB_DEVICE(0x13b1, 0x0018), .driver_info = FLAG_TYPE_AX88172 },
646 /* 0Q0 cable ethernet */
647 { USB_DEVICE(0x1557, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
648 /* DLink DUB-E100 H/W Ver B1 Alternate */
649 { USB_DEVICE(0x2001, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
651 { USB_DEVICE(0x0b95, 0x772b),
652 .driver_info = FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
653 { USB_DEVICE(0x0b95, 0x7e2b), .driver_info = FLAG_TYPE_AX88772B },
654 { } /* Terminating entry */
657 U_BOOT_USB_DEVICE(asix_eth, asix_eth_id_table);