Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: sys/dev/usb/if_axen.c



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



Home | Main Index | Thread Index | Old Index