mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
hyperv/hn: Use vmbus xact for RNDIS set.
And use new RNDIS set to configure NDIS offloading parameters. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7641
This commit is contained in:
parent
467da5ad48
commit
77c4f5aa9d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304834
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/hyperv/netvsc/hv_rndis.h>
|
||||
#include <dev/hyperv/netvsc/hv_rndis_filter.h>
|
||||
#include <dev/hyperv/netvsc/if_hnreg.h>
|
||||
#include <dev/hyperv/netvsc/ndis.h>
|
||||
|
||||
#define HV_RF_RECVINFO_VLAN 0x1
|
||||
#define HV_RF_RECVINFO_CSUM 0x2
|
||||
@ -98,6 +99,9 @@ static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
|
||||
const void *data, int dlen);
|
||||
static int hn_rndis_query(struct hn_softc *sc, uint32_t oid,
|
||||
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,
|
||||
size_t dlen);
|
||||
static int hn_rndis_conf_offload(struct hn_softc *sc);
|
||||
|
||||
static __inline uint32_t
|
||||
hn_rndis_rid(struct hn_softc *sc)
|
||||
@ -1002,7 +1006,7 @@ hn_rndis_query(struct hn_softc *sc, uint32_t oid,
|
||||
reqlen = sizeof(*req) + idlen;
|
||||
xact = vmbus_xact_get(sc->hn_xact, reqlen);
|
||||
if (xact == NULL) {
|
||||
if_printf(sc->hn_ifp, "no xact for RNDIS query\n");
|
||||
if_printf(sc->hn_ifp, "no xact for RNDIS query 0x%08x\n", oid);
|
||||
return (ENXIO);
|
||||
}
|
||||
rid = hn_rndis_rid(sc);
|
||||
@ -1078,6 +1082,96 @@ hn_rndis_query(struct hn_softc *sc, uint32_t oid,
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen)
|
||||
{
|
||||
struct rndis_set_req *req;
|
||||
const struct rndis_set_comp *comp;
|
||||
struct vmbus_xact *xact;
|
||||
size_t reqlen, comp_len;
|
||||
uint32_t rid;
|
||||
int error;
|
||||
|
||||
KASSERT(dlen > 0, ("invalid dlen %zu", dlen));
|
||||
|
||||
reqlen = sizeof(*req) + dlen;
|
||||
xact = vmbus_xact_get(sc->hn_xact, reqlen);
|
||||
if (xact == NULL) {
|
||||
if_printf(sc->hn_ifp, "no xact for RNDIS set 0x%08x\n", oid);
|
||||
return (ENXIO);
|
||||
}
|
||||
rid = hn_rndis_rid(sc);
|
||||
req = vmbus_xact_req_data(xact);
|
||||
req->rm_type = REMOTE_NDIS_SET_MSG;
|
||||
req->rm_len = reqlen;
|
||||
req->rm_rid = rid;
|
||||
req->rm_oid = oid;
|
||||
req->rm_infobuflen = dlen;
|
||||
req->rm_infobufoffset = RNDIS_SET_REQ_INFOBUFOFFSET;
|
||||
/* Data immediately follows RNDIS set. */
|
||||
memcpy(req + 1, data, dlen);
|
||||
|
||||
comp_len = sizeof(*comp);
|
||||
comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len,
|
||||
REMOTE_NDIS_SET_CMPLT);
|
||||
if (comp == NULL) {
|
||||
if_printf(sc->hn_ifp, "exec RNDIS set 0x%08x failed\n", oid);
|
||||
error = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (comp->rm_status != RNDIS_STATUS_SUCCESS) {
|
||||
if_printf(sc->hn_ifp, "RNDIS set 0x%08x failed: "
|
||||
"status 0x%08x\n", oid, comp->rm_status);
|
||||
error = EIO;
|
||||
goto done;
|
||||
}
|
||||
error = 0;
|
||||
done:
|
||||
vmbus_xact_put(xact);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
hn_rndis_conf_offload(struct hn_softc *sc)
|
||||
{
|
||||
struct ndis_offload_params params;
|
||||
size_t paramsz;
|
||||
int error;
|
||||
|
||||
/* NOTE: 0 means "no change" */
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT;
|
||||
if (sc->hn_ndis_ver < NDIS_VERSION_6_30) {
|
||||
params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2;
|
||||
paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1;
|
||||
} else {
|
||||
params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3;
|
||||
paramsz = NDIS_OFFLOAD_PARAMS_SIZE;
|
||||
}
|
||||
params.ndis_hdr.ndis_size = paramsz;
|
||||
|
||||
params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX;
|
||||
params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX;
|
||||
params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX;
|
||||
if (sc->hn_ndis_ver >= NDIS_VERSION_6_30) {
|
||||
params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX;
|
||||
params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX;
|
||||
}
|
||||
params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON;
|
||||
/* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */
|
||||
|
||||
error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz);
|
||||
if (error) {
|
||||
if_printf(sc->hn_ifp, "offload config failed: %d\n", error);
|
||||
} else {
|
||||
if (bootverbose)
|
||||
if_printf(sc->hn_ifp, "offload config done\n");
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* RNDIS filter init device
|
||||
*/
|
||||
@ -1243,7 +1337,6 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
|
||||
{
|
||||
int ret;
|
||||
rndis_device *rndis_dev;
|
||||
rndis_offload_params offloads;
|
||||
struct rndis_recv_scale_cap rsscaps;
|
||||
uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap);
|
||||
netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
|
||||
@ -1293,21 +1386,8 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
|
||||
/* TODO: shut down rndis device and the channel */
|
||||
}
|
||||
|
||||
/* config csum offload and send request to host */
|
||||
memset(&offloads, 0, sizeof(offloads));
|
||||
offloads.ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.tcp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.udp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.tcp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.udp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.lso_v2_ipv4 = RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
|
||||
|
||||
ret = hv_rf_send_offload_request(sc, &offloads);
|
||||
if (ret != 0) {
|
||||
/* TODO: shut down rndis device and the channel */
|
||||
device_printf(dev,
|
||||
"hv_rf_send_offload_request failed, ret=%d\n", ret);
|
||||
}
|
||||
/* Configure NDIS offload settings */
|
||||
hn_rndis_conf_offload(sc);
|
||||
|
||||
memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, ETHER_ADDR_LEN);
|
||||
|
||||
|
118
sys/dev/hyperv/netvsc/ndis.h
Normal file
118
sys/dev/hyperv/netvsc/ndis.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NET_NDIS_H_
|
||||
#define _NET_NDIS_H_
|
||||
|
||||
#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C
|
||||
|
||||
#define NDIS_OBJTYPE_DEFAULT 0x80
|
||||
|
||||
/* common_set */
|
||||
#define NDIS_OFFLOAD_SET_NOCHG 0
|
||||
#define NDIS_OFFLOAD_SET_ON 1
|
||||
#define NDIS_OFFLOAD_SET_OFF 2
|
||||
|
||||
/* a.k.a GRE MAC */
|
||||
#define NDIS_ENCAP_TYPE_NVGRE 0x00000001
|
||||
|
||||
struct ndis_object_hdr {
|
||||
uint8_t ndis_type; /* NDIS_OBJTYPE_ */
|
||||
uint8_t ndis_rev; /* type specific */
|
||||
uint16_t ndis_size; /* incl. this hdr */
|
||||
};
|
||||
|
||||
/* OID_TCP_OFFLOAD_PARAMETERS */
|
||||
struct ndis_offload_params {
|
||||
struct ndis_object_hdr ndis_hdr;
|
||||
uint8_t ndis_ip4csum; /* param_set */
|
||||
uint8_t ndis_tcp4csum; /* param_set */
|
||||
uint8_t ndis_udp4csum; /* param_set */
|
||||
uint8_t ndis_tcp6csum; /* param_set */
|
||||
uint8_t ndis_udp6csum; /* param_set */
|
||||
uint8_t ndis_lsov1; /* lsov1_set */
|
||||
uint8_t ndis_ipsecv1; /* ipsecv1_set */
|
||||
uint8_t ndis_lsov2_ip4; /* lsov2_set */
|
||||
uint8_t ndis_lsov2_ip6; /* lsov2_set */
|
||||
uint8_t ndis_tcp4conn; /* PARAM_NOCHG */
|
||||
uint8_t ndis_tcp6conn; /* PARAM_NOCHG */
|
||||
uint32_t ndis_flags; /* 0 */
|
||||
/* NDIS >= 6.1 */
|
||||
uint8_t ndis_ipsecv2; /* ipsecv2_set */
|
||||
uint8_t ndis_ipsecv2_ip4; /* ipsecv2_set */
|
||||
/* NDIS >= 6.30 */
|
||||
uint8_t ndis_rsc_ip4; /* rsc_set */
|
||||
uint8_t ndis_rsc_ip6; /* rsc_set */
|
||||
uint8_t ndis_encap; /* common_set */
|
||||
uint8_t ndis_encap_types; /* NDIS_ENCAP_TYPE_ */
|
||||
};
|
||||
|
||||
#define NDIS_OFFLOAD_PARAMS_SIZE sizeof(struct ndis_offload_params)
|
||||
#define NDIS_OFFLOAD_PARAMS_SIZE_6_1 \
|
||||
__offsetof(struct ndis_offload_params, ndis_rsc_ip4)
|
||||
|
||||
#define NDIS_OFFLOAD_PARAMS_REV_2 2 /* NDIS 6.1 */
|
||||
#define NDIS_OFFLOAD_PARAMS_REV_3 3 /* NDIS 6.30 */
|
||||
|
||||
/* param_set */
|
||||
#define NDIS_OFFLOAD_PARAM_NOCHG 0 /* common to all sets */
|
||||
#define NDIS_OFFLOAD_PARAM_OFF 1
|
||||
#define NDIS_OFFLOAD_PARAM_TX 2
|
||||
#define NDIS_OFFLOAD_PARAM_RX 3
|
||||
#define NDIS_OFFLOAD_PARAM_TXRX 4
|
||||
|
||||
/* lsov1_set */
|
||||
/* NDIS_OFFLOAD_PARAM_NOCHG */
|
||||
#define NDIS_OFFLOAD_LSOV1_OFF 1
|
||||
#define NDIS_OFFLOAD_LSOV1_ON 2
|
||||
|
||||
/* ipsecv1_set */
|
||||
/* NDIS_OFFLOAD_PARAM_NOCHG */
|
||||
#define NDIS_OFFLOAD_IPSECV1_OFF 1
|
||||
#define NDIS_OFFLOAD_IPSECV1_AH 2
|
||||
#define NDIS_OFFLOAD_IPSECV1_ESP 3
|
||||
#define NDIS_OFFLOAD_IPSECV1_AH_ESP 4
|
||||
|
||||
/* lsov2_set */
|
||||
/* NDIS_OFFLOAD_PARAM_NOCHG */
|
||||
#define NDIS_OFFLOAD_LSOV2_OFF 1
|
||||
#define NDIS_OFFLOAD_LSOV2_ON 2
|
||||
|
||||
/* ipsecv2_set */
|
||||
/* NDIS_OFFLOAD_PARAM_NOCHG */
|
||||
#define NDIS_OFFLOAD_IPSECV2_OFF 1
|
||||
#define NDIS_OFFLOAD_IPSECV2_AH 2
|
||||
#define NDIS_OFFLOAD_IPSECV2_ESP 3
|
||||
#define NDIS_OFFLOAD_IPSECV2_AH_ESP 4
|
||||
|
||||
/* rsc_set */
|
||||
/* NDIS_OFFLOAD_PARAM_NOCHG */
|
||||
#define NDIS_OFFLOAD_RSC_OFF 1
|
||||
#define NDIS_OFFLOAD_RSC_ON 2
|
||||
|
||||
#endif /* !_NET_NDIS_H_ */
|
@ -202,6 +202,10 @@ struct rndis_set_req {
|
||||
uint32_t rm_devicevchdl;
|
||||
};
|
||||
|
||||
#define RNDIS_SET_REQ_INFOBUFOFFSET \
|
||||
(sizeof(struct rndis_set_req) - \
|
||||
__offsetof(struct rndis_set_req, rm_rid))
|
||||
|
||||
struct rndis_set_comp {
|
||||
uint32_t rm_type;
|
||||
uint32_t rm_len;
|
||||
|
Loading…
Reference in New Issue
Block a user