Index | Thread | Search

From:
Kevin Lo <kevlo@openbsd.org>
Subject:
Re: two ASIX devices: DLINK DUB-1312 & TPLINK UE-306
To:
tech@openbsd.org
Date:
Thu, 4 Jan 2024 10:09:57 +0800

Download raw body.

Thread
On Tue, Dec 19, 2023 at 05:32:48PM +0800, Kevin Lo wrote:
> 
> On Sat, Dec 16, 2023 at 10:34:46AM +0100, Landry Breuil wrote:
> > hi
> 
> Hi Landry,
> 
> > wanting to replace an axen that constantly spouts 'axen0: checksum err
> > (pkt#1)' i've bought two 'cheap' usb-eth devices, supposedly also having
> > AX88179:
> > 
> > -DLINK DUB-1312 is supported by axen(4) according to the manpage, but
> > plugging the device it attaches as cdce, since
> > https://marc.info/?l=openbsd-tech&m=168233597211047&w=2:
> > 
> > cdce0 at uhub0 port 13 "ASIX AX88179A" rev 3.20/2.00 addr 2
> > cdce0: address 64:29:43:6d:04:94
> > 
> > on the device, the P/N is EUB1312...C1G, i guess a new revision.
> > the complete lsusb output for both devices is attached.
> > 
> > tcpbench isnt so bad:
> > 150610824 bytes sent over 12.985 seconds
> > bandwidth min/avg/max/std-dev = 92.498/92.804/93.182/0.161 Mbps
> > 
> > according to kevlo,
> > https://github.com/freebsd/freebsd-src/commit/70fbcd451b68b7f6038d8a602cd8d5e1bb890f1d
> 
> This is a quick fix for AX88179A. The diff below skips dummy packet headers,
> which fixes 'axen0: invalid buffer(pkt#1), continue'.
> 
> While here, update man page to reflect ax88179a support.
> 
> Tested with:
> axen0 at uhub0 port 15 configuration 1 interface 0 "ASIX AX88179A" rev 3.20/2.00 addr 4
> axen0: AX88179A, address f8:e4:3b:xx:xx:xx
> ukphy0 at axen0 phy 3: Generic IEEE 802.3u media interface, rev. 1: OUI 0x00070b, model 0x0006
> 
> axen1 at uhub0 port 16 configuration 1 interface 0 "ASIX Elec. Corp. AX88179" rev 3.00/1.00 addr 5
> axen1: AX88179, address 00:0e:c6:xx:xx:xx
> rgephy1 at axen1 phy 3: RTL8169S/8110S/8211 PHY, rev. 5
> 
> ok?

Anyone willing to ok?

I found that NetBSD has a similar diff for axen:
https://github.com/NetBSD/src/commit/e97ed546208ee5b6e45242b7d0e8de4e62e2c2aa

> Index: share/man/man4/axen.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/axen.4,v
> retrieving revision 1.9
> diff -u -p -u -p -r1.9 axen.4
> --- share/man/man4/axen.4	8 Sep 2021 20:29:21 -0000	1.9
> +++ share/man/man4/axen.4	19 Dec 2023 09:24:49 -0000
> @@ -19,15 +19,16 @@
>  .Os
>  .Sh NAME
>  .Nm axen
> -.Nd ASIX Electronics AX88179 10/100/1Gb USB Ethernet device
> +.Nd ASIX Electronics AX88179/AX88179A 10/100/1Gb USB Ethernet device
>  .Sh SYNOPSIS
>  .Cd "axen*   at uhub?"
>  .Cd "rgephy* at mii?"
> +.Cd "ukphy* at mii?"
>  .Sh DESCRIPTION
>  The
>  .Nm
>  driver provides support for USB Ethernet adapters based on the ASIX
> -Electronics AX88179 USB 3.0 chipset, including the following:
> +Electronics AX88179/AX88179A USB 3.0 chipset, including the following:
>  .Pp
>  .Bl -tag -width Ds -offset indent -compact
>  .It D-Link DUB-1312
> @@ -35,6 +36,8 @@ Electronics AX88179 USB 3.0 chipset, inc
>  .It Logitec LAN-GTJU3
>  .It Sitecom LN-032
>  .It StarTech USB31000S
> +.It TP-LINK UE300C v2
> +.It TP-Link UE306
>  .El
>  .Pp
>  The
> @@ -63,6 +66,7 @@ For more information on configuring this
>  .Xr intro 4 ,
>  .Xr netintro 4 ,
>  .Xr rgephy 4 ,
> +.Xr ukphy 4 ,
>  .Xr usb 4 ,
>  .Xr hostname.if 5 ,
>  .Xr ifconfig 8
> Index: share/man/man4/usb.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/usb.4,v
> retrieving revision 1.216
> diff -u -p -u -p -r1.216 usb.4
> --- share/man/man4/usb.4	6 May 2023 08:14:26 -0000	1.216
> +++ share/man/man4/usb.4	19 Dec 2023 09:24:49 -0000
> @@ -112,7 +112,7 @@ ADMtek AN986/ADM8511 Pegasus family 10/1
>  .It Xr axe 4
>  ASIX Electronics AX88172/AX88178/AX88772 10/100/1Gb USB Ethernet device
>  .It Xr axen 4
> -ASIX Electronics AX88179 10/100/1Gb USB Ethernet device
> +ASIX Electronics AX88179/AX88179A 10/100/1Gb USB Ethernet device
>  .It Xr cdce 4
>  USB Communication Device Class Ethernet device
>  .It Xr cue 4
> Index: sys/dev/usb/if_axen.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_axen.c,v
> retrieving revision 1.31
> diff -u -p -u -p -r1.31 if_axen.c
> --- sys/dev/usb/if_axen.c	9 Jan 2022 05:43:00 -0000	1.31
> +++ sys/dev/usb/if_axen.c	19 Dec 2023 09:24:51 -0000
> @@ -17,8 +17,8 @@
>   */
>  
>  /*
> - * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet
> - * driver.
> + * ASIX Electronics AX88178a USB 2.0 ethernet and 
> + * AX88179/AX88179a USB 3.0 Ethernet driver.
>   */
>  
>  #include "bpfilter.h"
> @@ -600,6 +600,7 @@ axen_attach(struct device *parent, struc
>  	struct usb_attach_arg	*uaa = aux;
>  	usb_interface_descriptor_t *id;
>  	usb_endpoint_descriptor_t *ed;
> +	usb_device_descriptor_t *dd;
>  	struct mii_data		*mii;
>  	u_char			 eaddr[ETHER_ADDR_LEN];
>  	char			*devname = sc->axen_dev.dv_xname;
> @@ -658,6 +659,10 @@ axen_attach(struct device *parent, struc
>  		}
>  	}
>  
> +	dd = usbd_get_device_descriptor(sc->axen_udev);
> +	if (UGETW(dd->bcdDevice) == 0x200)
> +		sc->axen_flags = AX179A;
> +
>  	s = splnet();
>  
>  	sc->axen_phyno = AXEN_PHY_ID;
> @@ -680,6 +685,8 @@ axen_attach(struct device *parent, struc
>  		printf(" AX88178a");
>  	else if (sc->axen_flags & AX179)
>  		printf(" AX88179");
> +	else
> +		printf(" AX88179A");
>  	printf(", address %s\n", ether_sprintf(eaddr));
>  
>  	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
> @@ -885,7 +892,7 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  	u_int16_t		hdr_offset, pkt_count;
>  	size_t			pkt_len;
>  	size_t			temp;
> -	int			s;
> +	int			padlen, s;
>  
>  	DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
>  
> @@ -916,7 +923,14 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  
>  	/* 
>  	 * buffer map
> +	 *
> +	 * for ax88179
>  	 * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
> +	 *
> +	 * for ax88179a
> +	 * [packet #0]...[packet #n][pkt hdr#0][dummy_hdr]..
> +	 * [pkt hdr#n][dummy_hdr][recv_hdr]
> +	 *
>  	 * each packet has 0xeeee as pseudo header..
>  	 */
>  	hdr_p = (u_int32_t *)(buf + total_len - sizeof(u_int32_t));
> @@ -953,7 +967,23 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  	}
>  #endif
>  
> +	/* skip pseudo header (2byte) */
> +	padlen = 2;
> +	/* skip trailer padding (4Byte) for ax88179 */
> +	if (!(sc->axen_flags & AX179A))
> +		padlen += 4;
> +
>  	do {
> +		pkt_hdr = letoh32(*hdr_p);
> +		pkt_len = (pkt_hdr >> 16) & 0x1fff;
> +
> +		DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
> +		   pkt_count, pkt_hdr, pkt_len));
> +
> +		/* skip dummy packet header */
> +		if (pkt_len == 0)
> +			goto nextpkt;
> +
>  		if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>  			printf("%s: invalid buffer(pkt#%d), continue\n",
>  			    sc->axen_dev.dv_xname, pkt_count);
> @@ -961,12 +991,6 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  			goto done;
>  		}
>  
> -		pkt_hdr = letoh32(*hdr_p);
> -		pkt_len = (pkt_hdr >> 16) & 0x1fff;
> -
> -		DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
> -		   pkt_count, pkt_hdr, pkt_len));
> -
>  		if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>  	    	    (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
>  	    		ifp->if_ierrors++;
> @@ -983,8 +1007,7 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  			goto nextpkt;
>  		}
>  
> -		/* skip pseudo header (2byte) and trailer padding (4Byte) */
> -		m->m_pkthdr.len = m->m_len = pkt_len - 6;
> +		m->m_pkthdr.len = m->m_len = pkt_len - padlen;
>  
>  #ifdef AXEN_TOE
>  		/* checksum err */
> @@ -1007,7 +1030,7 @@ axen_rxeof(struct usbd_xfer *xfer, void 
>  			    M_UDP_CSUM_IN_OK;
>  #endif
>  
> -		memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
> +		memcpy(mtod(m, char *), buf + 2, pkt_len - padlen);
>  
>  		ml_enqueue(&ml, m);
>  
> Index: sys/dev/usb/if_axenreg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_axenreg.h,v
> retrieving revision 1.6
> diff -u -p -u -p -r1.6 if_axenreg.h
> --- sys/dev/usb/if_axenreg.h	14 Sep 2016 12:41:09 -0000	1.6
> +++ sys/dev/usb/if_axenreg.h	19 Dec 2023 09:24:51 -0000
> @@ -227,6 +227,7 @@ struct axen_type {
>  	u_int16_t		axen_flags;
>  #define AX178A	0x0001		/* AX88178a */
>  #define AX179	0x0002		/* AX88179 */
> +#define AX179A	0x0004		/* AX88179a */
>  };
>  
>  struct axen_softc;
> Index: sys/dev/usb/if_cdce.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_cdce.c,v
> retrieving revision 1.81
> diff -u -p -u -p -r1.81 if_cdce.c
> --- sys/dev/usb/if_cdce.c	27 Apr 2023 08:33:59 -0000	1.81
> +++ sys/dev/usb/if_cdce.c	19 Dec 2023 09:24:51 -0000
> @@ -59,11 +59,8 @@
>  #include <netinet/in.h>
>  #include <netinet/if_ether.h>
>  
> -#include <machine/bus.h>
> -
>  #include <dev/usb/usb.h>
>  #include <dev/usb/usbdi.h>
> -#include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdevs.h>
>  #include <dev/usb/usbcdc.h>
> @@ -93,19 +90,18 @@ void	 cdce_stop(struct cdce_softc *);
>  void	 cdce_intr(struct usbd_xfer *, void *, usbd_status);
>  
>  const struct cdce_type cdce_devs[] = {
> -    {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, 0, 0, -1 },
> -    {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, 0, 0, -1 },
> -    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, 0, CDCE_CRC32, -1 },
> -    {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, 0, 0, -1 },
> -    {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, 0, 0, -1 },
> -    {{ USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250 }, 0, CDCE_SWAPUNION, -1 },
> -    {{ USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179 }, 0x0200, CDCE_MATCHREV, 3 },
> +    {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, 0 },
> +    {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, 0 },
> +    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, CDCE_CRC32 },
> +    {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, CDCE_CRC32 },
> +    {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, 0 },
> +    {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, 0 },
> +    {{ USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250 }, CDCE_SWAPUNION },
>  };
>  #define cdce_lookup(v, p) \
>      ((const struct cdce_type *)usb_lookup(cdce_devs, v, p))
> @@ -127,15 +123,6 @@ cdce_match(struct device *parent, void *
>  {
>  	struct usb_attach_arg *uaa = aux;
>  	usb_interface_descriptor_t *id;
> -	const struct cdce_type *type;
> -
> -	if ((type = cdce_lookup(uaa->vendor, uaa->product)) != NULL) {
> -		if (type->cdce_flags & CDCE_MATCHREV) {
> -			if (type->cdce_rev == uaa->release)
> -				return (UMATCH_VENDOR_PRODUCT_REV);
> -		} else
> -			return (UMATCH_VENDOR_PRODUCT);
> -	}
>  
>  	if (uaa->iface == NULL)
>  		return (UMATCH_NONE);
> @@ -144,6 +131,9 @@ cdce_match(struct device *parent, void *
>  	if (id == NULL)
>  		return (UMATCH_NONE);
>  
> +	if (cdce_lookup(uaa->vendor, uaa->product) != NULL)
> +		return (UMATCH_VENDOR_PRODUCT);
> +
>  	if (id->bInterfaceClass == UICLASS_CDC &&
>  	    (id->bInterfaceSubClass ==
>  	    UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL ||
> @@ -160,6 +150,7 @@ cdce_attach(struct device *parent, struc
>  	struct usb_attach_arg		*uaa = aux;
>  	int				 s;
>  	struct ifnet			*ifp = GET_IFP(sc);
> +	struct usbd_device		*dev = uaa->device;
>  	const struct cdce_type		*t;
>  	usb_interface_descriptor_t	*id;
>  	usb_endpoint_descriptor_t	*ed;
> @@ -172,51 +163,19 @@ cdce_attach(struct device *parent, struc
>  	int				 i, j, numalts, len;
>  	int				 ctl_ifcno = -1;
>  	int				 data_ifcno = -1;
> -	usbd_status			 err;
> -
> -	t = cdce_lookup(uaa->vendor, uaa->product);
> -	if (uaa->configno < 0) {
> -		if (t == NULL || t->cdce_cfgno < 0) {
> -			printf("%s: unknown configuration for vid/pid match\n",
> -			    sc->cdce_dev.dv_xname);
> -			return;
> -		}
> -		uaa->configno = t->cdce_cfgno;
> -		DPRINTF(("%s: switching to config #%d\n",
> -		    sc->cdce_dev.dv_xname));
> -		err = usbd_set_config_no(uaa->device, uaa->configno, 1);
> -		if (err) {
> -			printf("%s: failed to switch to config #%d: %s\n",
> -			    sc->cdce_dev.dv_xname, uaa->configno,
> -			    usbd_errstr(err));
> -			return;
> -		}
> -		for (i = 0; i <  uaa->device->cdesc->bNumInterfaces; i++) {
> -			if (usbd_iface_claimed(uaa->device, i))
> -				continue;
> -			id = usbd_get_interface_descriptor(
> -			    &uaa->device->ifaces[i]);
> -			if (id != NULL && id->bInterfaceClass == UICLASS_CDC &&
> -			    id->bInterfaceSubClass ==
> -			    UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL) {
> -				uaa->iface = &uaa->device->ifaces[i];
> -				uaa->ifaceno = uaa->iface->idesc->bInterfaceNumber;
> -				break;
> -			}
> -		}
> -	}
>  
>  	sc->cdce_udev = uaa->device;
>  	sc->cdce_ctl_iface = uaa->iface;
>  	id = usbd_get_interface_descriptor(sc->cdce_ctl_iface);
>  	ctl_ifcno = id->bInterfaceNumber;
>  
> +	t = cdce_lookup(uaa->vendor, uaa->product);
>  	if (t)
>  		sc->cdce_flags = t->cdce_flags;
>  
>  	/* Get the data interface no. and capabilities */
>  	ethd = NULL;
> -	usbd_desc_iter_init(sc->cdce_udev, &iter);
> +	usbd_desc_iter_init(dev, &iter);
>  	desc = usbd_desc_iter_next(&iter);
>  	while (desc) {
>  		if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
> @@ -251,13 +210,12 @@ cdce_attach(struct device *parent, struc
>  	} else {
>  		DPRINTF(("cdce_attach: union interface: ctl=%d, data=%d\n",
>  		    ctl_ifcno, data_ifcno));
> -		for (i = 0; i < uaa->device->cdesc->bNumInterfaces; i++) {
> +		for (i = 0; i < uaa->nifaces; i++) {
>  			if (usbd_iface_claimed(sc->cdce_udev, i))
>  				continue;
> -			id = usbd_get_interface_descriptor(
> -			    &uaa->device->ifaces[i]);
> +			id = usbd_get_interface_descriptor(uaa->ifaces[i]);
>  			if (id != NULL && id->bInterfaceNumber == data_ifcno) {
> -				sc->cdce_data_iface = &uaa->device->ifaces[i];
> +				sc->cdce_data_iface = uaa->ifaces[i];
>  				usbd_claim_iface(sc->cdce_udev, i);
>  			}
>  		}
> @@ -345,8 +303,8 @@ cdce_attach(struct device *parent, struc
>  found:
>  	s = splnet();
>  
> -	if (!ethd || usbd_get_string_desc(sc->cdce_udev, ethd->iMacAddress,
> -	    sc->cdce_udev->langid, &eaddr_str, &len)) {
> +	if (!ethd || usbd_get_string_desc(sc->cdce_udev, ethd->iMacAddress, 0,
> +	    &eaddr_str, &len)) {
>  		ether_fakeaddr(ifp);
>  	} else {
>  		for (i = 0; i < ETHER_ADDR_LEN * 2; i++) {
> Index: sys/dev/usb/if_cdcereg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_cdcereg.h,v
> retrieving revision 1.8
> diff -u -p -u -p -r1.8 if_cdcereg.h
> --- sys/dev/usb/if_cdcereg.h	27 Apr 2023 08:33:59 -0000	1.8
> +++ sys/dev/usb/if_cdcereg.h	19 Dec 2023 09:24:51 -0000
> @@ -40,12 +40,9 @@
>  
>  struct cdce_type {
>  	struct usb_devno	 cdce_dev;
> -	u_int16_t		 cdce_rev;
>  	u_int16_t		 cdce_flags;
>  #define CDCE_CRC32	1
>  #define CDCE_SWAPUNION	2
> -#define CDCE_MATCHREV	4
> -	int			 cdce_cfgno;
>  };
>  
>  struct cdce_softc;
>