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