Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161121078
D7641.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D7641.diff
View Options
Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -51,6 +51,7 @@
#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 @@
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 @@
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 @@
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 @@
{
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 @@
/* 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);
Index: head/sys/dev/hyperv/netvsc/ndis.h
===================================================================
--- head/sys/dev/hyperv/netvsc/ndis.h
+++ head/sys/dev/hyperv/netvsc/ndis.h
@@ -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_ */
Index: head/sys/net/rndis.h
===================================================================
--- head/sys/net/rndis.h
+++ head/sys/net/rndis.h
@@ -202,6 +202,10 @@
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;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 1, 5:52 PM (14 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34571935
Default Alt Text
D7641.diff (9 KB)
Attached To
Mode
D7641: hyperv/hn: Use vmbus xact for RNDIS set.
Attached
Detach File
Event Timeline
Log In to Comment