Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Aug 2016 10:46:30 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r304392 - stable/10/sys/dev/ntb/if_ntb
Message-ID:  <201608181046.u7IAkUhi026565@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Aug 18 10:46:29 2016
New Revision: 304392
URL: https://svnweb.freebsd.org/changeset/base/304392

Log:
  MFC r302499: Improve checksum "offload" support.
  
  For compatibility reasons make driver not report any checksum offload by
  default, since there is indeed none.  But if administrator knows that
  interface is used only for local traffic, he can enable fake checksum
  offload manually on both sides to save some CPU cycles, since the data
  are already protected by CRC32 of PCIe link.
  
  Sponsored by:   iXsystems, Inc.

Modified:
  stable/10/sys/dev/ntb/if_ntb/if_ntb.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/ntb/if_ntb/if_ntb.c
==============================================================================
--- stable/10/sys/dev/ntb/if_ntb/if_ntb.c	Thu Aug 18 10:45:53 2016	(r304391)
+++ stable/10/sys/dev/ntb/if_ntb/if_ntb.c	Thu Aug 18 10:46:29 2016	(r304392)
@@ -67,6 +67,13 @@ __FBSDID("$FreeBSD$");
 #define KTR_NTB KTR_SPARE3
 #define NTB_MEDIATYPE		 (IFM_ETHER | IFM_AUTO | IFM_FDX)
 
+#define	NTB_CSUM_FEATURES	(CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP)
+#define	NTB_CSUM_FEATURES6	(CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_SCTP_IPV6)
+#define	NTB_CSUM_SET		(CSUM_DATA_VALID | CSUM_DATA_VALID_IPV6 | \
+				    CSUM_PSEUDO_HDR | \
+				    CSUM_IP_CHECKED | CSUM_IP_VALID | \
+				    CSUM_SCTP_VALID)
+
 static SYSCTL_NODE(_hw, OID_AUTO, if_ntb, CTLFLAG_RW, 0, "if_ntb");
 
 static unsigned g_if_ntb_num_queues = 1;
@@ -171,7 +178,7 @@ ntb_net_attach(device_t dev)
 	ether_ifattach(ifp, sc->eaddr);
 	if_setcapabilities(ifp, IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 |
 	    IFCAP_JUMBO_MTU | IFCAP_LINKSTATE);
-	if_setcapenable(ifp, if_getcapabilities(ifp));
+	if_setcapenable(ifp, IFCAP_JUMBO_MTU | IFCAP_LINKSTATE);
 	if_setmtu(ifp, sc->mtu - ETHER_HDR_LEN);
 
 	ifmedia_init(&sc->media, IFM_IMASK, ntb_ifmedia_upd,
@@ -245,6 +252,31 @@ ntb_ioctl(if_t ifp, u_long command, cadd
 		error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
 		break;
 
+	case SIOCSIFCAP:
+		if (ifr->ifr_reqcap & IFCAP_RXCSUM)
+			if_setcapenablebit(ifp, IFCAP_RXCSUM, 0);
+		else
+			if_setcapenablebit(ifp, 0, IFCAP_RXCSUM);
+		if (ifr->ifr_reqcap & IFCAP_TXCSUM) {
+			if_setcapenablebit(ifp, IFCAP_TXCSUM, 0);
+			if_sethwassistbits(ifp, NTB_CSUM_FEATURES, 0);
+		} else {
+			if_setcapenablebit(ifp, 0, IFCAP_TXCSUM);
+			if_sethwassistbits(ifp, 0, NTB_CSUM_FEATURES);
+		}
+		if (ifr->ifr_reqcap & IFCAP_RXCSUM_IPV6)
+			if_setcapenablebit(ifp, IFCAP_RXCSUM_IPV6, 0);
+		else
+			if_setcapenablebit(ifp, 0, IFCAP_RXCSUM_IPV6);
+		if (ifr->ifr_reqcap & IFCAP_TXCSUM_IPV6) {
+			if_setcapenablebit(ifp, IFCAP_TXCSUM_IPV6, 0);
+			if_sethwassistbits(ifp, NTB_CSUM_FEATURES6, 0);
+		} else {
+			if_setcapenablebit(ifp, 0, IFCAP_TXCSUM_IPV6);
+			if_sethwassistbits(ifp, 0, NTB_CSUM_FEATURES6);
+		}
+		break;
+
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
@@ -398,6 +430,7 @@ ntb_net_rx_handler(struct ntb_transport_
 	struct ntb_net_ctx *sc = q->sc;
 	struct mbuf *m = data;
 	if_t ifp = q->ifp;
+	uint16_t proto;
 
 	CTR1(KTR_NTB, "RX: rx handler (%d)", len);
 	if (len < 0) {
@@ -410,9 +443,22 @@ ntb_net_rx_handler(struct ntb_transport_
 		m->m_pkthdr.flowid = q - sc->queues;
 		M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
 	}
-	if ((if_getcapenable(ifp) & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) ==
-	    (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) {
-		m->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID;
+	if (if_getcapenable(ifp) & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) {
+		m_copydata(m, 12, 2, (void *)&proto);
+		switch (ntohs(proto)) {
+		case ETHERTYPE_IP:
+			if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
+				m->m_pkthdr.csum_data = 0xffff;
+				m->m_pkthdr.csum_flags = NTB_CSUM_SET;
+			}
+			break;
+		case ETHERTYPE_IPV6:
+			if (if_getcapenable(ifp) & IFCAP_RXCSUM_IPV6) {
+				m->m_pkthdr.csum_data = 0xffff;
+				m->m_pkthdr.csum_flags = NTB_CSUM_SET;
+			}
+			break;
+		}
 	}
 	if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
 	if_input(ifp, m);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608181046.u7IAkUhi026565>