hyperv/hn: Factor out function to do NVS initialization.

MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D7807
This commit is contained in:
Sepherosa Ziehau 2016-09-08 06:23:08 +00:00
parent f7a9af2829
commit 021deece8f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305580
3 changed files with 51 additions and 43 deletions

View File

@ -69,6 +69,13 @@ static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
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 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
/*
* 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 @@ hv_nv_destroy_send_buffer(struct hn_softc *sc)
}
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 @@ hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
return (error);
}
static int
hn_nvs_init(struct hn_softc *sc)
{
int 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 <= 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,
HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver));
}
return (0);
}
}
if_printf(sc->hn_ifp, "no NVS available\n");
return (ENXIO);
}
/*
* Net VSC connect to VSP
*/
static int
hv_nv_connect_to_vsp(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];
sc->hn_ndis_ver = HN_NDIS_VERSION_6_30;
if (sc->hn_nvs_ver <= NVSP_PROTOCOL_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,
HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver));
}
break;
}
}
if (i < 0) {
if (bootverbose)
device_printf(dev, "failed to negotiate a valid "
"protocol.\n");
return (EPROTO);
}
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);
/*

View File

@ -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
*/

View File

@ -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