Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -368,6 +368,14 @@ static void hn_xmit_taskfunc(void *, int); static void hn_xmit_txeof_taskfunc(void *, int); +static const uint8_t hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa +}; + #if __FreeBSD_version >= 1100099 static void hn_set_lro_lenlim(struct hn_softc *sc, int lenlim) @@ -3146,7 +3154,8 @@ static int hn_synth_attach(struct hn_softc *sc, int mtu) { - int error, nsubch; + struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; + int error, nsubch, nchan, i; /* * Attach the primary channel _before_ attaching NVS and RNDIS. @@ -3180,7 +3189,9 @@ error = hn_synth_alloc_subchans(sc, &nsubch); if (error) return (error); - if (nsubch == 0) { + + nchan = nsubch + 1; + if (nchan == 1) { /* Only the primary channel can be used; done */ goto back; } @@ -3189,20 +3200,29 @@ * Configure RSS key and indirect table _after_ all sub-channels * are allocated. */ - error = hn_rndis_conf_rss(sc, nsubch + 1); + + /* Setup default RSS key. */ + memcpy(rss->rss_key, hn_rss_key_default, sizeof(rss->rss_key)); + + /* Setup default RSS indirect table. */ + /* TODO: Take ndis_rss_caps.ndis_nind into account. */ + for (i = 0; i < NDIS_HASH_INDCNT; ++i) + rss->rss_ind[i] = i % nchan; + + error = hn_rndis_conf_rss(sc); if (error) { /* * Failed to configure RSS key or indirect table; only * the primary channel can be used. */ - nsubch = 0; + nchan = 1; } back: /* * Set the # of TX/RX rings that could be used according to * the # of channels that NVS offered. */ - hn_set_ring_inuse(sc, nsubch + 1); + hn_set_ring_inuse(sc, nchan); /* * Attach the sub-channels, if any. Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c =================================================================== --- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -510,14 +510,6 @@ return (0); } -static uint8_t netvsc_hash_key[NDIS_HASH_KEYSIZE_TOEPLITZ] = { - 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, - 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, - 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, - 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa -}; - static const void * hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, struct hn_send_ctx *sndc, size_t *comp_len) @@ -845,11 +837,11 @@ } int -hn_rndis_conf_rss(struct hn_softc *sc, int nchan) +hn_rndis_conf_rss(struct hn_softc *sc) { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; struct ndis_rss_params *prm = &rss->rss_params; - int i, error; + int error; /* * Only NDIS 6.30+ is supported. @@ -857,7 +849,12 @@ KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); - memset(rss, 0, sizeof(*rss)); + /* + * NOTE: + * DO NOT whack rss_key and rss_ind, which are setup by the caller. + */ + memset(prm, 0, sizeof(*prm)); + prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; prm->ndis_hdr.ndis_size = sizeof(*rss); @@ -872,14 +869,6 @@ prm->ndis_keyoffset = __offsetof(struct ndis_rssprm_toeplitz, rss_key[0]); - /* Setup RSS key */ - memcpy(rss->rss_key, netvsc_hash_key, sizeof(rss->rss_key)); - - /* Setup RSS indirect table */ - /* TODO: Take ndis_rss_caps.ndis_nind into account */ - for (i = 0; i < NDIS_HASH_INDCNT; ++i) - rss->rss_ind[i] = i % nchan; - error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS, rss, sizeof(*rss)); if (error) { Index: head/sys/dev/hyperv/netvsc/if_hnvar.h =================================================================== --- head/sys/dev/hyperv/netvsc/if_hnvar.h +++ head/sys/dev/hyperv/netvsc/if_hnvar.h @@ -118,7 +118,7 @@ void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); int hn_rndis_attach(struct hn_softc *sc); -int hn_rndis_conf_rss(struct hn_softc *sc, int nchan); +int hn_rndis_conf_rss(struct hn_softc *sc); void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, size_t pktsize, size_t pi_dlen, uint32_t pi_type); int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt);