From d43754b476dbe575577573823559e0aca5286b39 Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Thu, 18 Jan 2007 04:36:58 +0000 Subject: Add support for AX88772 devices with external PHY. Thanks to Marco S Hyman for sending me hardware to play with. Committed over DUB-E100 rev B1 with external IC Plus PHY. --- sys/dev/usb/if_axe.c | 58 +++++++++++++++++++++++++++++++------------------ sys/dev/usb/if_axereg.h | 17 ++++++++++----- 2 files changed, 48 insertions(+), 27 deletions(-) (limited to 'sys') diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c index ce1c638ec74..516c77c0e2c 100644 --- a/sys/dev/usb/if_axe.c +++ b/sys/dev/usb/if_axe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_axe.c,v 1.57 2006/12/07 18:24:49 reyk Exp $ */ +/* $OpenBSD: if_axe.c,v 1.58 2007/01/18 04:36:57 jsg Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 @@ -139,6 +139,7 @@ Static const struct axe_type axe_devs[] = { { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772 }, { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0}, { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100}, 0 }, + { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 }, { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E}, 0 }, { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1}, 0 }, { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M}, 0 }, @@ -469,10 +470,10 @@ axe_ax88178_init(struct axe_softc *sc) } /* soft reset */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, NULL); + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); usbd_delay_ms(sc->axe_udev, 150); axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, - AXE_178_RESET_PRL | AXE_178_RESET_MAGIC, NULL); + AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); usbd_delay_ms(sc->axe_udev, 150); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); } @@ -483,24 +484,37 @@ axe_ax88772_init(struct axe_softc *sc) axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); usbd_delay_ms(sc->axe_udev, 40); - /* ask for embedded PHY */ - axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); - usbd_delay_ms(sc->axe_udev, 10); + if (sc->axe_phyaddrs[1] == AXE_INTPHY) { + /* ask for the embedded PHY */ + axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); + usbd_delay_ms(sc->axe_udev, 10); - /* power down and reset state, pin reset state */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0x00, NULL); - usbd_delay_ms(sc->axe_udev, 60); + /* power down and reset state, pin reset state */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); + usbd_delay_ms(sc->axe_udev, 60); - /* power down/reset state, pin operating state */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0x48, NULL); - usbd_delay_ms(sc->axe_udev, 150); + /* power down/reset state, pin operating state */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, + AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); + usbd_delay_ms(sc->axe_udev, 150); + + /* power up, reset */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); - /* power up, reset */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0x08, NULL); + /* power up, operating */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, + AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); + } else { + /* ask for external PHY */ + axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL); + usbd_delay_ms(sc->axe_udev, 10); - /* power up, operating */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0x28, NULL); + /* power down internal PHY */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, + AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); + } + usbd_delay_ms(sc->axe_udev, 150); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); } @@ -600,6 +614,12 @@ USB_ATTACH(axe) s = splnet(); + /* We need the PHYID for init dance in some cases */ + axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs); + + DPRINTF((" phyaddrs[0]: %x phyaddrs[1]: %x\n", + sc->axe_phyaddrs[0], sc->axe_phyaddrs[1])); + if (sc->axe_flags & AX178) { axe_ax88178_init(sc); printf(", AX88178"); @@ -618,13 +638,9 @@ USB_ATTACH(axe) axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr); /* - * Load IPG values and PHY indexes. + * Load IPG values */ axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs); - axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs); - - DPRINTF((" phyaddrs[0]: %x phyaddrs[1]: %x\n", - sc->axe_phyaddrs[0], sc->axe_phyaddrs[1])); /* * Work around broken adapters that appear to lie about diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h index 20581acb2eb..25079b2c5b2 100644 --- a/sys/dev/usb/if_axereg.h +++ b/sys/dev/usb/if_axereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_axereg.h,v 1.12 2006/06/01 05:19:38 pascoe Exp $ */ +/* $OpenBSD: if_axereg.h,v 1.13 2007/01/18 04:36:57 jsg Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 @@ -94,11 +94,15 @@ #define AXE_CMD_SW_PHY_STATUS 0x0021 #define AXE_CMD_SW_PHY_SELECT 0x0122 -#define AXE_178_RESET_RR 0x01 -#define AXE_178_RESET_RT 0x02 -#define AXE_178_RESET_PRTE 0x04 -#define AXE_178_RESET_PRL 0x08 -#define AXE_178_RESET_BZ 0x10 +#define AXE_SW_RESET_CLEAR 0x00 +#define AXE_SW_RESET_RR 0x01 +#define AXE_SW_RESET_RT 0x02 +#define AXE_SW_RESET_PRTE 0x04 +#define AXE_SW_RESET_PRL 0x08 +#define AXE_SW_RESET_BZ 0x10 +#define AXE_SW_RESET_IPRL 0x20 +#define AXE_SW_RESET_IPPD 0x40 + /* AX88178 documentation says to always write this bit... */ #define AXE_178_RESET_MAGIC 0x40 @@ -128,6 +132,7 @@ #define AXE_178_RXCMD_MFB 0x0300 #define AXE_NOPHY 0xE0 +#define AXE_INTPHY 0x10 #define AXE_TIMEOUT 1000 #define AXE_172_BUFSZ 1536 -- cgit v1.2.3