Author: sephe
Date: Thu Oct 13 09:18:56 2016
New Revision: 307211
URL: https://svnweb.freebsd.org/changeset/base/307211

Log:
  MFC 305801,305923,305924
  
  305801
      hyperv/hn: Fix some ifnet settings
  
      - ifnet.if_mtu does not require explicit setting.
      - ifnet.if_hdrlen must be set after ether_ifattach().
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7873
  
  305923
      hyperv/hn: Regroup ifnet setup code.
  
      While I'm here, add comment along the attach DEVMETHOD.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7874
  
  305924
      hyperv/hn: Put debug message under bootverbose
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7875

Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Thu Oct 13 
09:06:29 2016        (r307210)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Thu Oct 13 
09:18:56 2016        (r307211)
@@ -471,6 +471,9 @@ netvsc_attach(device_t dev)
        sc->hn_prichan = vmbus_get_channel(dev);
        HN_LOCK_INIT(sc);
 
+       /*
+        * Setup taskqueue for transmission.
+        */
        if (hn_tx_taskq == NULL) {
                sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
                    taskqueue_thread_enqueue, &sc->hn_tx_taskq);
@@ -493,11 +496,22 @@ netvsc_attach(device_t dev)
                sc->hn_tx_taskq = hn_tx_taskq;
        }
 
+       /*
+        * Allocate ifnet and setup its name earlier, so that if_printf
+        * can be used by functions, which will be called after
+        * ether_ifattach().
+        */
        ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER);
        ifp->if_softc = sc;
        if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 
        /*
+        * Initialize ifmedia earlier so that it can be unconditionally
+        * destroyed, if error happened later on.
+        */
+       ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
+
+       /*
         * Figure out the # of RX rings (ring_cnt) and the # of TX rings
         * to use (tx_ring_cnt).
         *
@@ -527,6 +541,10 @@ netvsc_attach(device_t dev)
         */
        sc->hn_cpu = atomic_fetchadd_int(&hn_cpu_index, ring_cnt) % mp_ncpus;
 
+       /*
+        * Create enough TX/RX rings, even if only limited number of
+        * channels can be allocated.
+        */
        error = hn_create_tx_data(sc, tx_ring_cnt);
        if (error)
                goto failed;
@@ -549,10 +567,54 @@ netvsc_attach(device_t dev)
        if (error)
                goto failed;
 
+       error = hn_rndis_get_linkstatus(sc, &link_status);
+       if (error)
+               goto failed;
+       if (link_status == NDIS_MEDIA_STATE_CONNECTED)
+               sc->hn_carrier = 1;
+
+       error = hn_rndis_get_eaddr(sc, eaddr);
+       if (error)
+               goto failed;
+
+#if __FreeBSD_version >= 1100099
+       if (sc->hn_rx_ring_inuse > 1) {
+               /*
+                * Reduce TCP segment aggregation limit for multiple
+                * RX rings to increase ACK timeliness.
+                */
+               hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
+       }
+#endif
+
+       hn_set_chim_size(sc, sc->hn_chim_szmax);
+       if (hn_tx_chimney_size > 0 &&
+           hn_tx_chimney_size < sc->hn_chim_szmax)
+               hn_set_chim_size(sc, hn_tx_chimney_size);
+
+       ctx = device_get_sysctl_ctx(dev);
+       child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+       SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
+           &sc->hn_nvs_ver, 0, "NVS version");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           hn_ndis_version_sysctl, "A", "NDIS version");
+
+       /*
+        * Setup the ifmedia, which has been initialized earlier.
+        */
+       ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+       ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
+       /* XXX ifmedia_set really should do this for us */
+       sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
+
+       /*
+        * Setup the ifnet for this interface.
+        */
+
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = hn_ioctl;
        ifp->if_init = hn_init;
-       ifp->if_mtu = ETHERMTU;
        if (hn_use_if_start) {
                int qdepth = hn_get_txswq_depth(&sc->hn_tx_ring[0]);
 
@@ -565,16 +627,6 @@ netvsc_attach(device_t dev)
                ifp->if_qflush = hn_xmit_qflush;
        }
 
-       ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
-       ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
-       ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
-       /* XXX ifmedia_set really should do this for us */
-       sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
-
-       /*
-        * Tell upper layers that we support full VLAN capability.
-        */
-       ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
        ifp->if_capabilities |=
            IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO |
            IFCAP_LRO;
@@ -583,54 +635,27 @@ netvsc_attach(device_t dev)
            IFCAP_LRO;
        ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO;
 
-#if __FreeBSD_version >= 1100099
-       if (sc->hn_rx_ring_inuse > 1) {
-               /*
-                * Reduce TCP segment aggregation limit for multiple
-                * RX rings to increase ACK timeliness.
-                */
-               hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
-       }
-#endif
-
-       error = hn_rndis_get_linkstatus(sc, &link_status);
-       if (error)
-               goto failed;
-       if (link_status == NDIS_MEDIA_STATE_CONNECTED)
-               sc->hn_carrier = 1;
-
        tso_maxlen = hn_tso_maxlen;
        if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET)
                tso_maxlen = IP_MAXPACKET;
-
        ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
        ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
        ifp->if_hw_tsomax = tso_maxlen -
            (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
 
-       error = hn_rndis_get_eaddr(sc, eaddr);
-       if (error)
-               goto failed;
        ether_ifattach(ifp, eaddr);
 
-       if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax,
-           ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize);
-
-       hn_set_chim_size(sc, sc->hn_chim_szmax);
-       if (hn_tx_chimney_size > 0 &&
-           hn_tx_chimney_size < sc->hn_chim_szmax)
-               hn_set_chim_size(sc, hn_tx_chimney_size);
+       if (bootverbose) {
+               if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax,
+                   ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize);
+       }
 
-       ctx = device_get_sysctl_ctx(dev);
-       child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
-       SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
-           &sc->hn_nvs_ver, 0, "NVS version");
-       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
-           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
-           hn_ndis_version_sysctl, "A", "NDIS version");
+       /* Inform the upper layer about the long frame support. */
+       ifp->if_hdrlen = sizeof(struct ether_vlan_header);
 
        return (0);
 failed:
+       /* TODO: reuse netvsc_detach() */
        hn_destroy_tx_data(sc);
        if (ifp != NULL)
                if_free(ifp);
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to