Module Name:    src
Committed By:   rin
Date:           Sun Sep 16 01:23:09 UTC 2018

Modified Files:
        src/sys/dev/usb: if_mue.c if_muereg.h

Log Message:
Rewrite mue_encap(); drop too long packets rather than panic.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/usb/if_mue.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/usb/if_muereg.h

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_mue.c
diff -u src/sys/dev/usb/if_mue.c:1.11 src/sys/dev/usb/if_mue.c:1.12
--- src/sys/dev/usb/if_mue.c:1.11	Sun Sep 16 01:18:30 2018
+++ src/sys/dev/usb/if_mue.c	Sun Sep 16 01:23:09 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_mue.c,v 1.11 2018/09/16 01:18:30 rin Exp $	*/
+/*	$NetBSD: if_mue.c,v 1.12 2018/09/16 01:23:09 rin Exp $	*/
 /*	$OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $	*/
 
 /*
@@ -20,7 +20,7 @@
 /* Driver for Microchip LAN7500/LAN7800 chipsets. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.11 2018/09/16 01:18:30 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.12 2018/09/16 01:23:09 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1207,42 +1207,49 @@ mue_encap(struct mue_softc *sc, struct m
 	struct mue_chain *c;
 	usbd_status err;
 	struct mue_txbuf_hdr hdr;
+	uint32_t tx_cmd_a, tx_cmd_b;
 	int len;
+	bool tso;
+
+	tso = m->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6);
+
+	len = m->m_pkthdr.len;
+	if (__predict_false((!tso && len > MUE_MAX_TX_LEN) ||
+			    ( tso && len > MUE_MAX_TSO_LEN))) {
+		MUE_PRINTF(sc, "packet length %d\n too long", len);
+		return EINVAL;
+	}
 
 	c = &sc->mue_cdata.mue_tx_chain[idx];
 
-	hdr.tx_cmd_a = htole32((m->m_pkthdr.len & MUE_TX_CMD_A_LEN_MASK) |
-	    MUE_TX_CMD_A_FCS);
+	KASSERT((len & ~MUE_TX_CMD_A_LEN_MASK) == 0);
+	tx_cmd_a = len | MUE_TX_CMD_A_FCS;
 
-	if (m->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6)) {
-		hdr.tx_cmd_a |= htole32(MUE_TX_CMD_A_LSO);
+	if (tso) {
+		tx_cmd_a |= MUE_TX_CMD_A_LSO;
 		if (__predict_true(m->m_pkthdr.segsz > MUE_TX_MSS_MIN))
-			hdr.tx_cmd_b = htole32(m->m_pkthdr.segsz <<
-			    MUE_TX_CMD_B_MSS_SHIFT);
+			tx_cmd_b = m->m_pkthdr.segsz;
 		else
-			hdr.tx_cmd_b = htole32(MUE_TX_MSS_MIN <<
-			    MUE_TX_CMD_B_MSS_SHIFT);
-		hdr.tx_cmd_b &= htole32(MUE_TX_CMD_B_MSS_MASK);
+			tx_cmd_b = MUE_TX_MSS_MIN;
+		tx_cmd_b <<= MUE_TX_CMD_B_MSS_SHIFT;
+		KASSERT((tx_cmd_b & ~MUE_TX_CMD_B_MSS_MASK) == 0);
 		mue_tx_offload(sc, m);
 	} else
-		hdr.tx_cmd_b = 0;
+		tx_cmd_b = 0;
 
-	memcpy(c->mue_buf, &hdr, sizeof(hdr)); 
-	len = sizeof(hdr);
-
-	KASSERTMSG((unsigned)(len + m->m_pkthdr.len) <= sc->mue_txbufsz,
-	    "%d <= %u", len + m->m_pkthdr.len, sc->mue_txbufsz);
+	hdr.tx_cmd_a = htole32(tx_cmd_a);
+	hdr.tx_cmd_b = htole32(tx_cmd_b);
 
-	m_copydata(m, 0, m->m_pkthdr.len, c->mue_buf + len);
-	len += m->m_pkthdr.len;
+	memcpy(c->mue_buf, &hdr, sizeof(hdr)); 
+	m_copydata(m, 0, len, c->mue_buf + sizeof(hdr));
 
-	usbd_setup_xfer(c->mue_xfer, c, c->mue_buf, len,
+	usbd_setup_xfer(c->mue_xfer, c, c->mue_buf, len + sizeof(hdr),
 	    USBD_FORCE_SHORT_XFER, 10000, mue_txeof);
 
 	/* Transmit */
 	err = usbd_transfer(c->mue_xfer);
 	if (__predict_false(err != USBD_IN_PROGRESS)) {
-		DPRINTF(sc, "%s\n", usbd_errstr(err));
+		MUE_PRINTF(sc, "%s\n", usbd_errstr(err));
 		mue_stop(ifp, 0);
 		return EIO;
 	}

Index: src/sys/dev/usb/if_muereg.h
diff -u src/sys/dev/usb/if_muereg.h:1.2 src/sys/dev/usb/if_muereg.h:1.3
--- src/sys/dev/usb/if_muereg.h:1.2	Thu Aug 30 09:00:08 2018
+++ src/sys/dev/usb/if_muereg.h	Sun Sep 16 01:23:09 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_muereg.h,v 1.2 2018/08/30 09:00:08 rin Exp $	*/
+/*	$NetBSD: if_muereg.h,v 1.3 2018/09/16 01:23:09 rin Exp $	*/
 /*	$OpenBSD: if_muereg.h,v 1.1 2018/08/03 01:50:15 kevlo Exp $	*/
 
 /*
@@ -122,8 +122,11 @@
 #define MUE_7800_RX_BUFSIZE		(12 * 1024)
 #define MUE_7800_MAX_RX_FIFO_SIZE	MUE_7800_RX_BUFSIZE
 #define MUE_7800_MAX_TX_FIFO_SIZE	MUE_7800_RX_BUFSIZE
-#define MUE_TX_BUFSIZE			(sizeof(struct mue_txbuf_hdr) + \
-	ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + IP_MAXPACKET)
+#define MUE_MAX_TX_LEN			(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN)
+#define MUE_MAX_TSO_LEN			\
+	(ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + IP_MAXPACKET)
+#define MUE_TX_BUFSIZE			\
+	(sizeof(struct mue_txbuf_hdr) + MUE_MAX_TSO_LEN)
 
 /* interrupt endpoint control register */
 #define MUE_INT_EP_CTL_PHY_INT		0x20000

Reply via email to