svn commit: r211670 - head/sys/dev/xl

Pyun YongHyeon yongari at FreeBSD.org
Mon Aug 23 00:24:12 UTC 2010


Author: yongari
Date: Mon Aug 23 00:24:12 2010
New Revision: 211670
URL: http://svn.freebsd.org/changeset/base/211670

Log:
  Clean up SIOCSIFCAP handler and allow RX checksum offloading could
  be controlled by user.

Modified:
  head/sys/dev/xl/if_xl.c

Modified: head/sys/dev/xl/if_xl.c
==============================================================================
--- head/sys/dev/xl/if_xl.c	Mon Aug 23 00:15:50 2010	(r211669)
+++ head/sys/dev/xl/if_xl.c	Mon Aug 23 00:24:12 2010	(r211670)
@@ -3083,7 +3083,7 @@ xl_ioctl(struct ifnet *ifp, u_long comma
 {
 	struct xl_softc		*sc = ifp->if_softc;
 	struct ifreq		*ifr = (struct ifreq *) data;
-	int			error = 0;
+	int			error = 0, mask;
 	struct mii_data		*mii = NULL;
 	u_int8_t		rxfilt;
 
@@ -3143,40 +3143,47 @@ xl_ioctl(struct ifnet *ifp, u_long comma
 			    &mii->mii_media, command);
 		break;
 	case SIOCSIFCAP:
+		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
-		if (ifr->ifr_reqcap & IFCAP_POLLING &&
-		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(xl_poll, ifp);
-			if (error)
-				return(error);
-			XL_LOCK(sc);
-			/* Disable interrupts */
-			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
-			ifp->if_capenable |= IFCAP_POLLING;
-			XL_UNLOCK(sc);
-			return (error);
-		}
-		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
-		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
-			/* Enable interrupts. */
-			XL_LOCK(sc);
-			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
-			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
-			if (sc->xl_flags & XL_FLAG_FUNCREG)
-				bus_space_write_4(sc->xl_ftag, sc->xl_fhandle,
-				    4, 0x8000);
-			ifp->if_capenable &= ~IFCAP_POLLING;
-			XL_UNLOCK(sc);
-			return (error);
+		if ((mask & IFCAP_POLLING) != 0 &&
+		    (ifp->if_capabilities & IFCAP_POLLING) != 0) {
+			ifp->if_capenable ^= IFCAP_POLLING;
+			if ((ifp->if_capenable & IFCAP_POLLING) != 0) {
+				error = ether_poll_register(xl_poll, ifp);
+				if (error)
+					break;
+				XL_LOCK(sc);
+				/* Disable interrupts */
+				CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
+				ifp->if_capenable |= IFCAP_POLLING;
+				XL_UNLOCK(sc);
+			} else {
+				error = ether_poll_deregister(ifp);
+				/* Enable interrupts. */
+				XL_LOCK(sc);
+				CSR_WRITE_2(sc, XL_COMMAND,
+				    XL_CMD_INTR_ACK | 0xFF);
+				CSR_WRITE_2(sc, XL_COMMAND,
+				    XL_CMD_INTR_ENB | XL_INTRS);
+				if (sc->xl_flags & XL_FLAG_FUNCREG)
+					bus_space_write_4(sc->xl_ftag,
+					    sc->xl_fhandle, 4, 0x8000);
+				XL_UNLOCK(sc);
+			}
 		}
 #endif /* DEVICE_POLLING */
 		XL_LOCK(sc);
-		ifp->if_capenable = ifr->ifr_reqcap;
-		if (ifp->if_capenable & IFCAP_TXCSUM)
-			ifp->if_hwassist = XL905B_CSUM_FEATURES;
-		else
-			ifp->if_hwassist = 0;
+		if ((mask & IFCAP_TXCSUM) != 0 &&
+		    (ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
+			ifp->if_capenable ^= IFCAP_TXCSUM;
+			if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
+				ifp->if_hwassist |= XL905B_CSUM_FEATURES;
+			else
+				ifp->if_hwassist &= ~XL905B_CSUM_FEATURES;
+		}
+		if ((mask & IFCAP_RXCSUM) != 0 &&
+		    (ifp->if_capabilities & IFCAP_RXCSUM) != 0)
+			ifp->if_capenable ^= IFCAP_RXCSUM;
 		XL_UNLOCK(sc);
 		break;
 	default:


More information about the svn-src-head mailing list