Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.h =================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -68,13 +68,6 @@ MALLOC_DECLARE(M_NETVSC); -#define NVSP_INVALID_PROTOCOL_VERSION (0xFFFFFFFF) - -#define NVSP_PROTOCOL_VERSION_1 2 -#define NVSP_PROTOCOL_VERSION_2 0x30002 -#define NVSP_PROTOCOL_VERSION_4 0x40000 -#define NVSP_PROTOCOL_VERSION_5 0x50000 - /* * The following arguably belongs in a separate header file */ Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -69,6 +69,13 @@ struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); +static const uint32_t hn_nvs_version[] = { + HN_NVS_VERSION_5, + HN_NVS_VERSION_4, + HN_NVS_VERSION_2, + HN_NVS_VERSION_1 +}; + uint32_t hn_chim_alloc(struct hn_softc *sc) { @@ -166,7 +173,7 @@ /* * Limit RXBUF size for old NVS. */ - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_2) + if (sc->hn_nvs_ver <= HN_NVS_VERSION_2) rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; else rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE; @@ -424,7 +431,7 @@ } static int -hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, uint32_t nvs_ver) +hn_nvs_doinit(struct hn_softc *sc, uint32_t nvs_ver) { struct vmbus_xact *xact; struct hn_nvs_init *init; @@ -485,55 +492,55 @@ return (error); } -/* - * Net VSC connect to VSP - */ static int -hv_nv_connect_to_vsp(struct hn_softc *sc) +hn_nvs_init(struct hn_softc *sc) { - uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, - NVSP_PROTOCOL_VERSION_2, - NVSP_PROTOCOL_VERSION_4, - NVSP_PROTOCOL_VERSION_5 }; int i; - int protocol_number = nitems(protocol_list); - int ret = 0; - device_t dev = sc->hn_dev; - struct ifnet *ifp = sc->hn_ifp; - struct hn_nvs_ndis_init ndis; - /* - * Negotiate the NVSP version. Try the latest NVSP first. - */ - for (i = protocol_number - 1; i >= 0; i--) { - if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { - sc->hn_nvs_ver = protocol_list[i]; + for (i = 0; i < nitems(hn_nvs_version); ++i) { + int error; + + error = hn_nvs_doinit(sc, hn_nvs_version[i]); + if (!error) { + sc->hn_nvs_ver = hn_nvs_version[i]; + + /* Set NDIS version according to NVS version. */ sc->hn_ndis_ver = HN_NDIS_VERSION_6_30; - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) + if (sc->hn_nvs_ver <= HN_NVS_VERSION_4) sc->hn_ndis_ver = HN_NDIS_VERSION_6_1; + if (bootverbose) { if_printf(sc->hn_ifp, "NVS version 0x%x, " - "NDIS version %u.%u\n", - sc->hn_nvs_ver, + "NDIS version %u.%u\n", sc->hn_nvs_ver, HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } - break; + return (0); } } + if_printf(sc->hn_ifp, "no NVS available\n"); + return (ENXIO); +} - if (i < 0) { - if (bootverbose) - device_printf(dev, "failed to negotiate a valid " - "protocol.\n"); - return (EPROTO); - } +/* + * Net VSC connect to VSP + */ +static int +hv_nv_connect_to_vsp(struct hn_softc *sc) +{ + int ret = 0; + struct ifnet *ifp = sc->hn_ifp; + struct hn_nvs_ndis_init ndis; + + ret = hn_nvs_init(sc); + if (ret != 0) + return (ret); /* * Set the MTU if supported by this NVSP protocol version * This needs to be right after the NVSP init message per Haiyang */ - if (sc->hn_nvs_ver >= NVSP_PROTOCOL_VERSION_2) + if (sc->hn_nvs_ver >= HN_NVS_VERSION_2) ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); /* Index: head/sys/dev/hyperv/netvsc/if_hnreg.h =================================================================== --- head/sys/dev/hyperv/netvsc/if_hnreg.h +++ head/sys/dev/hyperv/netvsc/if_hnreg.h @@ -40,6 +40,14 @@ #define HN_NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) #define HN_NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) +/* + * NVS versions. + */ +#define HN_NVS_VERSION_1 0x00002 +#define HN_NVS_VERSION_2 0x30002 +#define HN_NVS_VERSION_4 0x40000 +#define HN_NVS_VERSION_5 0x50000 + #define HN_NVS_RXBUF_SIG 0xcafe #define HN_NVS_CHIM_SIG 0xface