summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-10-17 07:20:01 +0000
committersephe <sephe@FreeBSD.org>2016-10-17 07:20:01 +0000
commit1650850a80f32eee2676cb7f8869df4e1d051ed8 (patch)
tree6876cca3c3c4868867cbbddbdf52680cd9cade53
parent37445c8067e2b4a3fba12cd7d32a3d14cd84358f (diff)
downloadFreeBSD-src-1650850a80f32eee2676cb7f8869df4e1d051ed8.zip
FreeBSD-src-1650850a80f32eee2676cb7f8869df4e1d051ed8.tar.gz
MFC 304832-304834,304972
304832 hyperv/hn: Use vmbus xact for RNDIS query. And switch MAC address query to use new RNDIS query function. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7639 304833 hyperv/hn: Save the adopted NDIS version for RNDIS to use later. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7640 304834 hyperv/hn: Use vmbus xact for RNDIS set. And use new RNDIS set to configure NDIS offloading parameters. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7641 304972 hyperv/hn: Add definition for NDIS media state. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7652
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c17
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h1
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c35
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis.h7
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c242
-rw-r--r--sys/dev/hyperv/netvsc/ndis.h121
-rw-r--r--sys/net/rndis.h11
7 files changed, 390 insertions, 44 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index 4e61516..e1552cc 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -521,9 +521,15 @@ hv_nv_connect_to_vsp(struct hn_softc *sc)
for (i = protocol_number - 1; i >= 0; i--) {
if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) {
sc->hn_nvs_ver = protocol_list[i];
+ sc->hn_ndis_ver = NDIS_VERSION_6_30;
+ if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4)
+ sc->hn_ndis_ver = NDIS_VERSION_6_1;
if (bootverbose) {
- device_printf(dev, "NVS version 0x%x\n",
- sc->hn_nvs_ver);
+ if_printf(sc->hn_ifp, "NVS version 0x%x, "
+ "NDIS version %u.%u\n",
+ sc->hn_nvs_ver,
+ NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
+ NDIS_VERSION_MINOR(sc->hn_ndis_ver));
}
break;
}
@@ -549,11 +555,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc)
memset(&ndis, 0, sizeof(ndis));
ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT;
- ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6;
- if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4)
- ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1;
- else
- ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30;
+ ndis.nvs_ndis_major = NDIS_VERSION_MAJOR(sc->hn_ndis_ver);
+ ndis.nvs_ndis_minor = NDIS_VERSION_MINOR(sc->hn_ndis_ver);
/* NOTE: No response. */
ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis));
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index f9dada0..f51fe76 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -382,6 +382,7 @@ typedef struct hn_softc {
struct hyperv_dma hn_chim_dma;
uint32_t hn_rndis_rid;
+ uint32_t hn_ndis_ver;
} hn_softc_t;
#define HN_FLAG_RXBUF_CONNECTED 0x0001
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index b7713be..24aa310 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -117,9 +117,11 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/include/vmbus_xact.h>
-#include "hv_net_vsc.h"
-#include "hv_rndis.h"
-#include "hv_rndis_filter.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/ndis.h>
+
#include "vmbus_if.h"
/* Short for Hyper-V network interface */
@@ -330,6 +332,7 @@ static int hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rx_stat_u64_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
+static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_check_iplen(const struct mbuf *, int);
static int hn_create_tx_ring(struct hn_softc *, int);
static void hn_destroy_tx_ring(struct hn_tx_ring *);
@@ -427,6 +430,8 @@ netvsc_probe(device_t dev)
static int
netvsc_attach(device_t dev)
{
+ struct sysctl_oid_list *child;
+ struct sysctl_ctx_list *ctx;
netvsc_device_info device_info;
hn_softc_t *sc;
int unit = device_get_unit(dev);
@@ -581,7 +586,7 @@ netvsc_attach(device_t dev)
}
#endif
- if (device_info.link_state == 0) {
+ if (device_info.link_state == NDIS_MEDIA_STATE_CONNECTED) {
sc->hn_carrier = 1;
}
@@ -608,9 +613,13 @@ netvsc_attach(device_t dev)
hn_tx_chimney_size < sc->hn_chim_szmax)
hn_set_chim_size(sc, hn_tx_chimney_size);
- SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- "nvs_version", CTLFLAG_RD, &sc->hn_nvs_ver, 0, "NVS version");
+ ctx = device_get_sysctl_ctx(dev);
+ child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+ SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
+ &sc->hn_nvs_ver, 0, "NVS version");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+ hn_ndis_version_sysctl, "A", "NDIS version");
return (0);
failed:
@@ -2094,6 +2103,18 @@ hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS)
}
static int
+hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hn_softc *sc = arg1;
+ char verstr[16];
+
+ snprintf(verstr, sizeof(verstr), "%u.%u",
+ NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
+ NDIS_VERSION_MINOR(sc->hn_ndis_ver));
+ return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
+}
+
+static int
hn_check_iplen(const struct mbuf *m, int hoff)
{
const struct ip *ip;
diff --git a/sys/dev/hyperv/netvsc/hv_rndis.h b/sys/dev/hyperv/netvsc/hv_rndis.h
index ce582e8..a5e28f1 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis.h
@@ -42,11 +42,8 @@
#define NDIS_VERSION_6_1 0x00060001
#define NDIS_VERSION_6_30 0x0006001e
-#define NDIS_VERSION_MAJOR_6 6
-#define NDIS_VERSION_MINOR_1 1
-#define NDIS_VERSION_MINOR_30 30
-
-#define NDIS_VERSION (NDIS_VERSION_5_1)
+#define NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16)
+#define NDIS_VERSION_MINOR(ver) ((ver) & 0xffff)
/*
* Object Identifiers used by NdisRequest Query/Set Information
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index 59e9cea..ae44243 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -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
@@ -96,6 +97,11 @@ static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
struct hn_softc *sc, struct vmbus_channel *chan,
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)
@@ -695,13 +701,23 @@ cleanup:
/*
* RNDIS filter query device MAC address
*/
-static inline int
+static int
hv_rf_query_device_mac(rndis_device *device)
{
- uint32_t size = ETHER_ADDR_LEN;
+ struct hn_softc *sc = device->sc;
+ size_t hwaddr_len;
+ int error;
- return (hv_rf_query_device(device,
- RNDIS_OID_802_3_PERMANENT_ADDRESS, device->hw_mac_addr, &size));
+ hwaddr_len = ETHER_ADDR_LEN;
+ error = hn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0,
+ device->hw_mac_addr, &hwaddr_len);
+ if (error)
+ return error;
+ if (hwaddr_len != ETHER_ADDR_LEN) {
+ if_printf(sc->hn_ifp, "invalid hwaddr len %zu\n", hwaddr_len);
+ return EINVAL;
+ }
+ return 0;
}
/*
@@ -892,12 +908,12 @@ exit:
static const void *
hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid,
- size_t reqlen, size_t min_complen, uint32_t comp_type)
+ size_t reqlen, size_t *comp_len0, uint32_t comp_type)
{
struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
const struct rndis_comp_hdr *comp;
bus_addr_t paddr;
- size_t comp_len;
+ size_t comp_len, min_complen = *comp_len0;
int gpa_cnt, error;
KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
@@ -946,7 +962,14 @@ hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid
* Check this RNDIS complete message.
*/
if (comp_len < min_complen) {
- if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n", comp_len);
+ if (comp_len >= sizeof(*comp)) {
+ /* rm_status field is valid */
+ if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu, "
+ "status 0x%08x\n", comp_len, comp->rm_status);
+ } else {
+ if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n",
+ comp_len);
+ }
return (NULL);
}
if (comp->rm_len < min_complen) {
@@ -965,9 +988,190 @@ hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid
return (NULL);
}
/* All pass! */
+ *comp_len0 = comp_len;
return (comp);
}
+static int
+hn_rndis_query(struct hn_softc *sc, uint32_t oid,
+ const void *idata, size_t idlen, void *odata, size_t *odlen0)
+{
+ struct rndis_query_req *req;
+ const struct rndis_query_comp *comp;
+ struct vmbus_xact *xact;
+ size_t reqlen, odlen = *odlen0, comp_len;
+ int error, ofs;
+ uint32_t rid;
+
+ 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 0x%08x\n", oid);
+ return (ENXIO);
+ }
+ rid = hn_rndis_rid(sc);
+ req = vmbus_xact_req_data(xact);
+ req->rm_type = REMOTE_NDIS_QUERY_MSG;
+ req->rm_len = reqlen;
+ req->rm_rid = rid;
+ req->rm_oid = oid;
+ /*
+ * XXX
+ * This is _not_ RNDIS Spec conforming:
+ * "This MUST be set to 0 when there is no input data
+ * associated with the OID."
+ *
+ * If this field was set to 0 according to the RNDIS Spec,
+ * Hyper-V would set non-SUCCESS status in the query
+ * completion.
+ */
+ req->rm_infobufoffset = RNDIS_QUERY_REQ_INFOBUFOFFSET;
+
+ if (idlen > 0) {
+ req->rm_infobuflen = idlen;
+ /* Input data immediately follows RNDIS query. */
+ memcpy(req + 1, idata, idlen);
+ }
+
+ comp_len = sizeof(*comp) + odlen;
+ comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len,
+ REMOTE_NDIS_QUERY_CMPLT);
+ if (comp == NULL) {
+ if_printf(sc->hn_ifp, "exec RNDIS query 0x%08x failed\n", oid);
+ error = EIO;
+ goto done;
+ }
+
+ if (comp->rm_status != RNDIS_STATUS_SUCCESS) {
+ if_printf(sc->hn_ifp, "RNDIS query 0x%08x failed: "
+ "status 0x%08x\n", oid, comp->rm_status);
+ error = EIO;
+ goto done;
+ }
+ if (comp->rm_infobuflen == 0 || comp->rm_infobufoffset == 0) {
+ /* No output data! */
+ if_printf(sc->hn_ifp, "RNDIS query 0x%08x, no data\n", oid);
+ *odlen0 = 0;
+ error = 0;
+ goto done;
+ }
+
+ /*
+ * Check output data length and offset.
+ */
+ /* ofs is the offset from the beginning of comp. */
+ ofs = RNDIS_QUERY_COMP_INFOBUFABS(comp->rm_infobufoffset);
+ if (ofs < sizeof(*comp) || ofs + comp->rm_infobuflen > comp_len) {
+ if_printf(sc->hn_ifp, "RNDIS query invalid comp ib off/len, "
+ "%u/%u\n", comp->rm_infobufoffset, comp->rm_infobuflen);
+ error = EINVAL;
+ goto done;
+ }
+
+ /*
+ * Save output data.
+ */
+ if (comp->rm_infobuflen < odlen)
+ odlen = comp->rm_infobuflen;
+ memcpy(odata, ((const uint8_t *)comp) + ofs, odlen);
+ *odlen0 = odlen;
+
+ error = 0;
+done:
+ vmbus_xact_put(xact);
+ 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(&params, 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, &params, 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
*/
@@ -978,6 +1182,7 @@ hv_rf_init_device(rndis_device *device)
struct rndis_init_req *req;
const struct rndis_init_comp *comp;
struct vmbus_xact *xact;
+ size_t comp_len;
uint32_t rid;
int error;
@@ -998,8 +1203,9 @@ hv_rf_init_device(rndis_device *device)
req->rm_ver_minor = RNDIS_VERSION_MINOR;
req->rm_max_xfersz = HN_RNDIS_XFER_SIZE;
- comp = hn_rndis_xact_execute(sc, xact, rid, sizeof(*req),
- RNDIS_INIT_COMP_SIZE_MIN, REMOTE_NDIS_INITIALIZE_CMPLT);
+ comp_len = RNDIS_INIT_COMP_SIZE_MIN;
+ comp = hn_rndis_xact_execute(sc, xact, rid, sizeof(*req), &comp_len,
+ REMOTE_NDIS_INITIALIZE_CMPLT);
if (comp == NULL) {
if_printf(sc->hn_ifp, "exec RNDIS init failed\n");
error = EIO;
@@ -1131,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;
@@ -1181,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);
diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h
new file mode 100644
index 0000000..10e0af2
--- /dev/null
+++ b/sys/dev/hyperv/netvsc/ndis.h
@@ -0,0 +1,121 @@
+/*-
+ * 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 NDIS_MEDIA_STATE_CONNECTED 0
+#define NDIS_MEDIA_STATE_DISCONNECTED 1
+
+#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_ */
diff --git a/sys/net/rndis.h b/sys/net/rndis.h
index 52ec660..5dd1d91 100644
--- a/sys/net/rndis.h
+++ b/sys/net/rndis.h
@@ -172,6 +172,10 @@ struct rndis_query_req {
uint32_t rm_devicevchdl;
};
+#define RNDIS_QUERY_REQ_INFOBUFOFFSET \
+ (sizeof(struct rndis_query_req) - \
+ __offsetof(struct rndis_query_req, rm_rid))
+
struct rndis_query_comp {
uint32_t rm_type;
uint32_t rm_len;
@@ -181,6 +185,9 @@ struct rndis_query_comp {
uint32_t rm_infobufoffset;
};
+#define RNDIS_QUERY_COMP_INFOBUFABS(ofs) \
+ ((ofs) + __offsetof(struct rndis_query_req, rm_rid))
+
/* Send a set object request. */
#define REMOTE_NDIS_SET_MSG 0x00000005
#define REMOTE_NDIS_SET_CMPLT 0x80000005
@@ -195,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;
OpenPOWER on IntegriCloud