Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Support checksum offloading for mue(4) by Robert...
details: https://anonhg.NetBSD.org/src/rev/0e2828cee421
branches: trunk
changeset: 837567:0e2828cee421
user: rin <rin%NetBSD.org@localhost>
date: Tue Dec 11 08:16:57 2018 +0000
description:
Support checksum offloading for mue(4) by Robert Swindells
and adjusted by myself.
diffstat:
sys/dev/usb/if_mue.c | 72 +++++++++++++++++++++++++++++++++++++++++-------
sys/dev/usb/if_muevar.h | 10 ++++++-
2 files changed, 70 insertions(+), 12 deletions(-)
diffs (168 lines):
diff -r 2f74bbe83ba8 -r 0e2828cee421 sys/dev/usb/if_mue.c
--- a/sys/dev/usb/if_mue.c Tue Dec 11 06:34:00 2018 +0000
+++ b/sys/dev/usb/if_mue.c Tue Dec 11 08:16:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_mue.c,v 1.19 2018/12/04 01:35:15 rin Exp $ */
+/* $NetBSD: if_mue.c,v 1.20 2018/12/11 08:16:57 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.19 2018/12/04 01:35:15 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.20 2018/12/11 08:16:57 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1009,7 +1009,12 @@
IFQ_SET_READY(&ifp->if_snd);
- ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6;
+ ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6 |
+ IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
+ IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
+ IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
+ IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
+ IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx;
sc->mue_ec.ec_capabilities = ETHERCAP_VLAN_MTU;
@@ -1208,10 +1213,14 @@
usbd_status err;
struct mue_txbuf_hdr hdr;
uint32_t tx_cmd_a, tx_cmd_b;
- int len;
- bool tso;
+ int csum, len;
+ bool tso, ipe, tpe;
- tso = m->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6);
+ csum = m->m_pkthdr.csum_flags;
+ tso = csum & (M_CSUM_TSOv4 | M_CSUM_TSOv6);
+ ipe = csum & M_CSUM_IPv4;
+ tpe = csum & (M_CSUM_TCPv4 | M_CSUM_UDPv4 |
+ M_CSUM_TCPv6 | M_CSUM_UDPv6);
len = m->m_pkthdr.len;
if (__predict_false((!tso && len > MUE_MAX_TX_LEN) ||
@@ -1234,8 +1243,13 @@
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
+ } else {
+ if (ipe)
+ tx_cmd_a |= MUE_TX_CMD_A_IPE;
+ if (tpe)
+ tx_cmd_a |= MUE_TX_CMD_A_TPE;
tx_cmd_b = 0;
+ }
hdr.tx_cmd_a = htole32(tx_cmd_a);
hdr.tx_cmd_b = htole32(tx_cmd_b);
@@ -1418,7 +1432,9 @@
uint32_t rx_cmd_a, totlen;
uint16_t pktlen;
int s;
+ int csum;
char *buf = c->mue_buf;
+ bool v6;
if (__predict_false(sc->mue_dying)) {
DPRINTF(sc, "dying\n");
@@ -1457,15 +1473,17 @@
hdrp = (struct mue_rxbuf_hdr *)buf;
rx_cmd_a = le32toh(hdrp->rx_cmd_a);
- if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_RED)) {
+ if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ERRORS)) {
+ /*
+ * We cannot use MUE_RX_CMD_A_RED bit here;
+ * it is turned on in the cases of L3/L4
+ * checksum errors which we handle below.
+ */
MUE_PRINTF(sc, "rx_cmd_a: 0x%x\n", rx_cmd_a);
ifp->if_ierrors++;
goto done;
}
- /* XXX not yet */
- KASSERT((rx_cmd_a & MUE_RX_CMD_A_ICSM) == 0);
-
pktlen = (uint16_t)(rx_cmd_a & MUE_RX_CMD_A_LEN_MASK);
if (sc->mue_flags & LAN7500)
pktlen -= 2;
@@ -1488,6 +1506,36 @@
m_set_rcvif(m, ifp);
m->m_pkthdr.len = m->m_len = pktlen;
m->m_flags |= M_HASFCS;
+
+ if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_ICSM)) {
+ csum = 0;
+ } else {
+ v6 = rx_cmd_a & MUE_RX_CMD_A_IPV;
+ switch (rx_cmd_a & MUE_RX_CMD_A_PID) {
+ case MUE_RX_CMD_A_PID_TCP:
+ csum = v6 ?
+ M_CSUM_TCPv6 : M_CSUM_IPv4 | M_CSUM_TCPv4;
+ break;
+ case MUE_RX_CMD_A_PID_UDP:
+ csum = v6 ?
+ M_CSUM_UDPv6 : M_CSUM_IPv4 | M_CSUM_UDPv4;
+ break;
+ case MUE_RX_CMD_A_PID_IP:
+ csum = v6 ? 0 : M_CSUM_IPv4;
+ break;
+ default:
+ csum = 0;
+ break;
+ }
+ csum &= ifp->if_csum_flags_rx;
+ if (__predict_false((csum & M_CSUM_IPv4) &&
+ (rx_cmd_a & MUE_RX_CMD_A_ICE)))
+ csum |= M_CSUM_IPv4_BAD;
+ if (__predict_false((csum & ~M_CSUM_IPv4) &&
+ (rx_cmd_a & MUE_RX_CMD_A_TCE)))
+ csum |= M_CSUM_TCP_UDP_BAD;
+ }
+ m->m_pkthdr.csum_flags = csum;
memcpy(mtod(m, char *), buf + sizeof(*hdrp), pktlen);
/* Attention: sizeof(hdr) = 10 */
@@ -1643,6 +1691,8 @@
if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
break;
error = 0;
+ if (cmd == SIOCSIFCAP)
+ mue_sethwcsum(sc);
if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI)
mue_setmulti(sc);
break;
diff -r 2f74bbe83ba8 -r 0e2828cee421 sys/dev/usb/if_muevar.h
--- a/sys/dev/usb/if_muevar.h Tue Dec 11 06:34:00 2018 +0000
+++ b/sys/dev/usb/if_muevar.h Tue Dec 11 08:16:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_muevar.h,v 1.2 2018/08/30 09:00:08 rin Exp $ */
+/* $NetBSD: if_muevar.h,v 1.3 2018/12/11 08:16:57 rin Exp $ */
/* $OpenBSD: if_muereg.h,v 1.1 2018/08/03 01:50:15 kevlo Exp $ */
/*
@@ -45,7 +45,15 @@
uint32_t rx_cmd_a;
#define MUE_RX_CMD_A_LEN_MASK 0x00003fff
#define MUE_RX_CMD_A_ICSM 0x00004000
+#define MUE_RX_CMD_A_ERRORS __BITS(16, 21) /* non-checksum errors */
#define MUE_RX_CMD_A_RED 0x00400000
+#define MUE_RX_CMD_A_PID __BITS(28, 27)
+#define MUE_RX_CMD_A_PID_TCP __SHIFTIN(1, MUE_RX_CMD_A_PID)
+#define MUE_RX_CMD_A_PID_UDP __SHIFTIN(2, MUE_RX_CMD_A_PID)
+#define MUE_RX_CMD_A_PID_IP __SHIFTIN(3, MUE_RX_CMD_A_PID)
+#define MUE_RX_CMD_A_IPV __BIT(29)
+#define MUE_RX_CMD_A_TCE __BIT(30)
+#define MUE_RX_CMD_A_ICE __BIT(31)
uint32_t rx_cmd_b;
uint16_t rx_cmd_c;
Home |
Main Index |
Thread Index |
Old Index