PERFORCE change 114016 for review
Sam Leffler
sam at FreeBSD.org
Sun Feb 4 22:59:53 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=114016
Change 114016 by sam at 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
More information about the p4-projects
mailing list