Author: royger
Date: Wed Aug 10 08:05:48 2016
New Revision: 303902
URL: https://svnweb.freebsd.org/changeset/base/303902

Log:
  MFC r303488 and r303771:
  
  xen-netfront: fix trying to send packets with disconnected netfront
  xen-netfront: improve the logic when handling nic features from ioctl
  
  Approved by:  re (kib)

Modified:
  stable/11/sys/dev/xen/netfront/netfront.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/xen/netfront/netfront.c
==============================================================================
--- stable/11/sys/dev/xen/netfront/netfront.c   Wed Aug 10 03:11:07 2016        
(r303901)
+++ stable/11/sys/dev/xen/netfront/netfront.c   Wed Aug 10 08:05:48 2016        
(r303902)
@@ -1760,7 +1760,7 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, 
 #ifdef INET
        struct ifaddr *ifa = (struct ifaddr *)data;
 #endif
-       int mask, error = 0;
+       int mask, error = 0, reinit;
 
        dev = sc->xbdev;
 
@@ -1809,41 +1809,36 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, 
                break;
        case SIOCSIFCAP:
                mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+               reinit = 0;
+
                if (mask & IFCAP_TXCSUM) {
-                       if (IFCAP_TXCSUM & ifp->if_capenable) {
-                               ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4);
-                               ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP
-                                   | CSUM_IP | CSUM_TSO);
-                       } else {
-                               ifp->if_capenable |= IFCAP_TXCSUM;
-                               ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP
-                                   | CSUM_IP);
-                       }
-               }
-               if (mask & IFCAP_RXCSUM) {
-                       ifp->if_capenable ^= IFCAP_RXCSUM;
+                       ifp->if_capenable ^= IFCAP_TXCSUM;
+                       ifp->if_hwassist ^= XN_CSUM_FEATURES;
                }
                if (mask & IFCAP_TSO4) {
-                       if (IFCAP_TSO4 & ifp->if_capenable) {
-                               ifp->if_capenable &= ~IFCAP_TSO4;
-                               ifp->if_hwassist &= ~CSUM_TSO;
-                       } else if (IFCAP_TXCSUM & ifp->if_capenable) {
-                               ifp->if_capenable |= IFCAP_TSO4;
-                               ifp->if_hwassist |= CSUM_TSO;
-                       } else {
-                               IPRINTK("Xen requires tx checksum offload"
-                                   " be enabled to use TSO\n");
-                               error = EINVAL;
-                       }
+                       ifp->if_capenable ^= IFCAP_TSO4;
+                       ifp->if_hwassist ^= CSUM_TSO;
                }
-               if (mask & IFCAP_LRO) {
-                       ifp->if_capenable ^= IFCAP_LRO;
 
+               if (mask & (IFCAP_RXCSUM | IFCAP_LRO)) {
+                       /* These Rx features require us to renegotiate. */
+                       reinit = 1;
+
+                       if (mask & IFCAP_RXCSUM)
+                               ifp->if_capenable ^= IFCAP_RXCSUM;
+                       if (mask & IFCAP_LRO)
+                               ifp->if_capenable ^= IFCAP_LRO;
                }
+
+               if (reinit == 0)
+                       break;
+
                /*
                 * We must reset the interface so the backend picks up the
                 * new features.
                 */
+               device_printf(sc->xbdev,
+                   "performing interface reset due to feature change\n");
                XN_LOCK(sc);
                netfront_carrier_off(sc);
                sc->xn_reset = true;
@@ -1865,6 +1860,13 @@ xn_ioctl(struct ifnet *ifp, u_long cmd, 
                xs_rm(XST_NIL, xenbus_get_node(dev), "feature-gso-tcpv4");
                xs_rm(XST_NIL, xenbus_get_node(dev), "feature-no-csum-offload");
                xenbus_set_state(dev, XenbusStateClosing);
+
+               /*
+                * Wait for the frontend to reconnect before returning
+                * from the ioctl. 30s should be more than enough for any
+                * sane backend to reconnect.
+                */
+               error = tsleep(sc, 0, "xn_rst", 30*hz);
                break;
        case SIOCADDMULTI:
        case SIOCDELMULTI:
@@ -1971,6 +1973,7 @@ xn_connect(struct netfront_info *np)
         * packets.
         */
        netfront_carrier_on(np);
+       wakeup(np);
 
        return (0);
 }
@@ -2085,7 +2088,7 @@ xn_configure_features(struct netfront_in
 #endif
        if ((ifp->if_capabilities & cap_enabled & IFCAP_TXCSUM) != 0) {
                ifp->if_capenable |= IFCAP_TXCSUM;
-               ifp->if_hwassist |= CSUM_TCP|CSUM_UDP;
+               ifp->if_hwassist |= XN_CSUM_FEATURES;
        }
        if ((ifp->if_capabilities & cap_enabled & IFCAP_RXCSUM) != 0)
                ifp->if_capenable |= IFCAP_RXCSUM;
@@ -2157,6 +2160,9 @@ xn_txq_mq_start(struct ifnet *ifp, struc
        np = ifp->if_softc;
        npairs = np->num_queues;
 
+       if (!netfront_carrier_ok(np))
+               return (ENOBUFS);
+
        KASSERT(npairs != 0, ("called with 0 available queues"));
 
        /* check if flowid is set */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to