Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
Show First 20 Lines • Show All 1,024 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* RNDIS filter on device add | * RNDIS filter on device add | ||||
*/ | */ | ||||
int | int | ||||
hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, | hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, | ||||
int *nchan0, struct hn_rx_ring *rxr) | int *nchan0, struct hn_rx_ring *rxr) | ||||
{ | { | ||||
struct hn_send_ctx sndc; | |||||
int ret; | int ret; | ||||
rndis_device *rndis_dev; | rndis_device *rndis_dev; | ||||
rndis_offload_params offloads; | rndis_offload_params offloads; | ||||
struct rndis_recv_scale_cap rsscaps; | struct rndis_recv_scale_cap rsscaps; | ||||
uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); | uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); | ||||
netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; | netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; | ||||
device_t dev = sc->hn_dev; | device_t dev = sc->hn_dev; | ||||
struct hn_nvs_subch_req *req; | struct hn_nvs_subch_req *req; | ||||
const struct hn_nvs_subch_resp *resp; | const struct hn_nvs_subch_resp *resp; | ||||
size_t resp_len; | size_t resp_len; | ||||
struct vmbus_xact *xact; | struct vmbus_xact *xact = NULL; | ||||
uint32_t status, nsubch; | uint32_t status, nsubch; | ||||
int nchan = *nchan0; | int nchan = *nchan0; | ||||
rndis_dev = hv_get_rndis_device(); | rndis_dev = hv_get_rndis_device(); | ||||
if (rndis_dev == NULL) { | if (rndis_dev == NULL) { | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
sc->rndis_dev = rndis_dev; | sc->rndis_dev = rndis_dev; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, | ||||
* Ask NVS to allocate sub-channels. | * Ask NVS to allocate sub-channels. | ||||
*/ | */ | ||||
xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); | xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); | ||||
if (xact == NULL) { | if (xact == NULL) { | ||||
if_printf(sc->hn_ifp, "no xact for nvs subch req\n"); | if_printf(sc->hn_ifp, "no xact for nvs subch req\n"); | ||||
ret = ENXIO; | ret = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
req = vmbus_xact_req_data(xact); | req = vmbus_xact_req_data(xact); | ||||
req->nvs_type = HN_NVS_TYPE_SUBCH_REQ; | req->nvs_type = HN_NVS_TYPE_SUBCH_REQ; | ||||
req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; | req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; | ||||
req->nvs_nsubch = nchan - 1; | req->nvs_nsubch = nchan - 1; | ||||
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); | resp = hn_nvs_xact_execute(sc, xact, req, sizeof(*req), &resp_len); | ||||
vmbus_xact_activate(xact); | if (resp == NULL) { | ||||
if_printf(sc->hn_ifp, "exec subch failed\n"); | |||||
ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, | ret = EIO; | ||||
req, sizeof(*req), &sndc); | |||||
if (ret != 0) { | |||||
if_printf(sc->hn_ifp, "send nvs subch req failed: %d\n", ret); | |||||
vmbus_xact_deactivate(xact); | |||||
vmbus_xact_put(xact); | |||||
goto out; | goto out; | ||||
} | } | ||||
resp = vmbus_xact_wait(xact, &resp_len); | |||||
if (resp_len < sizeof(*resp)) { | if (resp_len < sizeof(*resp)) { | ||||
if_printf(sc->hn_ifp, "invalid subch resp length %zu\n", | if_printf(sc->hn_ifp, "invalid subch resp length %zu\n", | ||||
resp_len); | resp_len); | ||||
vmbus_xact_put(xact); | |||||
ret = EINVAL; | ret = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) { | if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) { | ||||
if_printf(sc->hn_ifp, "not subch resp, type %u\n", | if_printf(sc->hn_ifp, "not subch resp, type %u\n", | ||||
resp->nvs_type); | resp->nvs_type); | ||||
vmbus_xact_put(xact); | |||||
ret = EINVAL; | ret = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
status = resp->nvs_status; | status = resp->nvs_status; | ||||
nsubch = resp->nvs_nsubch; | nsubch = resp->nvs_nsubch; | ||||
vmbus_xact_put(xact); | vmbus_xact_put(xact); | ||||
xact = NULL; | |||||
if (status != HN_NVS_STATUS_OK) { | if (status != HN_NVS_STATUS_OK) { | ||||
if_printf(sc->hn_ifp, "subch req failed: %x\n", status); | if_printf(sc->hn_ifp, "subch req failed: %x\n", status); | ||||
ret = EIO; | ret = EIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (nsubch > nchan - 1) { | if (nsubch > nchan - 1) { | ||||
if_printf(sc->hn_ifp, "%u subchans are allocated, requested %u\n", | if_printf(sc->hn_ifp, "%u subchans are allocated, requested %u\n", | ||||
nsubch, nchan - 1); | nsubch, nchan - 1); | ||||
nsubch = nchan - 1; | nsubch = nchan - 1; | ||||
} | } | ||||
nchan = nsubch + 1; | nchan = nsubch + 1; | ||||
ret = hv_rf_set_rss_param(rndis_dev, nchan); | ret = hv_rf_set_rss_param(rndis_dev, nchan); | ||||
*nchan0 = nchan; | *nchan0 = nchan; | ||||
out: | out: | ||||
if (xact != NULL) | |||||
vmbus_xact_put(xact); | |||||
return (ret); | return (ret); | ||||
} | } | ||||
/* | /* | ||||
* RNDIS filter on device remove | * RNDIS filter on device remove | ||||
*/ | */ | ||||
int | int | ||||
hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) | hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |