summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2005-08-10 23:07:34 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2005-08-10 23:07:34 +0000
commitc86a5fad9b241f52414ca939344b39e6db088174 (patch)
tree4c21f8629de1d26442d4ef68aab0e6bab7899975 /sys/dev/usb
parent8c3c3e548c40fd2582c0524443d999b99f19173d (diff)
Some of the bits that will be required for AX88178.
PHY doesn't attach possibly due to not twiddling GPIO pins correctly, rx and tx pipes being swapped not dealt with yet.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/if_axe.c82
-rw-r--r--sys/dev/usb/if_axereg.h64
2 files changed, 123 insertions, 23 deletions
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
index 86a9158f0e1..ea500e604c4 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.29 2005/08/01 05:36:48 brad Exp $ */
+/* $OpenBSD: if_axe.c,v 1.30 2005/08/10 23:07:33 jsg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003
@@ -154,6 +154,7 @@ Static const struct axe_type axe_devs[] = {
{ { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200}, 0 },
{ { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2}, 0 },
{ { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 },
+ { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 },
{ { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 },
{ { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_SNAPPORT}, 0 },
{ { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR}, 0},
@@ -261,6 +262,8 @@ axe_miibus_readreg(device_ptr_t dev, int phy, int reg)
* PHYs attached to the chip, so only read from those.
*/
+ DPRINTF(("axe_miibus_readreg: phy 0x%x reg 0x%x\n", phy, reg));
+
if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0])
return (0);
@@ -324,6 +327,11 @@ axe_miibus_statchg(device_ptr_t dev)
val = AXE_MEDIA_FULL_DUPLEX;
else
val = 0;
+
+ if (sc->axe_flags & AX178)
+ val |= (AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC |
+ AXE_178_MEDIA_ENCK);
+
DPRINTF(("axe_miibus_statchg: val=0x%x\n", val));
err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
if (err) {
@@ -450,11 +458,12 @@ USB_ATTACH(axe)
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
struct mii_data *mii;
+ u_int16_t eeprom;
u_char eaddr[ETHER_ADDR_LEN];
char *devinfop;
char *devname = USBDEVNAME(sc->axe_dev);
struct ifnet *ifp;
- int i, s;
+ int i, s, gpio0 = 0, phymode = 0;
devinfop = usbd_devinfo_alloc(dev, 0);
USB_ATTACH_SETUP;
@@ -468,6 +477,8 @@ USB_ATTACH(axe)
USB_ATTACH_ERROR_RETURN;
}
+ sc->axe_flags = axe_lookup(uaa->vendor, uaa->product)->axe_flags;
+
usb_init_task(&sc->axe_tick_task, axe_tick_task, sc);
lockinit(&sc->axe_mii_lock, PZERO, "axemii", 0, LK_CANRECURSE);
usb_init_task(&sc->axe_stop_task, (void (*)(void *))axe_stop, sc);
@@ -509,10 +520,56 @@ USB_ATTACH(axe)
s = splnet();
+ if (sc->axe_flags & AX178) {
+ axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
+ /* XXX magic */
+ axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
+ axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
+
+ DPRINTF((" EEPROM is 0x%x\n", eeprom));
+
+ /* if EEPROM is invalid we have to use to GPIO0 */
+ if (eeprom == 0xffff) {
+ phymode = 0;
+ gpio0 = 1;
+ } else {
+ phymode = eeprom & 7;
+ if (eeprom & 0x80)
+ gpio0 = 0;
+ }
+
+ DPRINTF(("use gpio0: %d, phymode %d\n", gpio0, phymode));
+
+ /* GPIO voodoo required to turn on PHY */
+ if (gpio0)
+ printf("gpio0 path not done! PHY not enabled\n");
+ else {
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
+ if (phymode != 1) {
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+ } else {
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
+ }
+ }
+
+ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
+ /* soft reset */
+ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+ AXE_178_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
+ delay(500);
+ axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
+ }
+
/*
* Get station address.
*/
- axe_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, &eaddr);
+ if (sc->axe_flags & AX178)
+ axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr);
+ else
+ axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr);
/*
* Load IPG values and PHY indexes.
@@ -520,6 +577,9 @@ USB_ATTACH(axe)
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
* their PHY addresses.
@@ -1115,12 +1175,20 @@ axe_init(void *xsc)
}
/* Set transmitter IPG values */
- axe_cmd(sc, AXE_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
- axe_cmd(sc, AXE_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
- axe_cmd(sc, AXE_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
+ if (sc->axe_flags & AX178)
+ axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, 0,
+ (sc->axe_ipgs[0] << 2) | (sc->axe_ipgs[1] << 1) |
+ (sc->axe_ipgs[2]), NULL);
+ else {
+ axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
+ axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
+ axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
+ }
/* Enable receiver, set RX mode */
- rxmode = AXE_RXCMD_UNICAST|AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
+ rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
+ if (!(sc->axe_flags & AX178))
+ rxmode |= AXE_172_RXCMD_UNICAST;
/* If we want promiscuous mode, set the allframes bit. */
if (ifp->if_flags & IFF_PROMISC)
diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h
index d25dca46810..cc895679e3f 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.4 2004/11/11 12:47:14 dlg Exp $ */
+/* $OpenBSD: if_axereg.h,v 1.5 2005/08/10 23:07:33 jsg Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003
@@ -55,9 +55,11 @@
#define AXE_CMD_LEN(x) (((x) & 0xF000) >> 12)
#define AXE_CMD_CMD(x) ((x) & 0x00FF)
-#define AXE_CMD_READ_RXTX_SRAM 0x2002
-#define AXE_CMD_WRITE_RX_SRAM 0x0103
-#define AXE_CMD_WRITE_TX_SRAM 0x0104
+#define AXE_172_CMD_READ_RXTX_SRAM 0x2002
+#define AXE_182_CMD_READ_RXTX_SRAM 0x8002
+#define AXE_172_CMD_WRITE_RX_SRAM 0x0103
+#define AXE_172_CMD_WRITE_TX_SRAM 0x0104
+#define AXE_182_CMD_WRITE_RXTX_SRAM 0x8103
#define AXE_CMD_MII_OPMODE_SW 0x0106
#define AXE_CMD_MII_READ_REG 0x2007
#define AXE_CMD_MII_WRITE_REG 0x2108
@@ -70,28 +72,56 @@
#define AXE_CMD_RXCTL_READ 0x200F
#define AXE_CMD_RXCTL_WRITE 0x0110
#define AXE_CMD_READ_IPG012 0x3011
-#define AXE_CMD_WRITE_IPG0 0x0112
-#define AXE_CMD_WRITE_IPG1 0x0113
-#define AXE_CMD_WRITE_IPG2 0x0114
+#define AXE_172_CMD_WRITE_IPG0 0x0112
+#define AXE_172_CMD_WRITE_IPG1 0x0113
+#define AXE_172_CMD_WRITE_IPG2 0x0114
+#define AXE_178_CMD_WRITE_IPG012 0x0112
#define AXE_CMD_READ_MCAST 0x8015
#define AXE_CMD_WRITE_MCAST 0x8116
-#define AXE_CMD_READ_NODEID 0x6017
-#define AXE_CMD_WRITE_NODEID 0x6118
+#define AXE_172_CMD_READ_NODEID 0x6017
+#define AXE_172_CMD_WRITE_NODEID 0x6118
+#define AXE_178_CMD_READ_NODEID 0x6013
+#define AXE_178_CMD_WRITE_NODEID 0x6014
#define AXE_CMD_READ_PHYID 0x2019
-#define AXE_CMD_READ_MEDIA 0x101A
+#define AXE_172_CMD_READ_MEDIA 0x101A
+#define AXE_178_CMD_READ_MEDIA 0x201A
#define AXE_CMD_WRITE_MEDIA 0x011B
#define AXE_CMD_READ_MONITOR_MODE 0x101C
#define AXE_CMD_WRITE_MONITOR_MODE 0x011D
#define AXE_CMD_READ_GPIO 0x101E
#define AXE_CMD_WRITE_GPIO 0x011F
-
-#define AXE_MEDIA_FULL_DUPLEX 0x02
-#define AXE_MEDIA_TX_ABORT_ALLOW 0x04
-#define AXE_MEDIA_FLOW_CONTROL_EN 0x10
+#define AXE_CMD_SW_RESET_REG 0x0120
+#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
+/* AX88178 documentation says to always write this bit... */
+#define AXE_178_RESET_MAGIC 0x40
+
+#define AXE_178_MEDIA_GMII 0x0001
+#define AXE_MEDIA_FULL_DUPLEX 0x0002
+#define AXE_172_MEDIA_TX_ABORT_ALLOW 0x0004
+/* AX88178 documentation says to always write 1 to reserved bit... */
+#define AXE_178_MEDIA_MAGIC 0x0004
+#define AXE_178_MEDIA_ENCK 0x0008
+#define AXE_172_MEDIA_FLOW_CONTROL_EN 0x0010
+#define AXE_178_MEDIA_RXFLOW_CONTROL_EN 0x0010
+#define AXE_178_MEDIA_TXFLOW_CONTROL_EN 0x0020
+#define AXE_178_MEDIA_JUMBO_EN 0x0040
+#define AXE_178_MEDIA_LTPF_ONLY 0x0080
+#define AXE_178_MEDIA_RX_EN 0x0100
+#define AXE_178_MEDIA_PORT_SPEED 0x0200
+#define AXE_178_MEDIA_SBP 0x0800
+#define AXE_178_MEDIA_SUPERMAC 0x1000
#define AXE_RXCMD_PROMISC 0x0001
#define AXE_RXCMD_ALLMULTI 0x0002
-#define AXE_RXCMD_UNICAST 0x0004
+#define AXE_172_RXCMD_UNICAST 0x0004
+#define AXE_178_RXCMD_KEEP_INVALID_CRC 0x0004
#define AXE_RXCMD_BROADCAST 0x0008
#define AXE_RXCMD_MULTICAST 0x0010
#define AXE_RXCMD_ENABLE 0x0080
@@ -125,7 +155,7 @@
struct axe_type {
struct usb_devno axe_dev;
u_int16_t axe_flags;
-/* XXX No flags so far */
+#define AX178 0x0001 /* AX88178 */
};
struct axe_softc;
@@ -168,6 +198,8 @@ struct axe_softc {
u_int16_t axe_vendor;
u_int16_t axe_product;
+ u_int16_t axe_flags;
+
int axe_ed[AXE_ENDPT_MAX];
usbd_pipe_handle axe_ep[AXE_ENDPT_MAX];
int axe_unit;