svn commit: r303948 - head/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Aug 11 06:14:56 UTC 2016
Author: sephe
Date: Thu Aug 11 06:14:54 2016
New Revision: 303948
URL: https://svnweb.freebsd.org/changeset/base/303948
Log:
hyperv/hn: Switch to vmbus xact APIs for NVS initialization
Reviewed by: Jun Su <junsu microsoft com>
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7457
Added:
head/sys/dev/hyperv/netvsc/if_hnreg.h (contents, props changed)
Modified:
head/sys/dev/hyperv/netvsc/hv_net_vsc.c
head/sys/dev/hyperv/netvsc/hv_net_vsc.h
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
head/sys/dev/hyperv/netvsc/if_hnvar.h
Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Aug 11 05:49:49 2016 (r303947)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Aug 11 06:14:54 2016 (r303948)
@@ -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 @@ static void hv_nv_on_receive(netvsc_dev
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 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne
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 @@ hv_nv_on_device_remove(struct hn_softc *
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 @@ hn_nvs_sent_wakeup(struct hn_send_ctx *s
}
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 @@ hv_nv_on_send_completion(netvsc_dev *net
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
Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Aug 11 05:49:49 2016 (r303947)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Aug 11 06:14:54 2016 (r303948)
@@ -1243,6 +1243,7 @@ typedef struct hn_softc {
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;
/*
Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Aug 11 05:49:49 2016 (r303947)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Aug 11 06:14:54 2016 (r303948)
@@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
#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 @@ __FBSDID("$FreeBSD$");
/* 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 @@ netvsc_attach(device_t dev)
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 @@ netvsc_detach(device_t dev)
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 @@ hn_txeof(struct hn_tx_ring *txr)
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;
Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Aug 11 05:49:49 2016 (r303947)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Aug 11 06:14:54 2016 (r303948)
@@ -91,10 +91,10 @@ hv_rf_send_offload_request(struct hn_sof
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 @@ hv_rf_on_close(struct hn_softc *sc)
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 @@ hn_rndis_sent_cb(struct hn_send_ctx *snd
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;
Added: head/sys/dev/hyperv/netvsc/if_hnreg.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/hyperv/netvsc/if_hnreg.h Thu Aug 11 06:14:54 2016 (r303948)
@@ -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_ */
Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h Thu Aug 11 05:49:49 2016 (r303947)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h Thu Aug 11 06:14:54 2016 (r303948)
@@ -40,7 +40,7 @@ struct hn_send_ctx;
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 @@ hn_send_ctx_init_simple(struct hn_send_c
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_ */
More information about the svn-src-head
mailing list