Bug 205264

Summary: XOR logic error in ixgb(4)
Product: Base System Reporter: Michael McConville <mmcco>
Component: kernAssignee: freebsd-net (Nobody) <net>
Status: Closed Overcome By Events    
Severity: Affects Many People CC: erj, kbowling, ngie, ports, sbruno, truckman
Priority: --- Keywords: IntelNetworking
Version: CURRENT   
Hardware: amd64   
OS: Any   

Description Michael McConville 2015-12-12 05:08:37 UTC
The driver code attempts to XOR using an if-else condition, but does so imperfectly. See sys/dev/ixgb/if_ixgb.c:601 and the discussion here:

https://marc.info/?t=144986401800001&r=1&w=2
Comment 1 Don Lewis freebsd_committer freebsd_triage 2015-12-12 21:35:24 UTC
IFCAP_HWCSUM is defined as (IFCAP_RXCSUM | IFCAP_TXCSUM), so this code:

	case SIOCSIFCAP:
		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
		[snip]
		if (mask & IFCAP_HWCSUM) {
			if (IFCAP_HWCSUM & ifp->if_capenable)
				ifp->if_capenable &= ~IFCAP_HWCSUM;
			else
				ifp->if_capenable |= IFCAP_HWCSUM;
			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
				ixgb_init(adapter);
		}

will set both bits even if the request only specifies one bit, and it
will clear both bits even if the request only wants to clear one bit.

Replacing the inner if/else block with this should fix the problem:

			ifp->if_capenable ^= (mask & IFCAP_HWCSUM);

or alternatively:

			ifp->if_capenable = (ifr->ifr_reqcap & IFCAP_HWCSUM) |
				(ifp->if_capenable & ~IFCAP_HWCSUM);
Comment 2 Kevin Bowling freebsd_committer freebsd_triage 2018-05-03 08:10:32 UTC
ixgb(4) support has been removed from HEAD for reasons as linked in r333173.