Module Name: src Committed By: skrll Date: Tue Dec 19 07:05:36 UTC 2023
Modified Files: src/sys/dev/usb: if_axen.c Log Message: Add support for AX88179A. From sc.dying on current-users. To generate a diff of this commit: cvs rdiff -u -r1.94 -r1.95 src/sys/dev/usb/if_axen.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_axen.c diff -u src/sys/dev/usb/if_axen.c:1.94 src/sys/dev/usb/if_axen.c:1.95 --- src/sys/dev/usb/if_axen.c:1.94 Sat Aug 20 14:08:59 2022 +++ src/sys/dev/usb/if_axen.c Tue Dec 19 07:05:36 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_axen.c,v 1.94 2022/08/20 14:08:59 riastradh Exp $ */ +/* $NetBSD: if_axen.c,v 1.95 2023/12/19 07:05:36 skrll Exp $ */ /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ /* @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.94 2022/08/20 14:08:59 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.95 2023/12/19 07:05:36 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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