Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
Show All 32 Lines | |||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_arp.h> | #include <net/if_arp.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <net/rndis.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <sys/sema.h> | #include <sys/sema.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <dev/hyperv/include/hyperv.h> | #include <dev/hyperv/include/hyperv.h> | ||||
#include <dev/hyperv/include/vmbus_xact.h> | #include <dev/hyperv/include/vmbus_xact.h> | ||||
#include <dev/hyperv/netvsc/hv_net_vsc.h> | #include <dev/hyperv/netvsc/hv_net_vsc.h> | ||||
#include <dev/hyperv/netvsc/hv_rndis.h> | |||||
#include <dev/hyperv/netvsc/hv_rndis_filter.h> | #include <dev/hyperv/netvsc/hv_rndis_filter.h> | ||||
#include <dev/hyperv/netvsc/if_hnreg.h> | #include <dev/hyperv/netvsc/if_hnreg.h> | ||||
#include <dev/hyperv/netvsc/ndis.h> | #include <dev/hyperv/netvsc/ndis.h> | ||||
#define HV_RF_RECVINFO_VLAN 0x1 | #define HV_RF_RECVINFO_VLAN 0x1 | ||||
#define HV_RF_RECVINFO_CSUM 0x2 | #define HV_RF_RECVINFO_CSUM 0x2 | ||||
#define HV_RF_RECVINFO_HASHINF 0x4 | #define HV_RF_RECVINFO_HASHINF 0x4 | ||||
#define HV_RF_RECVINFO_HASHVAL 0x8 | #define HV_RF_RECVINFO_HASHVAL 0x8 | ||||
▲ Show 20 Lines • Show All 354 Lines • ▼ Show 20 Lines | #undef IS_OFFSET_INVALID | ||||
} | } | ||||
if (__predict_false(data_off + data_len > pkt->rm_len)) { | if (__predict_false(data_off + data_len > pkt->rm_len)) { | ||||
if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " | if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " | ||||
"data overflow, msglen %u, data abs %d len %d\n", | "data overflow, msglen %u, data abs %d len %d\n", | ||||
pkt->rm_len, data_off, data_len); | pkt->rm_len, data_off, data_len); | ||||
return; | return; | ||||
} | } | ||||
netvsc_recv(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); | hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); | ||||
} | } | ||||
/* | /* | ||||
* RNDIS filter on receive | * RNDIS filter on receive | ||||
*/ | */ | ||||
void | void | ||||
hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, | hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, | ||||
const void *data, int dlen) | const void *data, int dlen) | ||||
▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct ndis_rss_caps in, caps; | struct ndis_rss_caps in, caps; | ||||
size_t caps_len; | size_t caps_len; | ||||
int error; | int error; | ||||
/* | /* | ||||
* Only NDIS 6.30+ is supported. | * Only NDIS 6.30+ is supported. | ||||
*/ | */ | ||||
KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, | KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, | ||||
("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); | ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); | ||||
*rxr_cnt = 0; | *rxr_cnt = 0; | ||||
memset(&in, 0, sizeof(in)); | memset(&in, 0, sizeof(in)); | ||||
in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS; | in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS; | ||||
in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; | in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; | ||||
in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; | in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | hn_rndis_conf_offload(struct hn_softc *sc) | ||||
struct ndis_offload_params params; | struct ndis_offload_params params; | ||||
size_t paramsz; | size_t paramsz; | ||||
int error; | int error; | ||||
/* NOTE: 0 means "no change" */ | /* NOTE: 0 means "no change" */ | ||||
memset(¶ms, 0, sizeof(params)); | memset(¶ms, 0, sizeof(params)); | ||||
params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; | params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; | ||||
if (sc->hn_ndis_ver < NDIS_VERSION_6_30) { | if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30) { | ||||
params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; | params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; | ||||
paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1; | paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1; | ||||
} else { | } else { | ||||
params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3; | params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3; | ||||
paramsz = NDIS_OFFLOAD_PARAMS_SIZE; | paramsz = NDIS_OFFLOAD_PARAMS_SIZE; | ||||
} | } | ||||
params.ndis_hdr.ndis_size = paramsz; | params.ndis_hdr.ndis_size = paramsz; | ||||
params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; | params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; | ||||
params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; | params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; | ||||
params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; | params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; | ||||
if (sc->hn_ndis_ver >= NDIS_VERSION_6_30) { | if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { | ||||
params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; | params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; | ||||
params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; | params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; | ||||
} | } | ||||
params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; | params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; | ||||
/* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ | /* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ | ||||
error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); | error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); | ||||
if (error) { | if (error) { | ||||
Show All 10 Lines | |||||
{ | { | ||||
struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; | struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; | ||||
struct ndis_rss_params *prm = &rss->rss_params; | struct ndis_rss_params *prm = &rss->rss_params; | ||||
int i, error; | int i, error; | ||||
/* | /* | ||||
* Only NDIS 6.30+ is supported. | * Only NDIS 6.30+ is supported. | ||||
*/ | */ | ||||
KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, | KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, | ||||
("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); | ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); | ||||
memset(rss, 0, sizeof(*rss)); | memset(rss, 0, sizeof(*rss)); | ||||
prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; | prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; | ||||
prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; | prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; | ||||
prm->ndis_hdr.ndis_size = sizeof(*rss); | prm->ndis_hdr.ndis_size = sizeof(*rss); | ||||
prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ | | prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ | | ||||
NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | | NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | | ||||
▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | if (ret != 0) { | ||||
/* TODO: shut down rndis device and the channel */ | /* TODO: shut down rndis device and the channel */ | ||||
} | } | ||||
/* Configure NDIS offload settings */ | /* Configure NDIS offload settings */ | ||||
hn_rndis_conf_offload(sc); | hn_rndis_conf_offload(sc); | ||||
hv_rf_query_device_link_status(sc, &dev_info->link_state); | hv_rf_query_device_link_status(sc, &dev_info->link_state); | ||||
if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) { | if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) { | ||||
/* | /* | ||||
* Either RSS is not supported, or multiple RX/TX rings | * Either RSS is not supported, or multiple RX/TX rings | ||||
* are not requested. | * are not requested. | ||||
*/ | */ | ||||
*nchan0 = 1; | *nchan0 = 1; | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | hv_rf_on_close(struct hn_softc *sc) | ||||
return (hn_rndis_set_rxfilter(sc, 0)); | return (hn_rndis_set_rxfilter(sc, 0)); | ||||
} | } | ||||
void | void | ||||
hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) | hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) | ||||
{ | { | ||||
netvsc_channel_rollup(rxr, txr); | hn_chan_rollup(rxr, txr); | ||||
} | } |