Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Mar 2015 15:20:10 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r280694 - projects/ifnet/sys/net
Message-ID:  <201503261520.t2QFKAnq024770@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Mar 26 15:20:09 2015
New Revision: 280694
URL: https://svnweb.freebsd.org/changeset/base/280694

Log:
  In SIOCSIFCAP case provide the logic that will enforce dependency
  of TSO on hardware checksum offloading.
  
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  projects/ifnet/sys/net/if.c

Modified: projects/ifnet/sys/net/if.c
==============================================================================
--- projects/ifnet/sys/net/if.c	Thu Mar 26 15:19:03 2015	(r280693)
+++ projects/ifnet/sys/net/if.c	Thu Mar 26 15:20:09 2015	(r280694)
@@ -2447,13 +2447,38 @@ if_drvioctl(struct ifnet *ifp, u_long cm
 		error = priv_check(td, PRIV_NET_SETIFCAP);
 		if (error)
 			return (error);
+		/*
+		 * All(?) NICs that do TSO require to perform VLAN tagging
+		 * and checksum offloading in hardware, when doing TSO.
+		 * Thus, turning TSO on implicitly turns on these features,
+		 * and turning these features off implicitly turns off TSO.
+		 */
 		if ((ifr->ifr_reqcap & IFCAP_VLAN_HWTSO) != 0)
 			ifr->ifr_reqcap |= IFCAP_VLAN_HWTAGGING;
+		if ((ifr->ifr_reqcap & IFCAP_VLAN_HWTAGGING) == 0)
+			ifr->ifr_reqcap &= ~IFCAP_VLAN_HWTSO;
+		if ((ifr->ifr_reqcap & IFCAP_TSO4) != 0)
+			ifr->ifr_reqcap |= IFCAP_TXCSUM;
+		if ((ifr->ifr_reqcap & IFCAP_TXCSUM) == 0)
+			ifr->ifr_reqcap &= ~IFCAP_TSO4;
+		if ((ifr->ifr_reqcap & IFCAP_TSO6) != 0)
+			ifr->ifr_reqcap |= IFCAP_TXCSUM_IPV6;
+		if ((ifr->ifr_reqcap & IFCAP_TXCSUM_IPV6) == 0)
+			ifr->ifr_reqcap &= ~IFCAP_TSO6;
+		/*
+		 * Now check that requested capabilities match
+		 * what interface can actually do, and whether
+		 * there is any change in the capenable.
+		 */
 		if (ifr->ifr_reqcap & ~ifp->if_capabilities)
 			return (EINVAL);
 		if (ifr->ifr_reqcap == ifp->if_capenable)
 			return (0);
 		ifr->ifr_curcap = ifp->if_capenable;
+		/*
+		 * See if driver accepts ifr_reqcap.  It may also
+		 * adjust them.  Driver also fills in ifr_hwassist.
+		 */
 		error = if_ioctl(ifp, cmd, data, td);
 		if (error != 0)
 			break;



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