From owner-p4-projects@FreeBSD.ORG Sun Feb 4 22:59:53 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3A83416A405; Sun, 4 Feb 2007 22:59:53 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id EC29716A403 for ; Sun, 4 Feb 2007 22:59:52 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id DA5CF13C471 for ; Sun, 4 Feb 2007 22:59:52 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l14MxqpF031129 for ; Sun, 4 Feb 2007 22:59:52 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l14MxqbB031126 for perforce@freebsd.org; Sun, 4 Feb 2007 22:59:52 GMT (envelope-from sam@freebsd.org) Date: Sun, 4 Feb 2007 22:59:52 GMT Message-Id: <200702042259.l14MxqbB031126@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 114016 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Feb 2007 22:59:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=114016 Change 114016 by sam@sam_ebb on 2007/02/04 22:59:50 checkpoint AX772 support; needs a bit more work Affected files ... .. //depot/projects/wifi/sys/dev/usb/if_axe.c#12 edit .. //depot/projects/wifi/sys/dev/usb/if_axereg.h#7 edit .. //depot/projects/wifi/sys/dev/usb/usbdevs#20 edit Differences ... ==== //depot/projects/wifi/sys/dev/usb/if_axe.c#12 (text+ko) ==== @@ -111,14 +111,17 @@ * Various supported device vendors/products. */ static struct axe_type axe_devs[] = { - { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 }, - { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 }, - { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 }, - { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL }, - { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 }, + { AX172, USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 }, + { AX172, USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 }, + { AX172, USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 }, + { AX172, USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M }, + { AX172, USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX }, + { AX172, USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 }, + { AX172, USB_VENDOR_SYSTEMTALKS,USB_PRODUCT_SYSTEMTALKS_SGCX2UL }, + { AX172, USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 }, + + { AX772, USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772 }, + { AX772, USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB200MV2 }, { 0, 0 } }; @@ -146,6 +149,8 @@ static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); static void axe_setmulti(struct axe_softc *); +static void axe_ax88178_init(struct axe_softc *); +static void axe_ax88772_init(struct axe_softc *); static device_method_t axe_methods[] = { /* Device interface */ @@ -276,13 +281,36 @@ static void axe_miibus_statchg(device_t dev) { -#ifdef notdef struct axe_softc *sc = USBGETSOFTC(dev); struct mii_data *mii = GET_MII(sc); -#endif - /* doesn't seem to be necessary */ + int val, err; + + if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) + val = AXE_MEDIA_FULL_DUPLEX; + else + val = 0; + + if ((sc->axe_flags & AX178) || (sc->axe_flags & AX772)) { + val |= (AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC); + + switch (IFM_SUBTYPE(mii->mii_media_active)) { + case IFM_1000_T: + val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; + break; + case IFM_100_TX: + val |= AXE_178_MEDIA_100TX; + break; + case IFM_10_T: + /* doesn't need to be handled */ + break; + } + } - return; + err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); + if (err) { + printf("axe%d: media change failed\n", sc->axe_unit); + return; + } } /* @@ -317,8 +345,6 @@ mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; - - return; } static void @@ -344,12 +370,7 @@ rxmode &= ~AXE_RXCMD_ALLMULTI; IF_ADDR_LOCK(ifp); -#if __FreeBSD_version >= 500000 - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) -#else - LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) -#endif - { + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; h = ether_crc32_be(LLADDR((struct sockaddr_dl *) @@ -361,8 +382,80 @@ axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); AXE_UNLOCK(sc); +} + +static void +axe_ax88178_init(struct axe_softc *sc) +{ + int gpio0 = 0, phymode = 0; + u_int16_t eeprom; - return; + 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); + + /* if EEPROM is invalid we have to use to GPIO0 */ + if (eeprom == 0xffff) { + phymode = 0; + gpio0 = 1; + } else { + phymode = eeprom & 7; + gpio0 = (eeprom & 0x80) ? 0 : 1; + } + + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL); + usbd_delay_ms(sc->axe_udev, 40); + if ((eeprom >> 8) != 1) { + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); + usbd_delay_ms(sc->axe_udev, 30); + + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL); + usbd_delay_ms(sc->axe_udev, 300); + + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); + usbd_delay_ms(sc->axe_udev, 30); + } else { + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL); + usbd_delay_ms(sc->axe_udev, 30); + axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL); + usbd_delay_ms(sc->axe_udev, 30); + } + + /* soft reset */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, 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); + usbd_delay_ms(sc->axe_udev, 150); + axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); +} + +static void +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); + + /* 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/reset state, pin operating state */ + axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0x48, NULL); + usbd_delay_ms(sc->axe_udev, 150); + + /* 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, 0x28, NULL); + + axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); } static void @@ -383,27 +476,26 @@ return; } +static int +axe_devflags(int vendor, int product) +{ + struct axe_type *t; + + for (t = axe_devs; t->axe_vid != 0; t++) + if (t->axe_vid == vendor && t->axe_did == product) + return t->axe_flags; + return 0; +} + /* * Probe for a AX88172 chip. */ USB_MATCH(axe) { USB_MATCH_START(axe, uaa); - struct axe_type *t; - if (!uaa->iface) - return(UMATCH_NONE); - - t = axe_devs; - while(t->axe_vid) { - if (uaa->vendor == t->axe_vid && - uaa->product == t->axe_did) { - return(UMATCH_VENDOR_PRODUCT); - } - t++; - } - - return(UMATCH_NONE); + return (!uaa->iface || axe_devflags(uaa->vendor, uaa->product) == 0 ? + UMATCH_NONE : UMATCH_VENDOR_PRODUCT); } /* @@ -424,6 +516,7 @@ sc->axe_udev = uaa->device; sc->axe_dev = self; sc->axe_unit = device_get_unit(self); + sc->axe_flags = axe_devflags(uaa->vendor, uaa->product); if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) { printf("axe%d: getting interface handle failed\n", @@ -444,7 +537,9 @@ usbd_devinfo(uaa->device, 0, devinfo); device_set_desc_copy(self, devinfo); - printf("%s: %s\n", device_get_nameunit(self), devinfo); + printf("%s: %s%s\n", device_get_nameunit(self), devinfo, + sc->axe_flags & AX178 ? ", AX88178" : + sc->axe_flags & AX772 ? ", AX88772" : ""); /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { @@ -466,18 +561,24 @@ } } -#if __FreeBSD_version >= 500000 mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); -#endif sx_init(&sc->axe_sleeplock, device_get_nameunit(self)); AXE_SLEEPLOCK(sc); AXE_LOCK(sc); + if (sc->axe_flags & AX178) + axe_ax88178_init(sc); + else if (sc->axe_flags & AX772) + axe_ax88772_init(sc); + /* * Get station address. */ - axe_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, &eaddr); + if (sc->axe_flags & (AX178|AX772)) + axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr); + else + axe_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, &eaddr); /* * Load IPG values and PHY indexes. @@ -497,9 +598,7 @@ AXE_UNLOCK(sc); AXE_SLEEPUNLOCK(sc); sx_destroy(&sc->axe_sleeplock); -#if __FreeBSD_version >= 500000 mtx_destroy(&sc->axe_mtx); -#endif USB_ATTACH_ERROR_RETURN; } ifp->if_softc = sc; @@ -523,9 +622,7 @@ AXE_UNLOCK(sc); AXE_SLEEPUNLOCK(sc); sx_destroy(&sc->axe_sleeplock); -#if __FreeBSD_version >= 500000 mtx_destroy(&sc->axe_mtx); -#endif USB_ATTACH_ERROR_RETURN; } @@ -533,11 +630,7 @@ * Call MI attach routine. */ -#if __FreeBSD_version >= 500000 ether_ifattach(ifp, eaddr); -#else - ether_ifattach(ifp, ETHER_BPF_SUPPORTED); -#endif callout_handle_init(&sc->axe_stat_ch); usb_register_netisr(); @@ -563,12 +656,8 @@ untimeout(axe_tick, sc, sc->axe_stat_ch); usb_rem_task(sc->axe_udev, &sc->axe_tick_task); -#if __FreeBSD_version >= 500000 ether_ifdetach(ifp); if_free(ifp); -#else - ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); -#endif if (sc->axe_ep[AXE_ENDPT_TX] != NULL) usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]); @@ -579,9 +668,7 @@ AXE_UNLOCK(sc); sx_destroy(&sc->axe_sleeplock); -#if __FreeBSD_version >= 500000 mtx_destroy(&sc->axe_mtx); -#endif return(0); } @@ -915,12 +1002,24 @@ } /* 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|AX772)) { + axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2], + (sc->axe_ipgs[1]<<8) | sc->axe_ipgs[0], NULL); + } else { + 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); + } /* 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|AX772)) { +#ifdef notyet + if (sc->axe_udev->speed == USB_SPEED_HIGH) + rxmode |= AXE_178_RXCMD_MFB; +#endif + } else + rxmode |= AXE_RXCMD_UNICAST; /* If we want promiscuous mode, set the allframes bit. */ if (ifp->if_flags & IFF_PROMISC) ==== //depot/projects/wifi/sys/dev/usb/if_axereg.h#7 (text+ko) ==== @@ -82,7 +82,32 @@ #define AXE_CMD_WRITE_MONITOR_MODE 0x011D #define AXE_CMD_READ_GPIO 0x101E #define AXE_CMD_WRITE_GPIO 0x011F +#define AXE_CMD_SW_RESET_REG 0x0120 +#define AXE_CMD_SW_PHY_STATUS 0x0021 +#define AXE_CMD_SW_PHY_SELECT 0x0122 +#define AXE_172_CMD_WRITE_RX_SRAM 0x0103 +#define AXE_172_CMD_WRITE_TX_SRAM 0x0104 +#define AXE_172_CMD_WRITE_IPG0 0x0112 +#define AXE_172_CMD_WRITE_IPG1 0x0113 +#define AXE_172_CMD_WRITE_IPG2 0x0114 +#define AXE_172_CMD_READ_NODEID 0x6017 +#define AXE_172_CMD_WRITE_NODEID 0x6118 +#define AXE_172_CMD_READ_MEDIA 0x101A + +#define AXE_178_CMD_WRITE_IPG012 0x0112 +#define AXE_178_CMD_READ_NODEID 0x6013 +#define AXE_178_CMD_WRITE_NODEID 0x6014 +#define AXE_178_CMD_READ_MEDIA 0x201A + +#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_RXCMD_PROMISC 0x0001 #define AXE_RXCMD_ALLMULTI 0x0002 #define AXE_RXCMD_UNICAST 0x0004 @@ -90,6 +115,22 @@ #define AXE_RXCMD_MULTICAST 0x0010 #define AXE_RXCMD_ENABLE 0x0080 +#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_100TX 0x0200 +#define AXE_178_MEDIA_SBP 0x0800 +#define AXE_178_MEDIA_SUPERMAC 0x1000 + #define AXE_NOPHY 0xE0 #define AXE_TIMEOUT 1000 @@ -113,6 +154,10 @@ #define AXE_ENDPT_MAX 0x3 struct axe_type { + int axe_flags; +#define AX172 0x0001 /* AX88172 */ +#define AX178 0x0002 /* AX88178 */ +#define AX772 0x0004 /* AX88772 */ u_int16_t axe_vid; u_int16_t axe_did; }; @@ -120,13 +165,6 @@ #define AXE_INC(x, y) (x) = (x + 1) % y struct axe_softc { -#if defined(__FreeBSD__) -#define GET_MII(sc) (device_get_softc((sc)->axe_miibus)) -#elif defined(__NetBSD__) -#define GET_MII(sc) (&(sc)->axe_mii) -#elif defined(__OpenBSD__) -#define GET_MII(sc) (&(sc)->axe_mii) -#endif struct ifnet *axe_ifp; device_t axe_miibus; device_t axe_dev; @@ -136,11 +174,10 @@ usbd_pipe_handle axe_ep[AXE_ENDPT_MAX]; int axe_unit; int axe_if_flags; + int axe_flags; struct ue_cdata axe_cdata; struct callout_handle axe_stat_ch; -#if __FreeBSD_version >= 500000 struct mtx axe_mtx; -#endif struct sx axe_sleeplock; char axe_dying; int axe_link; @@ -151,6 +188,8 @@ struct usb_task axe_tick_task; }; +#define GET_MII(sc) device_get_softc((sc)->axe_miibus) + #if 0 #define AXE_LOCK(_sc) mtx_lock(&(_sc)->axe_mtx) #define AXE_UNLOCK(_sc) mtx_unlock(&(_sc)->axe_mtx) ==== //depot/projects/wifi/sys/dev/usb/usbdevs#20 (text+ko) ==== @@ -696,6 +696,7 @@ /* ASIX Electronics products */ product ASIX AX88172 0x1720 10/100 ethernet +product ASIX AX88772 0x7720 AX88772 /* ASUS products */ product ASUS WL167G 0x1707 WL-167g wireless adapter @@ -1226,6 +1227,7 @@ product LINKSYS4 WUSB54G 0x000d WUSB54G wireless adapter product LINKSYS4 WUSB54GP 0x0011 WUSB54GP wireless adapter product LINKSYS4 HU200TS 0x001a HU200TS wireless adapter +product LINKSYS4 USB200MV2 0x0018 USB 2.0 10/100 ethernet /* Logitech products */ product LOGITECH M2452 0x0203 M2452 keyboard