Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/vmware/vmxnet3/if_vmx.c
Show All 17 Lines | |||||
* $OpenBSD: src/sys/dev/pci/if_vmx.c,v 1.11 2013/06/22 00:28:10 uebayasi Exp $ | * $OpenBSD: src/sys/dev/pci/if_vmx.c,v 1.11 2013/06/22 00:28:10 uebayasi Exp $ | ||||
*/ | */ | ||||
/* Driver for VMware vmxnet3 virtual ethernet devices. */ | /* Driver for VMware vmxnet3 virtual ethernet devices. */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_rss.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/sockio.h> | #include <sys/sockio.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_arp.h> | #include <net/if_arp.h> | ||||
#include <net/if_dl.h> | #include <net/if_dl.h> | ||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
#include <net/if_media.h> | #include <net/if_media.h> | ||||
#include <net/if_vlan_var.h> | #include <net/if_vlan_var.h> | ||||
#include <net/iflib.h> | #include <net/iflib.h> | ||||
#ifdef RSS | |||||
#include <net/rss_config.h> | |||||
#endif | |||||
#include <netinet/in_systm.h> | #include <netinet/in_systm.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/ip.h> | #include <netinet/ip.h> | ||||
#include <netinet/ip6.h> | #include <netinet/ip6.h> | ||||
#include <netinet6/ip6_var.h> | #include <netinet6/ip6_var.h> | ||||
#include <netinet/udp.h> | #include <netinet/udp.h> | ||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
▲ Show 20 Lines • Show All 1,078 Lines • ▼ Show 20 Lines | static const uint8_t rss_key[UPT1_RSS_MAX_KEY_SIZE] = { | ||||
0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70, | 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70, | ||||
0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3, | 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3, | ||||
0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9, | 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9, | ||||
}; | }; | ||||
struct vmxnet3_driver_shared *ds; | struct vmxnet3_driver_shared *ds; | ||||
if_softc_ctx_t scctx; | if_softc_ctx_t scctx; | ||||
struct vmxnet3_rss_shared *rss; | struct vmxnet3_rss_shared *rss; | ||||
#ifdef RSS | |||||
uint8_t rss_algo; | |||||
#endif | |||||
int i; | int i; | ||||
ds = sc->vmx_ds; | ds = sc->vmx_ds; | ||||
scctx = sc->vmx_scctx; | scctx = sc->vmx_scctx; | ||||
rss = sc->vmx_rss; | rss = sc->vmx_rss; | ||||
rss->hash_type = | rss->hash_type = | ||||
UPT1_RSS_HASH_TYPE_IPV4 | UPT1_RSS_HASH_TYPE_TCP_IPV4 | | UPT1_RSS_HASH_TYPE_IPV4 | UPT1_RSS_HASH_TYPE_TCP_IPV4 | | ||||
UPT1_RSS_HASH_TYPE_IPV6 | UPT1_RSS_HASH_TYPE_TCP_IPV6; | UPT1_RSS_HASH_TYPE_IPV6 | UPT1_RSS_HASH_TYPE_TCP_IPV6; | ||||
rss->hash_func = UPT1_RSS_HASH_FUNC_TOEPLITZ; | rss->hash_func = UPT1_RSS_HASH_FUNC_TOEPLITZ; | ||||
rss->hash_key_size = UPT1_RSS_MAX_KEY_SIZE; | rss->hash_key_size = UPT1_RSS_MAX_KEY_SIZE; | ||||
rss->ind_table_size = UPT1_RSS_MAX_IND_TABLE_SIZE; | rss->ind_table_size = UPT1_RSS_MAX_IND_TABLE_SIZE; | ||||
#ifdef RSS | |||||
/* | |||||
* If the software RSS is configured to anything else other than | |||||
* Toeplitz, then just do Toeplitz in "hardware" for the sake of | |||||
* the packet distribution, but report the hash as opaque to | |||||
* disengage from the software RSS. | |||||
*/ | |||||
rss_algo = rss_gethashalgo(); | |||||
if (rss_algo == RSS_HASH_TOEPLITZ) { | |||||
rss_getkey(rss->hash_key); | |||||
for (i = 0; i < UPT1_RSS_MAX_IND_TABLE_SIZE; i++) { | |||||
rss->ind_table[i] = rss_get_indirection_to_bucket(i) % | |||||
scctx->isc_nrxqsets; | |||||
} | |||||
sc->vmx_flags |= VMXNET3_FLAG_SOFT_RSS; | |||||
} else | |||||
#endif | |||||
{ | |||||
memcpy(rss->hash_key, rss_key, UPT1_RSS_MAX_KEY_SIZE); | memcpy(rss->hash_key, rss_key, UPT1_RSS_MAX_KEY_SIZE); | ||||
for (i = 0; i < UPT1_RSS_MAX_IND_TABLE_SIZE; i++) | for (i = 0; i < UPT1_RSS_MAX_IND_TABLE_SIZE; i++) | ||||
rss->ind_table[i] = i % scctx->isc_nrxqsets; | rss->ind_table[i] = i % scctx->isc_nrxqsets; | ||||
sc->vmx_flags &= ~VMXNET3_FLAG_SOFT_RSS; | |||||
} | } | ||||
} | |||||
static void | static void | ||||
vmxnet3_reinit_shared_data(struct vmxnet3_softc *sc) | vmxnet3_reinit_shared_data(struct vmxnet3_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
struct vmxnet3_driver_shared *ds; | struct vmxnet3_driver_shared *ds; | ||||
if_softc_ctx_t scctx; | if_softc_ctx_t scctx; | ||||
▲ Show 20 Lines • Show All 326 Lines • ▼ Show 20 Lines | if (++cqidx == rxc->vxcr_ndesc) { | ||||
cqidx = 0; | cqidx = 0; | ||||
rxc->vxcr_gen ^= 1; | rxc->vxcr_gen ^= 1; | ||||
} | } | ||||
rxcd = &rxc->vxcr_u.rxcd[cqidx]; | rxcd = &rxc->vxcr_u.rxcd[cqidx]; | ||||
} | } | ||||
KASSERT(rxcd->sop, ("%s: expected sop", __func__)); | KASSERT(rxcd->sop, ("%s: expected sop", __func__)); | ||||
/* | /* | ||||
* RSS and flow ID | * RSS and flow ID. | ||||
* Types other than M_HASHTYPE_NONE and M_HASHTYPE_OPAQUE_HASH should | |||||
* be used only if the software RSS is enabled and it uses the same | |||||
* algorithm and the hash key as the "hardware". If the software RSS | |||||
* is not enabled, then it's simply pointless to use those types. | |||||
* If it's enabled but with different parameters, then hash values will | |||||
* not match. | |||||
*/ | */ | ||||
ri->iri_flowid = rxcd->rss_hash; | ri->iri_flowid = rxcd->rss_hash; | ||||
#ifdef RSS | |||||
if ((sc->vmx_flags & VMXNET3_FLAG_SOFT_RSS) != 0) { | |||||
switch (rxcd->rss_type) { | switch (rxcd->rss_type) { | ||||
case VMXNET3_RCD_RSS_TYPE_NONE: | case VMXNET3_RCD_RSS_TYPE_NONE: | ||||
ri->iri_flowid = ri->iri_qsidx; | ri->iri_flowid = ri->iri_qsidx; | ||||
ri->iri_rsstype = M_HASHTYPE_NONE; | ri->iri_rsstype = M_HASHTYPE_NONE; | ||||
break; | break; | ||||
case VMXNET3_RCD_RSS_TYPE_IPV4: | case VMXNET3_RCD_RSS_TYPE_IPV4: | ||||
ri->iri_rsstype = M_HASHTYPE_RSS_IPV4; | ri->iri_rsstype = M_HASHTYPE_RSS_IPV4; | ||||
break; | break; | ||||
case VMXNET3_RCD_RSS_TYPE_TCPIPV4: | case VMXNET3_RCD_RSS_TYPE_TCPIPV4: | ||||
ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV4; | ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV4; | ||||
break; | break; | ||||
case VMXNET3_RCD_RSS_TYPE_IPV6: | case VMXNET3_RCD_RSS_TYPE_IPV6: | ||||
ri->iri_rsstype = M_HASHTYPE_RSS_IPV6; | ri->iri_rsstype = M_HASHTYPE_RSS_IPV6; | ||||
break; | break; | ||||
case VMXNET3_RCD_RSS_TYPE_TCPIPV6: | case VMXNET3_RCD_RSS_TYPE_TCPIPV6: | ||||
ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV6; | ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV6; | ||||
break; | break; | ||||
default: | default: | ||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH; | ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH; | ||||
break; | break; | ||||
} | |||||
} else | |||||
#endif | |||||
{ | |||||
switch (rxcd->rss_type) { | |||||
case VMXNET3_RCD_RSS_TYPE_NONE: | |||||
ri->iri_flowid = ri->iri_qsidx; | |||||
ri->iri_rsstype = M_HASHTYPE_NONE; | |||||
break; | |||||
default: | |||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH; | |||||
break; | |||||
} | |||||
} | } | ||||
/* VLAN */ | /* VLAN */ | ||||
if (rxcd->vlan) { | if (rxcd->vlan) { | ||||
ri->iri_flags |= M_VLANTAG; | ri->iri_flags |= M_VLANTAG; | ||||
ri->iri_vtag = rxcd->vtag; | ri->iri_vtag = rxcd->vtag; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 884 Lines • Show Last 20 Lines |