From 9c887effe59fe24e35e1e1a370e24a5ae51e393a Mon Sep 17 00:00:00 2001 From: kevlo Date: Thu, 4 Jan 2024 08:41:59 +0000 Subject: [PATCH] Add support for AX88179A. AX88179A interweave dummies alongside valid packet headers in axen_rxeof(). However current driver records these dummy headers as dropped frames, leading to stats misreporting one Ifail per Ipkt. This skips those dummy headers silently, thereby not generating Ifail for them. From FreeBSD commit 70fbcd451b68b7f6038d8a602cd8d5e1bb890f1d Tested by landry@ and myself. ok claudio@, landry@ --- share/man/man4/axen.4 | 12 ++++-- share/man/man4/usb.4 | 6 +-- sys/dev/usb/if_axen.c | 49 ++++++++++++++++------ sys/dev/usb/if_axenreg.h | 3 +- sys/dev/usb/if_cdce.c | 90 +++++++++++----------------------------- sys/dev/usb/if_cdcereg.h | 5 +-- 6 files changed, 74 insertions(+), 91 deletions(-) diff --git a/share/man/man4/axen.4 b/share/man/man4/axen.4 index c1a42dbd287..81ca9bab06a 100644 --- a/share/man/man4/axen.4 +++ b/share/man/man4/axen.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: axen.4,v 1.9 2021/09/08 20:29:21 jmc Exp $ +.\" $OpenBSD: axen.4,v 1.10 2024/01/04 08:41:59 kevlo Exp $ .\" .\" Copyright (c) 2013 Yojiro UO .\" @@ -14,20 +14,21 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 8 2021 $ +.Dd $Mdocdate: January 4 2024 $ .Dt AXEN 4 .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, including the following: .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 device, see .Xr intro 4 , .Xr netintro 4 , .Xr rgephy 4 , +.Xr ukphy 4 , .Xr usb 4 , .Xr hostname.if 5 , .Xr ifconfig 8 diff --git a/share/man/man4/usb.4 b/share/man/man4/usb.4 index f27b454861c..1d95449fdd6 100644 --- a/share/man/man4/usb.4 +++ b/share/man/man4/usb.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: usb.4,v 1.216 2023/05/06 08:14:26 kevlo Exp $ +.\" $OpenBSD: usb.4,v 1.217 2024/01/04 08:41:59 kevlo Exp $ .\" $NetBSD: usb.4,v 1.15 1999/07/29 14:20:32 augustss Exp $ .\" .\" Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 6 2023 $ +.Dd $Mdocdate: January 4 2024 $ .Dt USB 4 .Os .Sh NAME @@ -112,7 +112,7 @@ ADMtek AN986/ADM8511 Pegasus family 10/100 USB Ethernet device .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 diff --git a/sys/dev/usb/if_axen.c b/sys/dev/usb/if_axen.c index 7b4cc2d4043..f60af2a7ccd 100644 --- a/sys/dev/usb/if_axen.c +++ b/sys/dev/usb/if_axen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_axen.c,v 1.31 2022/01/09 05:43:00 jsg Exp $ */ +/* $OpenBSD: if_axen.c,v 1.32 2024/01/04 08:41:59 kevlo Exp $ */ /* * Copyright (c) 2013 Yojiro UO @@ -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, struct device *self, void *aux) 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, struct device *self, void *aux) } } + 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, struct device *self, void *aux) 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 *priv, usbd_status status) 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 *priv, usbd_status status) /* * 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 *priv, usbd_status status) } #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 *priv, usbd_status status) 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 *priv, usbd_status status) 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 *priv, usbd_status status) 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); diff --git a/sys/dev/usb/if_axenreg.h b/sys/dev/usb/if_axenreg.h index 8de2c6d5097..98be650b5eb 100644 --- a/sys/dev/usb/if_axenreg.h +++ b/sys/dev/usb/if_axenreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_axenreg.h,v 1.6 2016/09/14 12:41:09 mpi Exp $ */ +/* $OpenBSD: if_axenreg.h,v 1.7 2024/01/04 08:41:59 kevlo Exp $ */ /* * Copyright (c) 2013 Yojiro UO . All right reserved. @@ -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; diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c index 6ca142c1e66..faa5ba5d53d 100644 --- a/sys/dev/usb/if_cdce.c +++ b/sys/dev/usb/if_cdce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cdce.c,v 1.81 2023/04/27 08:33:59 gerhard Exp $ */ +/* $OpenBSD: if_cdce.c,v 1.82 2024/01/04 08:41:59 kevlo Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul @@ -59,11 +59,8 @@ #include #include -#include - #include #include -#include #include #include #include @@ -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 *match, void *aux) { 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 *match, void *aux) 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, struct device *self, void *aux) 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, struct device *self, void *aux) 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, struct device *self, void *aux) } 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, struct device *self, void *aux) 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++) { diff --git a/sys/dev/usb/if_cdcereg.h b/sys/dev/usb/if_cdcereg.h index 6d08efeec2a..de49c8d56d8 100644 --- a/sys/dev/usb/if_cdcereg.h +++ b/sys/dev/usb/if_cdcereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cdcereg.h,v 1.8 2023/04/27 08:33:59 gerhard Exp $ */ +/* $OpenBSD: if_cdcereg.h,v 1.9 2024/01/04 08:41:59 kevlo Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul @@ -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; -- 2.20.1