Add support for AX88179A. AX88179A interweave dummies alongside valid
authorkevlo <kevlo@openbsd.org>
Thu, 4 Jan 2024 08:41:59 +0000 (08:41 +0000)
committerkevlo <kevlo@openbsd.org>
Thu, 4 Jan 2024 08:41:59 +0000 (08:41 +0000)
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
share/man/man4/usb.4
sys/dev/usb/if_axen.c
sys/dev/usb/if_axenreg.h
sys/dev/usb/if_cdce.c
sys/dev/usb/if_cdcereg.h

index c1a42db..81ca9ba 100644 (file)
@@ -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 <yuo@nui.org>
 .\"
 .\" 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
index f27b454..1d95449 100644 (file)
@@ -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
index 7b4cc2d..f60af2a 100644 (file)
@@ -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 <yuo@openbsd.org>
@@ -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);
 
index 8de2c6d..98be650 100644 (file)
@@ -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 <yuo@openbsd.org>. 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;
index 6ca142c..faa5ba5 100644 (file)
@@ -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 <wpaul@windriver.com>
 #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 *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++) {
index 6d08efe..de49c8d 100644 (file)
@@ -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 <wpaul@windriver.com>
 
 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;