diff options
-rw-r--r-- | sys/dev/usb/if_axe.c | 82 | ||||
-rw-r--r-- | sys/dev/usb/if_axereg.h | 64 |
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; |