Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
static void hv_rf_receive_data(struct hn_rx_ring *rxr, | static void hv_rf_receive_data(struct hn_rx_ring *rxr, | ||||
const void *data, int dlen); | const void *data, int dlen); | ||||
static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, | static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, | ||||
const void *idata, size_t idlen, void *odata, size_t *odlen0); | const void *idata, size_t idlen, void *odata, size_t *odlen0); | ||||
static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, | static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, | ||||
size_t dlen); | size_t dlen); | ||||
static int hn_rndis_conf_offload(struct hn_softc *sc); | static int hn_rndis_conf_offload(struct hn_softc *sc); | ||||
static int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt); | |||||
static int hn_rndis_conf_rss(struct hn_softc *sc, int nchan); | |||||
static __inline uint32_t | static __inline uint32_t | ||||
hn_rndis_rid(struct hn_softc *sc) | hn_rndis_rid(struct hn_softc *sc) | ||||
{ | { | ||||
uint32_t rid; | uint32_t rid; | ||||
again: | again: | ||||
rid = atomic_fetchadd_int(&sc->hn_rndis_rid, 1); | rid = atomic_fetchadd_int(&sc->hn_rndis_rid, 1); | ||||
▲ Show 20 Lines • Show All 612 Lines • ▼ Show 20 Lines | hn_rndis_query(struct hn_softc *sc, uint32_t oid, | ||||
*odlen0 = odlen; | *odlen0 = odlen; | ||||
error = 0; | error = 0; | ||||
done: | done: | ||||
vmbus_xact_put(xact); | vmbus_xact_put(xact); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | int | ||||
hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) | hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) | ||||
{ | { | ||||
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. | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | if (error) { | ||||
if_printf(sc->hn_ifp, "offload config failed: %d\n", error); | if_printf(sc->hn_ifp, "offload config failed: %d\n", error); | ||||
} else { | } else { | ||||
if (bootverbose) | if (bootverbose) | ||||
if_printf(sc->hn_ifp, "offload config done\n"); | if_printf(sc->hn_ifp, "offload config done\n"); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | int | ||||
hn_rndis_conf_rss(struct hn_softc *sc, int nchan) | hn_rndis_conf_rss(struct hn_softc *sc, int nchan) | ||||
{ | { | ||||
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. | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | hv_rf_halt_device(struct hn_softc *sc) | ||||
hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len); | hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len); | ||||
vmbus_xact_put(xact); | vmbus_xact_put(xact); | ||||
if (bootverbose) | if (bootverbose) | ||||
if_printf(sc->hn_ifp, "RNDIS halt done\n"); | if_printf(sc->hn_ifp, "RNDIS halt done\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | int | ||||
hn_rndis_attach(struct hn_softc *sc) | hn_rndis_attach(struct hn_softc *sc) | ||||
{ | { | ||||
int error; | int error; | ||||
/* | /* | ||||
* Initialize RNDIS. | * Initialize RNDIS. | ||||
*/ | */ | ||||
error = hn_rndis_init(sc); | error = hn_rndis_init(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Configure NDIS offload settings. | * Configure NDIS offload settings. | ||||
* XXX no offloading, if error happened? | * XXX no offloading, if error happened? | ||||
*/ | */ | ||||
hn_rndis_conf_offload(sc); | hn_rndis_conf_offload(sc); | ||||
return (0); | |||||
} | |||||
int | |||||
hv_rf_on_device_add(struct hn_softc *sc, int *nchan0, int mtu) | |||||
{ | |||||
int ret; | |||||
device_t dev = sc->hn_dev; | |||||
int nchan = *nchan0, rxr_cnt, nsubch; | |||||
ret = hn_nvs_attach(sc, mtu); | |||||
if (ret != 0) | |||||
return (ret); | |||||
ret = hn_rndis_attach(sc); | |||||
if (ret != 0) | |||||
return (ret); | |||||
if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) { | |||||
/* | |||||
* Either RSS is not supported, or multiple RX/TX rings | |||||
* are not requested. | |||||
*/ | |||||
*nchan0 = 1; | |||||
return (0); | |||||
} | |||||
/* | |||||
* Get RSS capabilities, e.g. # of RX rings, and # of indirect | |||||
* table entries. | |||||
*/ | |||||
ret = hn_rndis_get_rsscaps(sc, &rxr_cnt); | |||||
if (ret) { | |||||
/* No RSS; this is benign. */ | |||||
*nchan0 = 1; | |||||
return (0); | |||||
} | |||||
if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n", | |||||
rxr_cnt, nchan); | |||||
if (nchan > rxr_cnt) | |||||
nchan = rxr_cnt; | |||||
if (nchan == 1) { | |||||
device_printf(dev, "only 1 channel is supported, no vRSS\n"); | |||||
*nchan0 = 1; | |||||
return (0); | |||||
} | |||||
/* | |||||
* Allocate sub-channels from NVS. | |||||
*/ | |||||
nsubch = nchan - 1; | |||||
ret = hn_nvs_alloc_subchans(sc, &nsubch); | |||||
if (ret || nsubch == 0) { | |||||
/* Failed to allocate sub-channels. */ | |||||
*nchan0 = 1; | |||||
return (0); | |||||
} | |||||
nchan = nsubch + 1; | |||||
/* | |||||
* Configure RSS key and indirect table after all sub-channels | |||||
* are allocated. | |||||
*/ | |||||
ret = hn_rndis_conf_rss(sc, nchan); | |||||
if (ret != 0) { | |||||
/* Failed to configure RSS key or indirect table. */ | |||||
nchan = 1; | |||||
} | |||||
*nchan0 = nchan; | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* RNDIS filter on device remove | * RNDIS filter on device remove | ||||
*/ | */ | ||||
int | int | ||||
hv_rf_on_device_remove(struct hn_softc *sc) | hv_rf_on_device_remove(struct hn_softc *sc) | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |