this adds support to axe(4) for the ax88772b usb ethernet adapter that came with my asus ux21.
it adds the usb device and an ax88772b-specific register that freebsd sets[1]. according to linux[2], the ax88772b only uses 11 bits of the header for the actual packet size and the other bits are used for something else. older chips didn't use those extra 5 bits, so they didn't produce length mismatches. this makes the length checks only look at 11 bits. tested and working on the ax88772b with no input errors. tested and still working on an older apple ax88772 usb adapter. 1. http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/net/if_axe.c.diff?r1=1.37;r2=1.38 and http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/net/if_axereg.h.diff?r1=1.7;r2=1.8 2. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=bca0beb9363f8487ac902931a50eb00180a2d14a Index: dev/usb/if_axe.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_axe.c,v retrieving revision 1.107 diff -u -p -u -p -r1.107 if_axe.c --- dev/usb/if_axe.c 16 Sep 2011 17:20:07 -0000 1.107 +++ dev/usb/if_axe.c 20 Oct 2011 03:51:24 -0000 @@ -150,6 +150,7 @@ const struct axe_type axe_devs[] = { { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 }, { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772}, AX772 }, { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A}, AX772 }, + { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B}, AX772 | AX772B }, { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 }, { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 }, { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 }, @@ -765,6 +766,8 @@ axe_attach(struct device *parent, struct printf("%s:", sc->axe_dev.dv_xname); if (sc->axe_flags & AX178) printf(" AX88178"); + else if (sc->axe_flags & AX772B) + printf(" AX88772B"); else if (sc->axe_flags & AX772) printf(" AX88772"); else @@ -1025,11 +1028,11 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_pr memcpy(&hdr, buf, sizeof(hdr)); total_len -= sizeof(hdr); - if ((hdr.len ^ hdr.ilen) != 0xffff) { + if (((hdr.len & 0x07ff) ^ (hdr.ilen & 0x07ff)) != 0x07ff) { ifp->if_ierrors++; goto done; } - pktlen = letoh16(hdr.len); + pktlen = letoh16(hdr.len & 0x07ff); if (pktlen > total_len) { ifp->if_ierrors++; goto done; @@ -1334,7 +1337,9 @@ axe_init(void *xsc) /* Enable receiver, set RX mode */ rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE; - if (sc->axe_flags & AX178 || sc->axe_flags & AX772) { + if (sc->axe_flags & AX772B) + rxmode |= AXE_772B_RXCMD_HDR_TYPE_1; + else if (sc->axe_flags & AX178 || sc->axe_flags & AX772) { if (sc->axe_udev->speed == USB_SPEED_HIGH) { /* largest possible USB buffer size for AX88178 */ rxmode |= AXE_178_RXCMD_MFB; Index: dev/usb/if_axereg.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_axereg.h,v retrieving revision 1.20 diff -u -p -u -p -r1.20 if_axereg.h --- dev/usb/if_axereg.h 6 Dec 2010 04:41:39 -0000 1.20 +++ dev/usb/if_axereg.h 20 Oct 2011 03:51:24 -0000 @@ -149,6 +149,8 @@ #define AXE_PHY_NO_AX772_EPHY 0x10 /* Embedded 10/100 PHY of AX88772 */ +#define AXE_772B_RXCMD_HDR_TYPE_1 0x0100 + #define AXE_TIMEOUT 1000 #define AXE_172_BUFSZ 1536 #define AXE_178_MIN_BUFSZ 2048 @@ -177,6 +179,7 @@ struct axe_type { u_int16_t axe_flags; #define AX178 0x0001 /* AX88178 */ #define AX772 0x0002 /* AX88772 */ +#define AX772B 0x0004 /* AX88772B */ }; struct axe_softc; Index: dev/usb/usbdevs =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.558 diff -u -p -u -p -r1.558 usbdevs --- dev/usb/usbdevs 7 Oct 2011 06:01:49 -0000 1.558 +++ dev/usb/usbdevs 20 Oct 2011 03:51:28 -0000 @@ -908,6 +908,7 @@ product ASIX AX88172 0x1720 USB 2.0 10/ product ASIX AX88178 0x1780 AX88178 product ASIX AX88772 0x7720 AX88772 product ASIX AX88772A 0x772a AX88772a +product ASIX AX88772B 0x7e2b AX88772b /* ASUS products */ product ASUS2 USBN11 0x0b05 USB-N11 Index: dev/usb/usbdevs.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v retrieving revision 1.568 diff -u -p -u -p -r1.568 usbdevs.h --- dev/usb/usbdevs.h 7 Oct 2011 06:02:19 -0000 1.568 +++ dev/usb/usbdevs.h 20 Oct 2011 03:51:34 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdevs.h,v 1.568 2011/10/07 06:02:19 ckuethe Exp $ */ +/* $OpenBSD$ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -915,6 +915,7 @@ #define USB_PRODUCT_ASIX_AX88178 0x1780 /* AX88178 */ #define USB_PRODUCT_ASIX_AX88772 0x7720 /* AX88772 */ #define USB_PRODUCT_ASIX_AX88772A 0x772a /* AX88772a */ +#define USB_PRODUCT_ASIX_AX88772B 0x7e2b /* AX88772b */ /* ASUS products */ #define USB_PRODUCT_ASUS2_USBN11 0x0b05 /* USB-N11 */ Index: dev/usb/usbdevs_data.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v retrieving revision 1.562 diff -u -p -u -p -r1.562 usbdevs_data.h --- dev/usb/usbdevs_data.h 7 Oct 2011 06:02:19 -0000 1.562 +++ dev/usb/usbdevs_data.h 20 Oct 2011 03:51:39 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdevs_data.h,v 1.562 2011/10/07 06:02:19 ckuethe Exp $ */ +/* $OpenBSD$ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -784,6 +784,10 @@ const struct usb_known_product usb_known { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A, "AX88772a", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B, + "AX88772b", }, { USB_VENDOR_ASUS2, USB_PRODUCT_ASUS2_USBN11,