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:
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to