Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143587418
D7457.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D7457.diff
View Options
Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1243,6 +1243,7 @@
struct taskqueue *hn_tx_taskq;
struct sysctl_oid *hn_tx_sysctl_tree;
struct sysctl_oid *hn_rx_sysctl_tree;
+ struct vmbus_xact_ctx *hn_xact;
} hn_softc_t;
/*
Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -45,9 +45,11 @@
#include <machine/atomic.h>
#include <dev/hyperv/include/hyperv.h>
-#include "hv_net_vsc.h"
-#include "hv_rndis.h"
-#include "hv_rndis_filter.h"
+#include <dev/hyperv/include/vmbus_xact.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/if_hnreg.h>
MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
@@ -70,7 +72,10 @@
const struct vmbus_chanpkt_hdr *pkt);
static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
- const struct nvsp_msg_ *msg);
+ const struct nvsp_msg_ *msg, int);
+static void hn_nvs_sent_xact(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg, int dlen);
static struct hn_send_ctx hn_send_ctx_none =
HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@@ -462,45 +467,64 @@
return (ret);
}
-
-/*
- * Attempt to negotiate the caller-specified NVSP version
- *
- * For NVSP v2, Server 2008 R2 does not set
- * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
- * to the negotiated version, so we cannot rely on that.
- */
static int
hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
- uint32_t nvsp_ver)
+ uint32_t nvs_ver)
{
struct hn_send_ctx sndc;
- nvsp_msg *init_pkt;
- int ret;
-
- init_pkt = &net_dev->channel_init_packet;
- memset(init_pkt, 0, sizeof(nvsp_msg));
- init_pkt->hdr.msg_type = nvsp_msg_type_init;
+ struct vmbus_xact *xact;
+ struct hn_nvs_init *init;
+ const struct hn_nvs_init_resp *resp;
+ size_t resp_len;
+ uint32_t status;
+ int error;
+
+ xact = vmbus_xact_get(sc->hn_xact, sizeof(*init));
+ if (xact == NULL) {
+ if_printf(sc->hn_ifp, "no xact for nvs init\n");
+ return (ENXIO);
+ }
+
+ init = vmbus_xact_req_data(xact);
+ init->nvs_type = HN_NVS_TYPE_INIT;
+ init->nvs_ver_min = nvs_ver;
+ init->nvs_ver_max = nvs_ver;
- /*
- * Specify parameter as the only acceptable protocol version
- */
- init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
- init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
+ vmbus_xact_activate(xact);
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- /* Send the init request */
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
- ret = vmbus_chan_send(sc->hn_prichan,
+ error = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
- if (ret != 0)
- return (-1);
-
- sema_wait(&net_dev->channel_init_sema);
+ init, sizeof(*init), (uint64_t)(uintptr_t)&sndc);
+ if (error) {
+ if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
+ vmbus_xact_deactivate(xact);
+ vmbus_xact_put(xact);
+ return (error);
+ }
- if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
+ resp = vmbus_xact_wait(xact, &resp_len);
+ if (resp_len < sizeof(*resp)) {
+ if_printf(sc->hn_ifp, "invalid init resp length %zu\n",
+ resp_len);
+ vmbus_xact_put(xact);
return (EINVAL);
+ }
+ if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) {
+ if_printf(sc->hn_ifp, "not init resp, type %u\n",
+ resp->nvs_type);
+ vmbus_xact_put(xact);
+ return (EINVAL);
+ }
+
+ status = resp->nvs_status;
+ vmbus_xact_put(xact);
+ if (status != HN_NVS_STATUS_OK) {
+ if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n",
+ nvs_ver);
+ return (EINVAL);
+ }
return (0);
}
@@ -744,7 +768,7 @@
void
hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
- const struct nvsp_msg_ *msg)
+ const struct nvsp_msg_ *msg, int dlen __unused)
{
/* Copy the response back */
memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
@@ -752,9 +776,18 @@
}
static void
+hn_nvs_sent_xact(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
+ const struct nvsp_msg_ *msg, int dlen)
+{
+
+ vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen);
+}
+
+static void
hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
- const struct nvsp_msg_ *msg __unused)
+ const struct nvsp_msg_ *msg __unused, int dlen __unused)
{
/* EMPTY */
}
@@ -788,7 +821,8 @@
struct hn_send_ctx *sndc;
sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
- sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt));
+ sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt),
+ VMBUS_CHANPKT_DATALEN(pkt));
/*
* NOTE:
* 'sndc' CAN NOT be accessed anymore, since it can be freed by
Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -115,6 +115,7 @@
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus_xact.h>
#include "hv_net_vsc.h"
#include "hv_rndis.h"
@@ -124,6 +125,9 @@
/* Short for Hyper-V network interface */
#define NETVSC_DEVNAME "hn"
+#define HN_XACT_REQ_SIZE (2 * PAGE_SIZE)
+#define HN_XACT_RESP_SIZE (2 * PAGE_SIZE)
+
/*
* It looks like offset 0 of buf is reserved to hold the softc pointer.
* The sc pointer evidently not needed, and is not presently populated.
@@ -542,6 +546,11 @@
IFCAP_LRO;
ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO;
+ sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev),
+ HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE);
+ if (sc->hn_xact == NULL)
+ goto failed;
+
error = hv_rf_on_device_add(sc, &device_info, ring_cnt,
&sc->hn_rx_ring[0]);
if (error)
@@ -643,6 +652,7 @@
if (sc->hn_tx_taskq != hn_tx_taskq)
taskqueue_free(sc->hn_tx_taskq);
+ vmbus_xact_ctx_destroy(sc->hn_xact);
return (0);
}
@@ -782,7 +792,8 @@
static void
hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
- struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused)
+ struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused,
+ int dlen __unused)
{
struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
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
@@ -91,10 +91,10 @@
static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
- const struct nvsp_msg_ *msg);
+ const struct nvsp_msg_ *msg, int dlen);
static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
- const struct nvsp_msg_ *msg);
+ const struct nvsp_msg_ *msg, int dlen);
/*
* Set the Per-Packet-Info with the specified type
@@ -1239,7 +1239,8 @@
static void
hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
- struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused,
+ int dlen __unused)
{
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
hn_chim_free(net_dev, sndc->hn_chim_idx);
@@ -1247,7 +1248,8 @@
static void
hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
- struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused,
+ int dlen __unused)
{
rndis_request *request = sndc->hn_cbarg;
Index: head/sys/dev/hyperv/netvsc/if_hnreg.h
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hnreg.h
+++ head/sys/dev/hyperv/netvsc/if_hnreg.h
@@ -0,0 +1,62 @@
+/*-
+ * 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 _IF_HNREG_H_
+#define _IF_HNREG_H_
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#define HN_NVS_STATUS_OK 1
+
+#define HN_NVS_TYPE_INIT 1
+#define HN_NVS_TYPE_INIT_RESP 2
+
+/*
+ * Any size less than this one will _not_ work, e.g. hn_nvs_init
+ * only has 12B valid data, however, if only 12B data were sent,
+ * Hypervisor would never reply.
+ */
+#define HN_NVS_REQSIZE_MIN 32
+
+struct hn_nvs_init {
+ uint32_t nvs_type; /* HN_NVS_TYPE_INIT */
+ uint32_t nvs_ver_min;
+ uint32_t nvs_ver_max;
+ uint8_t nvs_rsvd[20];
+} __packed;
+CTASSERT(sizeof(struct hn_nvs_init) >= HN_NVS_REQSIZE_MIN);
+
+struct hn_nvs_init_resp {
+ uint32_t nvs_type; /* HN_NVS_TYPE_INIT_RESP */
+ uint32_t nvs_ver; /* deprecated */
+ uint32_t nvs_rsvd;
+ uint32_t nvs_status; /* HN_NVS_STATUS_ */
+} __packed;
+
+#endif /* !_IF_HNREG_H_ */
Index: head/sys/dev/hyperv/netvsc/if_hnvar.h
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -40,7 +40,7 @@
typedef void (*hn_sent_callback_t)
(struct hn_send_ctx *, struct netvsc_dev_ *,
- struct vmbus_channel *, const struct nvsp_msg_ *);
+ struct vmbus_channel *, const struct nvsp_msg_ *, int);
struct hn_send_ctx {
hn_sent_callback_t hn_cb;
@@ -77,7 +77,7 @@
void hn_nvs_sent_wakeup(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
- const struct nvsp_msg_ *msg);
+ const struct nvsp_msg_ *msg, int dlen);
void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx);
#endif /* !_IF_HNVAR_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 1, 12:09 AM (3 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28223918
Default Alt Text
D7457.diff (11 KB)
Attached To
Mode
D7457: hyperv/hn: Switch to vmbus xact APIs for NVS initialization
Attached
Detach File
Event Timeline
Log In to Comment