hi,

Attached patch should add support AX88179A.


--- src/sys/dev/usb/if_axen.c.orig      2022-08-20 23:30:49.194557768 +0000
+++ src/sys/dev/usb/if_axen.c   2023-11-19 20:56:42.716569803 +0000
@@ -52,6 +52,12 @@ struct axen_type {
        uint16_t                axen_flags;
 #define AX178A 0x0001          /* AX88178a */
 #define AX179  0x0002          /* AX88179 */
+#define AX179A 0x0004          /* AX88179A */
+};
+
+struct axen_softc {
+       struct usbnet           axen_un;
+       uint16_t                axen_flags;
 };
 
 /*
@@ -70,7 +76,7 @@ static const struct axen_type axen_devs[
 static int     axen_match(device_t, cfdata_t, void *);
 static void    axen_attach(device_t, device_t, void *);
 
-CFATTACH_DECL_NEW(axen, sizeof(struct usbnet),
+CFATTACH_DECL_NEW(axen, sizeof(struct axen_softc),
        axen_match, axen_attach, usbnet_detach, usbnet_activate);
 
 static int     axen_cmd(struct usbnet *, int, int, int, void *);
@@ -572,14 +578,14 @@ static void
 axen_attach(device_t parent, device_t self, void *aux)
 {
        USBNET_MII_DECL_DEFAULT(unm);
-       struct usbnet * const un = device_private(self);
+       struct axen_softc * const sc = device_private(self);
+       struct usbnet * const un = &sc->axen_un;
        struct usb_attach_arg *uaa = aux;
        struct usbd_device *dev = uaa->uaa_device;
        usbd_status err;
        usb_interface_descriptor_t *id;
        usb_endpoint_descriptor_t *ed;
        char *devinfop;
-       uint16_t axen_flags;
        int i;
 
        aprint_naive("\n");
@@ -590,7 +596,7 @@ axen_attach(device_t parent, device_t se
 
        un->un_dev = self;
        un->un_udev = dev;
-       un->un_sc = un;
+       un->un_sc = sc;
        un->un_ops = &axen_ops;
        un->un_rx_xfer_flags = USBD_SHORT_XFER_OK;
        un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER;
@@ -604,7 +610,12 @@ axen_attach(device_t parent, device_t se
                return;
        }
 
-       axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags;
+       sc->axen_flags =
+           axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags;
+       if (UGETW(usbd_get_device_descriptor(dev)->bcdDevice) == 0x0200) {
+               sc->axen_flags &= ~(AX178A | AX179);
+               sc->axen_flags |= AX179A;
+       }
 
        err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX, &un->un_iface);
        if (err) {
@@ -663,11 +674,25 @@ axen_attach(device_t parent, device_t se
 
        axen_ax88179_init(un);
 
+#if 0
+#define   AXEN_FW_MODE                         0x08
+#define     AXEN_FW_MODE_178A179               0x0000
+#define     AXEN_FW_MODE_179A                  0x0001
+       if (sc->axen_flags & AX179A) {
+               uint8_t bval = 0;
+               /*          len         dir       cmd */
+               int cmd = (1 << 12) | (1 << 8) | (AXEN_FW_MODE & 0x00FF);
+               axen_cmd(un, cmd, 1, AXEN_FW_MODE_178A179, &bval);
+       }
+#endif
+
        /* An ASIX chip was detected. Inform the world.  */
-       if (axen_flags & AX178A)
+       if (sc->axen_flags & AX178A)
                aprint_normal_dev(self, "AX88178a\n");
-       else if (axen_flags & AX179)
+       else if (sc->axen_flags & AX179)
                aprint_normal_dev(self, "AX88179\n");
+       else if (sc->axen_flags & AX179A)
+               aprint_normal_dev(self, "AX88179A\n");
        else
                aprint_normal_dev(self, "(unknown)\n");
 
@@ -735,6 +760,7 @@ axen_csum_flags_rx(struct ifnet *ifp, ui
 static void
 axen_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
 {
+       struct axen_softc * const sc = usbnet_softc(un);
        struct ifnet *ifp = usbnet_ifp(un);
        uint8_t *buf = c->unc_buf;
        uint32_t rx_hdr, pkt_hdr;
@@ -752,7 +778,7 @@ axen_uno_rx_loop(struct usbnet *un, stru
        /*
         * buffer map
         * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
-        * each packet has 0xeeee as psuedo header..
+        * each packet has 0xeeee as pseudo header..
         */
        hdr_p = (uint32_t *)(buf + total_len - sizeof(uint32_t));
        rx_hdr = le32toh(*hdr_p);
@@ -789,7 +815,7 @@ axen_uno_rx_loop(struct usbnet *un, stru
        if (pkt_count)
                rnd_add_uint32(usbnet_rndsrc(un), pkt_count);
 
-       do {
+       while (pkt_count > 0) {
                if ((buf[0] != 0xee) || (buf[1] != 0xee)) {
                        aprint_error_dev(un->un_dev,
                            "invalid buffer(pkt#%d), continue\n", pkt_count);
@@ -803,6 +829,9 @@ axen_uno_rx_loop(struct usbnet *un, stru
                    ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
                   device_xname(un->un_dev), pkt_count, pkt_hdr, pkt_len));
 
+               if (pkt_len < sizeof(struct ether_header) + ETHER_ALIGN)
+                       goto nextpkt;
+
                if (pkt_hdr & (AXEN_RXHDR_CRC_ERR | AXEN_RXHDR_DROP_ERR)) {
                        if_statinc(ifp, if_ierrors);
                        /* move to next pkt header */
@@ -813,7 +842,15 @@ axen_uno_rx_loop(struct usbnet *un, stru
                        goto nextpkt;
                }
 
-               usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6,
+               if (sc->axen_flags & AX179A) {
+                       /* each 88179A frame doesn't contain FCS. */
+                       usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 2,
+                              axen_csum_flags_rx(ifp, pkt_hdr), 0, 0);
+                       /* 88179A next pkt_hdr looks bogus, skip it. */
+                       hdr_p++;
+                       pkt_count--;
+               } else
+                       usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6,
                               axen_csum_flags_rx(ifp, pkt_hdr), 0, 0);
 
 nextpkt:
@@ -825,8 +862,10 @@ nextpkt:
                temp = ((pkt_len + 7) & 0xfff8);
                buf = buf + temp;
                hdr_p++;
+               if (pkt_count == 0)
+                       break;
                pkt_count--;
-       } while (pkt_count > 0);
+       }
 }
 
 static unsigned

Reply via email to