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
This commit is contained in:
parent
34ccb11831
commit
ae75f7ee26
@ -467,9 +467,15 @@ hn_nvs_conf_ndis(struct hn_softc *sc, int mtu)
|
||||
|
||||
/* 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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -325,6 +325,7 @@ static int hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
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");
|
||||
@ -2094,6 +2098,30 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -3223,6 +3251,11 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
||||
{
|
||||
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.
|
||||
@ -3245,6 +3278,17 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
||||
if (error)
|
||||
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.
|
||||
*
|
||||
|
@ -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 *sc)
|
||||
}
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user