Date: Mon, 19 Sep 2016 07:17:43 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305964 - head/sys/dev/hyperv/netvsc Message-ID: <201609190717.u8J7HhqC031417@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Mon Sep 19 07:17:43 2016 New Revision: 305964 URL: https://svnweb.freebsd.org/changeset/base/305964 Log: hyperv/hn: Save capabilities for later use. And don't allow capability changes during reinitialization, which breaks too much static configuration. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7922 Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c head/sys/dev/hyperv/netvsc/hv_net_vsc.h head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Sep 19 07:07:55 2016 (r305963) +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Sep 19 07:17:43 2016 (r305964) @@ -467,9 +467,15 @@ hn_nvs_conf_ndis(struct hn_softc *sc, in /* NOTE: No response. */ error = hn_nvs_req_send(sc, &conf, sizeof(conf)); - if (error) + if (error) { if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); - return (error); + return (error); + } + + if (bootverbose) + if_printf(sc->hn_ifp, "nvs ndis conf done\n"); + sc->hn_caps |= HN_CAP_MTU | HN_CAP_VLAN; + return (0); } static int Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.h Mon Sep 19 07:07:55 2016 (r305963) +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h Mon Sep 19 07:17:43 2016 (r305964) @@ -228,7 +228,8 @@ struct hn_softc { struct vmbus_xact_ctx *hn_xact; uint32_t hn_nvs_ver; - uint32_t hn_flags; + uint32_t hn_caps; /* HN_CAP_ */ + uint32_t hn_flags; /* HN_FLAG_ */ void *hn_rxbuf; uint32_t hn_rxbuf_gpadl; struct hyperv_dma hn_rxbuf_dma; @@ -245,6 +246,16 @@ struct hn_softc { #define HN_FLAG_RXBUF_CONNECTED 0x0001 #define HN_FLAG_CHIM_CONNECTED 0x0002 +#define HN_CAP_VLAN 0x0001 +#define HN_CAP_MTU 0x0002 +#define HN_CAP_IPCS 0x0004 +#define HN_CAP_TCP4CS 0x0008 +#define HN_CAP_TCP6CS 0x0010 +#define HN_CAP_UDP4CS 0x0020 +#define HN_CAP_UDP6CS 0x0040 +#define HN_CAP_TSO4 0x0080 +#define HN_CAP_TSO6 0x0100 + /* * Externs */ Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Sep 19 07:07:55 2016 (r305963) +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Sep 19 07:17:43 2016 (r305964) @@ -325,6 +325,7 @@ static int hn_rx_stat_ulong_sysctl(SYSCT static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS); static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); @@ -641,6 +642,9 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_ndis_version_sysctl, "A", "NDIS version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "caps", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_caps_sysctl, "A", "capabilities"); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_rss_key_sysctl, "IU", "RSS key"); @@ -2095,6 +2099,30 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_AR } static int +hn_caps_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char caps_str[128]; + uint32_t caps; + + HN_LOCK(sc); + caps = sc->hn_caps; + HN_UNLOCK(sc); + snprintf(caps_str, sizeof(caps_str), "%b", caps, + "\020" + "\001VLAN" + "\002MTU" + "\003IPCS" + "\004TCP4CS" + "\005TCP6CS" + "\006UDP4CS" + "\007UDP6CS" + "\010TSO4" + "\011TSO6"); + return sysctl_handle_string(oidp, caps_str, sizeof(caps_str), req); +} + +static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) { struct hn_softc *sc = arg1; @@ -3223,6 +3251,11 @@ hn_synth_attach(struct hn_softc *sc, int { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; int error, nsubch, nchan, i; + uint32_t old_caps; + + /* Save capabilities for later verification. */ + old_caps = sc->hn_caps; + sc->hn_caps = 0; /* * Attach the primary channel _before_ attaching NVS and RNDIS. @@ -3246,6 +3279,17 @@ hn_synth_attach(struct hn_softc *sc, int return (error); /* + * Make sure capabilities are not changed. + */ + if (device_is_attached(sc->hn_dev) && old_caps != sc->hn_caps) { + if_printf(sc->hn_ifp, "caps mismatch old 0x%08x, new 0x%08x\n", + old_caps, sc->hn_caps); + /* Restore old capabilities and abort. */ + sc->hn_caps = old_caps; + return ENXIO; + } + + /* * Allocate sub-channels for multi-TX/RX rings. * * NOTE: Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Sep 19 07:07:55 2016 (r305963) +++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Sep 19 07:17:43 2016 (r305964) @@ -800,6 +800,7 @@ static int hn_rndis_conf_offload(struct hn_softc *sc) { struct ndis_offload_params params; + uint32_t caps; size_t paramsz; int error; @@ -816,24 +817,29 @@ hn_rndis_conf_offload(struct hn_softc *s } params.ndis_hdr.ndis_size = paramsz; + caps = HN_CAP_IPCS | HN_CAP_TCP4CS | HN_CAP_TCP6CS; params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { + caps |= HN_CAP_UDP4CS | HN_CAP_UDP6CS; params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; } + caps |= HN_CAP_TSO4; params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; /* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); if (error) { if_printf(sc->hn_ifp, "offload config failed: %d\n", error); - } else { - if (bootverbose) - if_printf(sc->hn_ifp, "offload config done\n"); + return (error); } - return (error); + + if (bootverbose) + if_printf(sc->hn_ifp, "offload config done\n"); + sc->hn_caps |= caps; + return (0); } int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609190717.u8J7HhqC031417>