PERFORCE change 117219 for review

Hans Petter Selasky hselasky at FreeBSD.org
Mon Apr 2 20:49:25 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=117219

Change 117219 by hselasky at hselasky_mini_itx on 2007/04/02 20:49:18

	Add support for Ax88178 and Ax88772 to if_axe. Ported from OpenBSD.
	Fixed some bugs. Please test.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/if_axe.c#18 edit
.. //depot/projects/usb/src/sys/dev/usb/if_axereg.h#12 edit
.. //depot/projects/usb/src/sys/dev/usb/if_ural.c#21 edit
.. //depot/projects/usb/src/sys/dev/usb/usbdevs#8 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/if_axe.c#18 (text+ko) ====

@@ -68,6 +68,15 @@
  */
 
 /*
+ * Ax88178 and Ax88772 support backported from the OpenBSD driver.
+ * 2007/02/12, J.R. Oldroyd, fbsd at opal.com
+ *
+ * Manual here:
+ * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
+ * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
+ */
+
+/*
  * NOTE: all function names beginning like "axe_cfg_" can only
  * be called from within the config thread function !
  */
@@ -125,20 +134,35 @@
 #define DPRINTF(...)
 #endif
 
-
 /*
  * 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 },
-	{ 0, 0 }
+	{ 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, AXE_FLAG_178 },
+	{ USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, AXE_FLAG_772 },
+	{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, 0 },
+	{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 , AXE_FLAG_178 },
+	{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, 0},
+	{ USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, AXE_FLAG_772 },
+	{ 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 , AXE_FLAG_772 },
+	{ USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, 0 },
+	{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, AXE_FLAG_178 },
+	{ USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, 0 },
+	{ USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, 0 },
+	{ USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, AXE_FLAG_178 },
+	{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, 0 },
+	{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, 0 },
+	{ USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, AXE_FLAG_772 },
+	{ USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T , AXE_FLAG_178 },
+	{ USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, 0 },
+	{ USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 , AXE_FLAG_178 },
+	{ USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0 },
+	{ 0, 0, 0 }
 };
 
 static device_probe_t axe_probe;
@@ -196,13 +220,19 @@
 static void
 axe_watchdog(void *arg);
 
+static void
+axe_cfg_ax88178_init(struct axe_softc *);
+
+static void
+axe_cfg_ax88772_init(struct axe_softc *);
+
 static const struct usbd_config axe_config[AXE_ENDPT_MAX] = {
 
     [0] = {
       .type      = UE_BULK,
       .endpoint  = -1, /* any */
       .direction = UE_DIR_OUT,
-      .bufsize   = MCLBYTES,
+      .bufsize   = AXE_BULK_BUF_SIZE,
       .flags     = (USBD_USE_DMA|USBD_FORCE_SHORT_XFER),
       .callback  = &axe_bulk_write_callback,
       .timeout   = 10000, /* 10 seconds */
@@ -212,7 +242,7 @@
       .type      = UE_BULK,
       .endpoint  = -1, /* any */
       .direction = UE_DIR_IN,
-      .bufsize   = MCLBYTES,
+      .bufsize   = AXE_BULK_BUF_SIZE,
       .flags     = (USBD_USE_DMA|USBD_SHORT_XFER_OK),
       .callback  = &axe_bulk_read_callback,
       .timeout   = 0, /* no timeout */
@@ -313,7 +343,7 @@
 
 	if (err) {
 
-	    DPRINTF(sc, 0, "device request failed, err=%s "
+	    DPRINTF(sc, -1, "device request failed, err=%s "
 		    "(ignored)\n", usbd_errstr(err));
 
 	error:
@@ -391,7 +421,37 @@
 static void
 axe_cfg_miibus_statchg(device_t dev)
 {
-	/* doesn't seem to be necessary */
+	struct axe_softc * sc = device_get_softc(dev);
+	struct mii_data * mii = GET_MII(sc);
+	uint16_t val;
+
+	mtx_lock(&(sc->sc_mtx)); /* XXX */
+
+	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
+		val = AXE_MEDIA_FULL_DUPLEX;
+	else
+		val = 0;
+
+	if (sc->sc_flags & (AXE_FLAG_772|AXE_FLAG_178)) {
+
+		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;
+		}
+	}
+
+	axe_cfg_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
+
+	mtx_unlock(&(sc->sc_mtx)); /* XXX */
 	return;
 }
 
@@ -545,6 +605,22 @@
 	return;
 }
 
+static struct axe_type *
+axe_find_product(struct usb_attach_arg *uaa)
+{
+	struct axe_type	*t;
+
+	t = axe_devs;
+	while(t->axe_vid) {
+	    if ((uaa->vendor == t->axe_vid) &&
+		(uaa->product == t->axe_did)) {
+		return t;
+	    }
+	    t++;
+	}
+	return NULL;
+}
+
 /*
  * Probe for a AX88172 chip.
  */
@@ -552,21 +628,13 @@
 axe_probe(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
-	struct axe_type	*t;
 
 	if (uaa->iface != NULL) {
 	    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 (axe_find_product(uaa) ? 
+		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
 }
 
 /*
@@ -577,6 +645,7 @@
 axe_attach(device_t dev)
 {
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	struct axe_type	*t = axe_find_product(uaa);
 	struct axe_softc *sc = device_get_softc(dev);
 	int32_t error;
 
@@ -587,6 +656,7 @@
 	sc->sc_udev = uaa->device;
 	sc->sc_dev = dev;
 	sc->sc_unit = device_get_unit(dev);
+	sc->sc_flags = t->axe_flags;
 
 	usbd_set_desc(dev, uaa->device);
 
@@ -627,6 +697,12 @@
 
 	sc->sc_flags |= AXE_FLAG_WAIT_LINK;
 
+	/* correct maximum bulk-receive length */
+
+	sc->sc_xfer[1]->length = 
+	  (sc->sc_flags & (AXE_FLAG_772|AXE_FLAG_178)) ?
+	  AXE_BULK_BUF_SIZE : MIN(MCLBYTES, AXE_BULK_BUF_SIZE);
+
 	/* start setup */
 
 	usbd_config_td_queue_command
@@ -644,6 +720,112 @@
 }
 
 static void
+axe_cfg_ax88178_init(struct axe_softc *sc)
+{
+	uint16_t eeprom;
+	uint16_t phymode;
+	uint16_t gpio0;
+	uint8_t err;
+
+	DPRINTF(sc, 0, "\n");
+
+	axe_cfg_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
+	/* XXX magic */
+	axe_cfg_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
+	axe_cfg_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
+
+	/* For big-endian machines: */
+	eeprom = le16toh(eeprom);
+
+	/* 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_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
+	err = usbd_config_td_sleep(&(sc->sc_config_td), hz/16);
+
+	if ((eeprom >> 8) != 0x01) {
+		axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/32);
+
+		axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/3);
+
+		axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/32);
+	} else {
+		axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/32);
+
+		axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/32);
+	}
+
+	/* soft reset */
+	axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
+	err = usbd_config_td_sleep(&(sc->sc_config_td), hz/4);
+
+	axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+		    AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
+	err = usbd_config_td_sleep(&(sc->sc_config_td), hz/4);
+
+	axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
+	return;
+}
+
+static void
+axe_cfg_ax88772_init(struct axe_softc *sc)
+{
+	uint8_t err;
+
+	DPRINTF(sc, 0, "\n");
+
+	axe_cfg_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
+	err = usbd_config_td_sleep(&(sc->sc_config_td), hz/16);
+
+	if (sc->sc_phyaddrs[1] == AXE_INTPHY) {
+		/* ask for the embedded PHY */
+		axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/64);
+
+		/* power down and reset state, pin reset state */
+		axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 
+			    AXE_SW_RESET_CLEAR, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/16);
+
+		/* power down/reset state, pin operating state */
+		axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+			    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/4);
+
+		/* power up, reset */
+		axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 
+			    AXE_SW_RESET_PRL, NULL);
+
+		/* power up, operating */
+		axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+			    AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
+	} else {
+		/* ask for external PHY */
+		axe_cfg_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
+		err = usbd_config_td_sleep(&(sc->sc_config_td), hz/64);
+
+		/* power down internal PHY */
+		axe_cfg_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
+			    AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
+	}
+
+	err = usbd_config_td_sleep(&(sc->sc_config_td), hz/4);
+	axe_cfg_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
+	return;
+}
+
+static void
 axe_cfg_first_time_setup(struct axe_softc *sc,
 			 struct axe_config_copy *cc, u_int16_t refcount)
 {
@@ -655,15 +837,28 @@
 	bzero(eaddr, sizeof(eaddr));
 
 	/*
+	 * Load PHY indexes first. Needed by axe_xxx_init().
+	 */
+	axe_cfg_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
+
+	if (sc->sc_flags & AXE_FLAG_178) {
+		axe_cfg_ax88178_init(sc);
+	} else if (sc->sc_flags & AXE_FLAG_772) {
+		axe_cfg_ax88772_init(sc);
+	}
+
+	/*
 	 * Get station address.
 	 */
-	axe_cfg_cmd(sc, AXE_CMD_READ_NODEID, 0, 0, eaddr);
+	if (sc->sc_flags & (AXE_FLAG_178|AXE_FLAG_772))
+		axe_cfg_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, eaddr);
+	else
+		axe_cfg_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, eaddr);
 
 	/*
-	 * Load IPG values and PHY indexes.
+	 * Load IPG values.
 	 */
 	axe_cfg_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
-	axe_cfg_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
 
 	/*
 	 * Work around broken adapters that appear to lie about
@@ -852,12 +1047,20 @@
 	return;
 }
 
+#if (AXE_BULK_BUF_SIZE >= 0x10000)
+#error "Please update axe_bulk_read_callback()!"
+#endif
+
 static void
 axe_bulk_read_callback(struct usbd_xfer *xfer)
 {
 	struct axe_softc *sc = xfer->priv_sc;
+	struct axe_sframe_hdr hdr;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct mbuf *m;
+	uint16_t pos;
+	uint16_t len;
+	uint16_t adjust;
 
 	USBD_CHECK_STATUS(xfer);
 
@@ -873,27 +1076,80 @@
 
  tr_transferred:
 
-	if (xfer->actlen < sizeof(struct ether_header)) {
-	    ifp->if_ierrors++;
-	    goto tr_setup;
-	}
+	pos = 0;
+
+	while (1) {
+
+	    if (sc->sc_flags & (AXE_FLAG_772|AXE_FLAG_178)) {
+
+	        if (xfer->actlen < sizeof(hdr)) {
+		    /* too little data */
+		    break;
+		}
+
+		usbd_copy_out(&(xfer->buf_data), pos, &hdr, sizeof(hdr));
+
+		if ((hdr.len ^ hdr.ilen) != 0xFFFF) {
+		    /* we lost sync */
+		    break;
+		}
+
+		xfer->actlen -= sizeof(hdr);
+		pos += sizeof(hdr);
+
+		len = le16toh(hdr.len);
+		if (len > xfer->actlen) {
+		    /* invalid length */
+		    break;
+		}
+
+		adjust = (len & 1);
+
+	    } else {
+	        len = xfer->actlen;
+		adjust = 0;
+	    }
+
+	    if (len < sizeof(struct ether_header)) {
+	        ifp->if_ierrors++;
+		goto skip;
+	    }
+
+	    m = usbd_ether_get_mbuf();
+
+	    if (m == NULL) {
+	        /* we are out of memory */
+	        break;
+	    }
+
+	    if (m->m_len > len) {
+	        m->m_len = len;
+	    }
+
+	    usbd_copy_out(&(xfer->buf_data), pos, m->m_data, m->m_len);
+
+	    ifp->if_ipackets++;
+	    m->m_pkthdr.rcvif = ifp;
+	    m->m_pkthdr.len = m->m_len;
 
-	m = usbd_ether_get_mbuf();
+	    (ifp->if_input)(ifp, m);
 
-	if (m == NULL) {
-	    ifp->if_ierrors++;
-	    goto tr_setup;
-	}
+	skip:
 
-	xfer->actlen = min(xfer->actlen, m->m_len);
+	    pos += len;
+	    xfer->actlen -= len;
 
-	usbd_copy_out(&(xfer->buf_data), 0, m->m_data, xfer->actlen);
+	    if (xfer->actlen <= adjust) {
+	        /* we are finished */
+	        goto tr_setup;
+	    }
 
-	ifp->if_ipackets++;
-	m->m_pkthdr.rcvif = ifp;
-	m->m_pkthdr.len = m->m_len = xfer->actlen;
+	    pos += adjust;
+	    xfer->actlen -= adjust;
+	}
 
-	(ifp->if_input)(ifp, m);
+	/* count an error */
+	ifp->if_ierrors++;
 
  tr_setup:
 
@@ -932,12 +1188,18 @@
 	return;
 }
 
+#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4)))
+#error "Please update axe_bulk_write_callback()!"
+#endif
+
 static void
 axe_bulk_write_callback(struct usbd_xfer *xfer)
 {
 	struct axe_softc *sc = xfer->priv_sc;
+	struct axe_sframe_hdr hdr;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct mbuf *m;
+	uint16_t pos;
 
 	USBD_CHECK_STATUS(xfer);
 
@@ -975,33 +1237,69 @@
 	    goto done;
 	}
 
-	IF_DEQUEUE(&(ifp->if_snd), m);
+	pos = 0;
+
+	while (1) {
+
+	    IF_DEQUEUE(&(ifp->if_snd), m);
+
+	    if (m == NULL) {
+	        if (pos > 0)
+		  break; /* send out data */
+		else
+		  goto done;
+	    }
+
+	    if (m->m_pkthdr.len > MCLBYTES) {
+	        m->m_pkthdr.len = MCLBYTES;
+	    }
+
+	    if (sc->sc_flags & (AXE_FLAG_772|AXE_FLAG_178)) {
+
+	        hdr.len = htole16(m->m_pkthdr.len);
+		hdr.ilen = ~hdr.len;
+
+		usbd_copy_in(&(xfer->buf_data), pos, &hdr, sizeof(hdr));
+
+		pos += sizeof(hdr);
+
+		/* NOTE: Some drivers force a short 
+		 * packet by appending a dummy header
+		 * with zero length at then end of the
+		 * USB transfer. This driver uses the
+		 * USBD_FORCE_SHORT_XFER flag instead.
+		 */
+	    }
 
-	if (m == NULL) {
-	    goto done;
-	}
+	    usbd_m_copy_in(&(xfer->buf_data), pos, 
+			   m, 0, m->m_pkthdr.len);
 
-	if (m->m_pkthdr.len > MCLBYTES) {
-	    m->m_pkthdr.len = MCLBYTES;
-	}
+	    pos += m->m_pkthdr.len;
 
-	xfer->length = m->m_pkthdr.len;
+	    /*
+	     * if there's a BPF listener, bounce a copy 
+	     * of this frame to him:
+	     */
+	    BPF_MTAP(ifp, m);
 
-	usbd_m_copy_in(&(xfer->buf_data), 0, 
-		       m, 0, m->m_pkthdr.len);
+	    m_freem(m);
 
-	/*
-	 * if there's a BPF listener, bounce a copy 
-	 * of this frame to him:
-	 */
-	BPF_MTAP(ifp, m);
+	    if (sc->sc_flags & (AXE_FLAG_772|AXE_FLAG_178)) {
+	        if (pos > (AXE_BULK_BUF_SIZE-MCLBYTES-sizeof(hdr))) {
+		    /* send out frame(s) */
+		    break;
+		}
+	    } else {
+	        /* send out frame */
+	        break;
+	    }
+	}
 
-	m_freem(m);
+	xfer->length = pos;
 
 	usbd_start_hardware(xfer);
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
  done:
 	return;
 }
@@ -1118,12 +1416,22 @@
 #endif
 
 	/* Set transmitter IPG values */
-	axe_cfg_cmd(sc, AXE_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL);
-	axe_cfg_cmd(sc, AXE_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL);
-	axe_cfg_cmd(sc, AXE_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL);
+	if (sc->sc_flags & (AXE_FLAG_178|AXE_FLAG_772)) {
+	    axe_cfg_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2],
+			(sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL);
+	} else {
+	    axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL);
+	    axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL);
+	    axe_cfg_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_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->sc_flags & (AXE_FLAG_178|AXE_FLAG_772)) {
+	    rxmode |= AXE_178_RXCMD_MFB_16384; /* default */
+	} else {
+	    rxmode |= AXE_172_RXCMD_UNICAST;
+	}
 
 	/* If we want promiscuous mode, set the allframes bit. */
 	if (cc->if_flags & IFF_PROMISC) {

==== //depot/projects/usb/src/sys/dev/usb/if_axereg.h#12 (text+ko) ====

@@ -33,15 +33,15 @@
  */
 
 /*
- * Definitions for the ASIX Electronics AX88172 to ethernet controller.
+ * Definitions for the ASIX Electronics AX88172, AX88178 
+ * and AX88772 to ethernet controllers.
  */
 
-
 /*
  * Vendor specific commands.  ASIX conveniently doesn't document the 'set
  * NODEID' command in their datasheet (thanks a lot guys).
  * To make handling these commands easier, I added some extra data which is
- * decided by the axe_cmd() routine. Commands are encoded in 16 bytes, with
+ * decided by the axe_cmd() routine. Commands are encoded in 16 bits, with
  * the format: LDCC. L and D are both nibbles in the high byte.  L represents
  * the data length (0 to 15) and D represents the direction (0 for vendor read,
  * 1 for vendor write).  CC is the command byte, as specified in the manual.
@@ -51,49 +51,93 @@
 #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_182_CMD_WRITE_RXTX_SRAM		0x8103
+#define	AXE_172_CMD_WRITE_TX_SRAM		0x0104
 #define	AXE_CMD_MII_OPMODE_SW			0x0106
 #define	AXE_CMD_MII_READ_REG			0x2007
 #define	AXE_CMD_MII_WRITE_REG			0x2108
 #define	AXE_CMD_MII_READ_OPMODE			0x1009
 #define	AXE_CMD_MII_OPMODE_HW			0x010A
-#define AXE_CMD_SROM_READ			0x200B
+#define	AXE_CMD_SROM_READ			0x200B
 #define	AXE_CMD_SROM_WRITE			0x010C
 #define	AXE_CMD_SROM_WR_ENABLE			0x010D
 #define	AXE_CMD_SROM_WR_DISABLE			0x010E
 #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_178_CMD_WRITE_IPG012		0x0112
+#define	AXE_172_CMD_WRITE_IPG1			0x0113
+#define	AXE_178_CMD_READ_NODEID			0x6013
+#define	AXE_172_CMD_WRITE_IPG2			0x0114
+#define	AXE_178_CMD_WRITE_NODEID		0x6114
 #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_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_CMD_SW_RESET_REG			0x0120
+#define	AXE_CMD_SW_PHY_STATUS			0x0021
+#define	AXE_CMD_SW_PHY_SELECT			0x0122
+
+#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
+
+#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_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
+#define	AXE_178_RXCMD_MFB_MASK			0x0300
+#define	AXE_178_RXCMD_MFB_2048			0x0000
+#define	AXE_178_RXCMD_MFB_4096			0x0100
+#define	AXE_178_RXCMD_MFB_8192			0x0200
+#define	AXE_178_RXCMD_MFB_16384			0x0300
 
 #define	AXE_NOPHY				0xE0
+#define	AXE_INTPHY				0x10
 
-#define	AXE_TIMEOUT		1000
-#define	AXE_MIN_FRAMELEN	60
-#define	AXE_RX_FRAMES		1
-#define	AXE_TX_FRAMES		1
+#define AXE_BULK_BUF_SIZE	16384 /* bytes */
 
 #define	AXE_CTL_READ		0x01
 #define	AXE_CTL_WRITE		0x02
@@ -107,9 +151,15 @@
 struct axe_type {
 	uint16_t		axe_vid;
 	uint16_t		axe_did;
+	uint16_t		axe_flags;
 };
 
-#define GET_MII(sc)	((sc)->sc_miibus ?				\
+struct axe_sframe_hdr {
+	uint16_t		len;
+	uint16_t		ilen;
+} __packed;
+
+#define	GET_MII(sc)	((sc)->sc_miibus ?				\
 			    device_get_softc((sc)->sc_miibus) : NULL)
 
 struct axe_softc {
@@ -136,6 +186,8 @@
 #define	AXE_FLAG_WRITE_STALL	0x0008
 #define	AXE_FLAG_LL_READY	0x0010
 #define	AXE_FLAG_HL_READY	0x0020
+#define	AXE_FLAG_772		0x0040 /* AX88772 */
+#define	AXE_FLAG_178		0x0080 /* AX88178 */
 
 	uint8_t     		sc_ipgs[3];
 	uint8_t      		sc_phyaddrs[2];

==== //depot/projects/usb/src/sys/dev/usb/if_ural.c#21 (text+ko) ====

@@ -231,9 +231,9 @@
 	{ USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DWLG122 },
 	{ USB_VENDOR_GIGABYTE,		USB_PRODUCT_GIGABYTE_GNWBKG },
 	{ USB_VENDOR_GUILLEMOT,		USB_PRODUCT_GUILLEMOT_HWGUSB254 },
-	{ USB_VENDOR_LINKSYS4,		USB_PRODUCT_LINKSYS4_WUSB54G },
-	{ USB_VENDOR_LINKSYS4,		USB_PRODUCT_LINKSYS4_WUSB54GP },
-	{ USB_VENDOR_LINKSYS4,		USB_PRODUCT_LINKSYS4_HU200TS },
+	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54G },
+	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GP },
+	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_HU200TS },
 	{ USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_KG54 },
 	{ USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_KG54AI },
 	{ USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_KG54YB },

==== //depot/projects/usb/src/sys/dev/usb/usbdevs#8 (text+ko) ====

@@ -65,6 +65,7 @@
 vendor EGALAX2		0x0123	eGalax
 vendor NETGEAR3		0x1385	Netgear
 vendor WISTRONNEWEB	0x1435	Wistron NeWeb
+vendor OQO		0x1557	OQO
 vendor UMEDIA		0x157e	U-MEDIA Communications
 vendor LTS		0x0386	LTS
 vendor AOX		0x03e8	AOX
@@ -525,7 +526,7 @@
 vendor WISTRONNEWEB	0x1435	Wistron NeWeb
 vendor MOBILITY		0x1342	Mobility
 vendor RADIOSHACK	0x1453	Radio Shack
-vendor LINKSYS4		0x13b1	Linksys
+vendor CISCOLINKSYS	0x13b1	Linksys
 vendor SHARK		0x13d2	Shark
 vendor NOVATEL2		0x1410	Novatel
 vendor SILICOM		0x1485	Silicom
@@ -539,12 +540,14 @@
 vendor SOHOWARE		0x15e8	SOHOware
 vendor UMAX		0x1606	UMAX
 vendor INSIDEOUT	0x1608	Inside Out Networks
+vendor GOODWAY		0x1631	Good Way Technology
 vendor ENTREGA		0x1645	Entrega
 vendor ACTIONTEC	0x1668	Actiontec
 vendor ATHEROS		0x168c	Atheros Communications
 vendor GIGASET		0x1690	Gigaset
 vendor GLOBALSUN	0x16ab	Global Sun Technology
 vendor CMOTECH		0x16d8	CMOTECH CO., LTD.
+vendor LINKSYS4		0x1737	Linksys
 vendor LINKSYS3		0x1915	Linksys
 vendor DLINK		0x2001	D-Link
 vendor PLANEX2		0x2019	Planex Communications
@@ -607,6 +610,7 @@
 product ABOCOM XX7		0x400c	XX7
 product ABOCOM XX8		0x4102	XX8
 product ABOCOM XX9		0x4104	XX9
+product ABOCOM UF200		0x420a	UF200 Ethernet
 product ABOCOM WL54		0x6001	WL54
 product ABOCOM XX10		0xabc1	XX10
 
@@ -718,6 +722,8 @@
 
 /* ASIX Electronics products */
 product ASIX AX88172		0x1720  10/100 ethernet
+product ASIX AX88178		0x1780	10/100 ethernet
+product ASIX AX88772		0x7720	10/100 ethernet
 
 /* ASUS products */
 product ASUS WL167G		0x1707	WL-167g wireless adapter
@@ -727,6 +733,7 @@
 product ATEN UC1284		0x2001	Parallel printer
 product ATEN UC10T		0x2002	10Mbps ethernet
 product ATEN UC232A		0x2008	Serial
+product ATEN UC210T		0x2009	UC210T Ethernet
 
 /* Atheros Communications products */
 product ATHEROS AR5523		0x0001	AR5523
@@ -761,6 +768,7 @@
 product BELKIN F5U409		0x0409	F5U409 Serial
 product BELKIN F6C550AVR	0x0551	F6C550-AVR UPS
 product BELKIN F5U120		0x1203	F5U120-PC Hub
+product BELKIN F5D5055		0x5055	F5D5055 ethernet
 product BELKIN F5D7050		0x7050	F5D7050 wireless adapter
 product BELKIN F5D7050C		0x705c	F5D705C 54g USB Network Adapter
 
@@ -769,6 +777,7 @@
 product BILLIONTON USBLP100	0x0987	USB100LP
 product BILLIONTON USBEL100	0x0988	USB100EL
 product BILLIONTON USBE100	0x8511	USBE100
+product BILLIONTON USB2AR	0x90ff	USB2AR/SNAPPORT Ethernet
 
 /* Broadcom products */
 product BROADCOM BCM2033	0x2033	BCM2033 Bluetooth USB dongle
@@ -812,6 +821,12 @@
 /* Chicony products */
 product CHICONY KB8933		0x0001	KB-8933 keyboard
 
+/* Cisco Linksys products */
+product CISCOLINKSYS WUSB54G	0x000d	WUSB54G wireless adapter
+product CISCOLINKSYS WUSB54GP	0x0011	WUSB54GP wireless adapter
+product CISCOLINKSYS USB200MV2	0x0018	USB 2.0 10/100 ethernet v2.0
+product CISCOLINKSYS HU200TS	0x001a	HU200TS wireless adapter
+
 /* CMOTECH products */
 product CMOTECH CDMA_MODEM0	0x5141	CMOTECH CDMA Technologies USB modem
 product CMOTECH CDMA_MODEM1	0x6280	CMOTECH CDMA Technologies USB modem
@@ -828,6 +843,7 @@
 product COREGA ETHER_USB_T	0x0001	Ether USB-T
 product COREGA FETHER_USB_TX	0x0004	FEther USB-TX
 product COREGA FETHER_USB_TXS	0x000d	FEther USB-TXS
+product COREGA FETHER_USB2_TX	0x0017	FEther USB2-TX
 product COREGA FETHER_USB_TXC	0x9601	FEther USB-TXC
 
 /* Creative products */
@@ -897,6 +913,7 @@
 product DLINK DUBE100		0x1a00	10/100 ethernet
 product DLINK DSB650TX4		0x200c	10/100 ethernet
 product DLINK DWLG122		0x3c00	DWL-G122 b1 wireless adapter
+product DLINK DUBE100B1		0x3c05	DUB-E100 rev B1
 product DLINK DWLAG122		0x3a04	DWL-AG122
 product DLINK DWLAG122_NF	0x3a05	DWL-AG122 (no firmware)
 product DLINK DWLAG132		0x3a00	DWL-AG132
@@ -1042,6 +1059,9 @@
 /* G.Mate, Inc products */
 product GMATE YP3X00		0x1001	YP3X00 PDA
 
+/* Good Way Technology products */
+product GOODWAY GWUSB2E		0x6200	GWUSB2E
+
 /* Guillemot Corporation */
 product GUILLEMOT DALEADER	0xa300	DA Leader
 product GUILLEMOT HWGUSB254	0xe000	HWGUSB2-54 WLAN
@@ -1147,6 +1167,7 @@
 product IODATA USBETT		0x0901	USB ETT
 product IODATA USBETTX		0x0904	USB ETTX
 product IODATA USBETTXS		0x0913	USB ETTX
+product IODATA ETGUS2		0x0930	ETG-US2
 product IODATA USBRSAQ		0x0a03	Serial USB-RSAQ1
 
 /* Iomega products */
@@ -1244,6 +1265,7 @@
 product LEXMARK S2450		0x0009	Optra S 2450
 
 /* Linksys products */
+product LINKSYS4 USB1000	0x0039	USB1000
 product LINKSYS MAUSB2		0x0105	Camedia MAUSB-2
 product LINKSYS USB10TX1	0x200c	USB10TX
 product LINKSYS USB10T		0x2202	USB10T Ethernet
@@ -1254,9 +1276,6 @@
 product LINKSYS2 WUSB11		0x2219	WUSB11 Wireless adapter
 product LINKSYS2 USB200M	0x2226	USB 2.0 10/100 ethernet
 product LINKSYS3 WUSB11v28	0x2233	WUSB11 v2.8 wireless adapter
-product LINKSYS4 WUSB54G	0x000d	WUSB54G wireless adapter
-product LINKSYS4 WUSB54GP	0x0011	WUSB54GP wireless adapter
-product LINKSYS4 HU200TS	0x001a	HU200TS wireless adapter
 
 /* Logitech products */
 product LOGITECH M2452		0x0203	M2452 keyboard
@@ -1453,6 +1472,9 @@
 /* OnSpec Electronic, Inc. */
 product ONSPEC UCF100		0xa400	FlashLink UCF-100 CompactFlash Reader
 
+/* OQO */
+product OQO ETHER01PLUS		0x7720	model 01+ Ethernet
+
 /* Palm Computing, Inc. product */
 product PALM SERIAL		0x0080	USB Serial
 product PALM M500		0x0001	Palm m500
@@ -1496,6 +1518,7 @@
 product PIENGINEERING PS2USB	0x020b	PS2 to Mac USB Adapter
 
 /* Planex Communications products */
+product PLANEX3 GU1000T		0xab11	GU-1000T
 product PLANEX3 GWUS54MINI	0xab13	GW-US54Mini
 product PLANEX2 GWUS54GZL	0xc007	GW-US54GZL
 
@@ -1651,6 +1674,7 @@
 product SITECOM SERIAL		0x2068	USB to serial cable (v2)
 
 /* Sitecom Europe products */
+product SITECOMEU LN028		0x061c	LN-028
 product SITECOMEU WL113		0x9071	WL-113
 
 /* SmartBridges products */
@@ -1721,6 +1745,9 @@
 /* Sweex products */
 product SWEEX ZD1211		0x1809	ZD1211
 
+/* Surecom products */
+product ACERCM EP1427X2		0x0893	EP-1427X-2 Ethernet
+
 /* System TALKS, Inc. */
 product SYSTEMTALKS SGCX2UL	0x1920	SGC-X2UL
 


More information about the p4-projects mailing list