summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2007-01-18 04:36:58 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2007-01-18 04:36:58 +0000
commitd43754b476dbe575577573823559e0aca5286b39 (patch)
tree55469aabca13c397ba1cd39c8c41b6746f370ae8 /sys
parent485703bdc50c502d37eb3f8bdb4b1304d87b3078 (diff)
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/if_axe.c58
-rw-r--r--sys/dev/usb/if_axereg.h17
2 files changed, 48 insertions, 27 deletions
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