summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-10-17 06:09:36 +0000
committersephe <sephe@FreeBSD.org>2016-10-17 06:09:36 +0000
commit18a16f0687ce2b7b01a11550539cfd2c74a02f89 (patch)
tree02a3c4c89e9ee9dae4c0b781e50e1f92a279305b
parent8805b157602c7a0963d947649e1c61b2ff537024 (diff)
downloadFreeBSD-src-18a16f0687ce2b7b01a11550539cfd2c74a02f89.zip
FreeBSD-src-18a16f0687ce2b7b01a11550539cfd2c74a02f89.tar.gz
MFC 304204-304206,304252-304256
304204 hyperv/hn: Factor out hn_nvs_send/hn_nvs_send_sglist Avoid unnecessary message type setting and centralize the send context to transaction id cast. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7500 304205 hyperv/hn: Simplify RNDIS NVS message sending. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7501 304206 hyperv/hn: Simplify RNDIS message checks on RX path. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7502 304252 hyperv/hn: Ignore the useless TX table. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7514 304253 hyperv/hn: Simplify RNDIS RX packets acknowledgement. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7515 304254 hyperv/hn: Remove reference to nvsp_msg Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7516 304255 hyperv/hn: Remove reference to nvsp_status Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7517 304256 hyperv/hn: Get rid of unused bits Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7518
-rw-r--r--sys/dev/hyperv/include/vmbus.h1
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c161
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h838
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c14
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c34
-rw-r--r--sys/dev/hyperv/netvsc/if_hnreg.h46
-rw-r--r--sys/dev/hyperv/netvsc/if_hnvar.h43
7 files changed, 161 insertions, 976 deletions
diff --git a/sys/dev/hyperv/include/vmbus.h b/sys/dev/hyperv/include/vmbus.h
index 0a16e6e..5843f03 100644
--- a/sys/dev/hyperv/include/vmbus.h
+++ b/sys/dev/hyperv/include/vmbus.h
@@ -83,6 +83,7 @@ struct vmbus_chanpkt_hdr {
#define VMBUS_CHANPKT_TYPE_GPA 0x0009
#define VMBUS_CHANPKT_TYPE_COMP 0x000b
+#define VMBUS_CHANPKT_FLAG_NONE 0
#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
#define VMBUS_CHANPKT_CONST_DATA(pkt) \
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index 2288d84..65c4e6d 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -72,7 +72,7 @@ static void hv_nv_on_receive(netvsc_dev *net_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, int);
+ const void *, int);
static struct hn_send_ctx hn_send_ctx_none =
HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@@ -118,7 +118,7 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
unsigned long bitsmap_words = net_dev->bitsmap_words;
unsigned long *bitsmap = net_dev->send_section_bitsmap;
unsigned long idx;
- int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ int ret = HN_NVS_CHIM_IDX_INVALID;
int i;
for (i = 0; i < bitsmap_words; i++) {
@@ -206,9 +206,8 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
- error = vmbus_chan_send(sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- conn, sizeof(*conn), (uint64_t)(uintptr_t)&sndc);
+ error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
+ conn, sizeof(*conn), &sndc);
if (error != 0) {
if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n",
error);
@@ -313,9 +312,8 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
- error = vmbus_chan_send(sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- chim, sizeof(*chim), (uint64_t)(uintptr_t)&sndc);
+ error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
+ chim, sizeof(*chim), &sndc);
if (error) {
if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n",
error);
@@ -393,9 +391,10 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN;
disconn.nvs_sig = HN_NVS_RXBUF_SIG;
- ret = vmbus_chan_send(net_dev->sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn),
- (uint64_t)(uintptr_t)&hn_send_ctx_none);
+ /* NOTE: No response. */
+ ret = hn_nvs_send(net_dev->sc->hn_prichan,
+ VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
+ &hn_send_ctx_none);
if (ret != 0) {
if_printf(net_dev->sc->hn_ifp,
"send rxbuf disconn failed: %d\n", ret);
@@ -445,9 +444,10 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN;
disconn.nvs_sig = HN_NVS_CHIM_SIG;
- ret = vmbus_chan_send(net_dev->sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn),
- (uint64_t)(uintptr_t)&hn_send_ctx_none);
+ /* NOTE: No response. */
+ ret = hn_nvs_send(net_dev->sc->hn_prichan,
+ VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
+ &hn_send_ctx_none);
if (ret != 0) {
if_printf(net_dev->sc->hn_ifp,
"send chim disconn failed: %d\n", ret);
@@ -509,9 +509,8 @@ hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
vmbus_xact_activate(xact);
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- error = vmbus_chan_send(sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init, sizeof(*init), (uint64_t)(uintptr_t)&sndc);
+ error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
+ init, sizeof(*init), &sndc);
if (error) {
if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
vmbus_xact_deactivate(xact);
@@ -560,8 +559,9 @@ hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
conf.nvs_mtu = mtu;
conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
- error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- &conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none);
+ /* NOTE: No response. */
+ error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
+ &conf, sizeof(conf), &hn_send_ctx_none);
if (error)
if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error);
return (error);
@@ -627,8 +627,9 @@ hv_nv_connect_to_vsp(struct hn_softc *sc)
else
ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30;
- ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- &ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none);
+ /* NOTE: No response. */
+ ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
+ &ndis, sizeof(ndis), &hn_send_ctx_none);
if (ret != 0) {
if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret);
goto cleanup;
@@ -689,8 +690,6 @@ hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
/* Initialize the NetVSC channel extension */
- sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
-
/*
* Open the channel
*/
@@ -721,7 +720,6 @@ cleanup:
* Free the packet buffers on the netvsc device packet queue.
* Release other resources.
*/
- sema_destroy(&net_dev->channel_init_sema);
free(net_dev, M_NETVSC);
return (NULL);
@@ -746,7 +744,6 @@ hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
vmbus_chan_close(sc->hn_prichan);
- sema_destroy(&net_dev->channel_init_sema);
free(net_dev, M_NETVSC);
return (0);
@@ -755,16 +752,16 @@ hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
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)
+ const void *data, int dlen)
{
- vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen);
+ vmbus_xact_wakeup(sndc->hn_cbarg, data, 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, int dlen __unused)
+ const void *data __unused, int dlen __unused)
{
/* EMPTY */
}
@@ -813,33 +810,23 @@ hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
* Returns 0 on success, non-zero on failure.
*/
int
-hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
{
- nvsp_msg send_msg;
+ struct hn_nvs_rndis rndis;
int ret;
- send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
- if (is_data_pkt) {
- /* 0 is RMC_DATA */
- send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
- } else {
- /* 1 is RMC_CONTROL */
- send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
- }
-
- send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
- sndc->hn_chim_idx;
- send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
- sndc->hn_chim_sz;
+ rndis.nvs_type = HN_NVS_TYPE_RNDIS;
+ rndis.nvs_rndis_mtype = rndis_mtype;
+ rndis.nvs_chim_idx = sndc->hn_chim_idx;
+ rndis.nvs_chim_sz = sndc->hn_chim_sz;
if (gpa_cnt) {
- ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
+ ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
+ &rndis, sizeof(rndis), sndc);
} else {
- ret = vmbus_chan_send(chan,
- VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
+ ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
+ &rndis, sizeof(rndis), sndc);
}
return (ret);
@@ -856,19 +843,18 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
{
const struct vmbus_chanpkt_rxbuf *pkt;
- const nvsp_msg *nvsp_msg_pkt;
+ const struct hn_nvs_hdr *nvs_hdr;
netvsc_packet vsc_pkt;
netvsc_packet *net_vsc_pkt = &vsc_pkt;
int count = 0;
int i = 0;
- int status = nvsp_status_success;
-
- nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
+ int status = HN_NVS_STATUS_OK;
- /* Make sure this is a valid nvsp packet */
- if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
- if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
- nvsp_msg_pkt->hdr.msg_type);
+ /* Make sure that this is a RNDIS message. */
+ nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
+ if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) {
+ if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n",
+ nvs_hdr->nvs_type);
return;
}
@@ -884,15 +870,16 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
for (i = 0; i < count; i++) {
- net_vsc_pkt->status = nvsp_status_success;
+ net_vsc_pkt->status = HN_NVS_STATUS_OK;
net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
pkt->cp_rxbuf[i].rb_ofs);
net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
- if (net_vsc_pkt->status != nvsp_status_success) {
- status = nvsp_status_failure;
- }
+
+ /* XXX pretty broken; whack it */
+ if (net_vsc_pkt->status != HN_NVS_STATUS_OK)
+ status = HN_NVS_STATUS_FAILED;
}
/*
@@ -912,20 +899,17 @@ static void
hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
uint32_t status)
{
- nvsp_msg rx_comp_msg;
+ struct hn_nvs_rndis_ack ack;
int retries = 0;
int ret = 0;
- rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
-
- /* Pass in the status */
- rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
- status;
+ ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
+ ack.nvs_status = status;
retry_send_cmplt:
/* Send the completion */
- ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0,
- &rx_comp_msg, sizeof(nvsp_msg), tid);
+ ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
+ VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid);
if (ret == 0) {
/* success */
/* no-op */
@@ -940,44 +924,17 @@ retry_send_cmplt:
}
}
-/*
- * Net VSC receiving vRSS send table from VSP
- */
static void
-hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
+hn_proc_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
{
- netvsc_dev *net_dev;
- const nvsp_msg *nvsp_msg_pkt;
- int i;
- uint32_t count;
- const uint32_t *table;
-
- net_dev = hv_nv_get_inbound_net_device(sc);
- if (!net_dev)
- return;
-
- nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
+ const struct hn_nvs_hdr *hdr;
- if (nvsp_msg_pkt->hdr.msg_type !=
- nvsp_msg5_type_send_indirection_table) {
- printf("Netvsc: !Warning! receive msg type not "
- "send_indirection_table. type = %d\n",
- nvsp_msg_pkt->hdr.msg_type);
+ hdr = VMBUS_CHANPKT_CONST_DATA(pkt);
+ if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) {
+ /* Useless; ignore */
return;
}
-
- count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
- if (count != VRSS_SEND_TABLE_SIZE) {
- printf("Netvsc: Received wrong send table size: %u\n", count);
- return;
- }
-
- table = (const uint32_t *)
- ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
- nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
-
- for (i = 0; i < count; i++)
- net_dev->vrss_send_table[i] = table[i];
+ if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type);
}
/*
@@ -1015,7 +972,7 @@ hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
hv_nv_on_receive(net_dev, rxr, chan, pkt);
break;
case VMBUS_CHANPKT_TYPE_INBAND:
- hv_nv_send_table(sc, pkt);
+ hn_proc_notify(sc, pkt);
break;
default:
if_printf(rxr->hn_ifp,
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index a861c3e..e80146e 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -177,834 +177,6 @@ typedef struct rndis_recv_scale_param_ {
uint32_t processor_masks_entry_size;
} rndis_recv_scale_param;
-typedef enum nvsp_msg_type_ {
- nvsp_msg_type_none = 0,
-
- /*
- * Init Messages
- */
- nvsp_msg_type_init = 1,
- nvsp_msg_type_init_complete = 2,
-
- nvsp_version_msg_start = 100,
-
- /*
- * Version 1 Messages
- */
- nvsp_msg_1_type_send_ndis_vers = nvsp_version_msg_start,
-
- nvsp_msg_1_type_send_rx_buf,
- nvsp_msg_1_type_send_rx_buf_complete,
- nvsp_msg_1_type_revoke_rx_buf,
-
- nvsp_msg_1_type_send_send_buf,
- nvsp_msg_1_type_send_send_buf_complete,
- nvsp_msg_1_type_revoke_send_buf,
-
- nvsp_msg_1_type_send_rndis_pkt,
- nvsp_msg_1_type_send_rndis_pkt_complete,
-
- /*
- * Version 2 Messages
- */
- nvsp_msg_2_type_send_chimney_delegated_buf,
- nvsp_msg_2_type_send_chimney_delegated_buf_complete,
- nvsp_msg_2_type_revoke_chimney_delegated_buf,
-
- nvsp_msg_2_type_resume_chimney_rx_indication,
-
- nvsp_msg_2_type_terminate_chimney,
- nvsp_msg_2_type_terminate_chimney_complete,
-
- nvsp_msg_2_type_indicate_chimney_event,
-
- nvsp_msg_2_type_send_chimney_packet,
- nvsp_msg_2_type_send_chimney_packet_complete,
-
- nvsp_msg_2_type_post_chimney_rx_request,
- nvsp_msg_2_type_post_chimney_rx_request_complete,
-
- nvsp_msg_2_type_alloc_rx_buf,
- nvsp_msg_2_type_alloc_rx_buf_complete,
-
- nvsp_msg_2_type_free_rx_buf,
-
- nvsp_msg_2_send_vmq_rndis_pkt,
- nvsp_msg_2_send_vmq_rndis_pkt_complete,
-
- nvsp_msg_2_type_send_ndis_config,
-
- nvsp_msg_2_type_alloc_chimney_handle,
- nvsp_msg_2_type_alloc_chimney_handle_complete,
-
- nvsp_msg2_max = nvsp_msg_2_type_alloc_chimney_handle_complete,
-
- /*
- * Version 4 Messages
- */
- nvsp_msg4_type_send_vf_association,
- nvsp_msg4_type_switch_data_path,
- nvsp_msg4_type_uplink_connect_state_deprecated,
-
- nvsp_msg4_max = nvsp_msg4_type_uplink_connect_state_deprecated,
-
- /*
- * Version 5 Messages
- */
- nvsp_msg5_type_oid_query_ex,
- nvsp_msg5_type_oid_query_ex_comp,
- nvsp_msg5_type_subchannel,
- nvsp_msg5_type_send_indirection_table,
-
- nvsp_msg5_max = nvsp_msg5_type_send_indirection_table,
-} nvsp_msg_type;
-
-typedef enum nvsp_status_ {
- nvsp_status_none = 0,
- nvsp_status_success,
- nvsp_status_failure,
- /* Deprecated */
- nvsp_status_prot_vers_range_too_new,
- /* Deprecated */
- nvsp_status_prot_vers_range_too_old,
- nvsp_status_invalid_rndis_pkt,
- nvsp_status_busy,
- nvsp_status_max,
-} nvsp_status;
-
-typedef struct nvsp_msg_hdr_ {
- uint32_t msg_type;
-} __packed nvsp_msg_hdr;
-
-/*
- * Init Messages
- */
-
-/*
- * This message is used by the VSC to initialize the channel
- * after the channels has been opened. This message should
- * never include anything other then versioning (i.e. this
- * message will be the same for ever).
- *
- * Forever is a long time. The values have been redefined
- * in Win7 to indicate major and minor protocol version
- * number.
- */
-typedef struct nvsp_msg_init_ {
- union {
- struct {
- uint16_t minor_protocol_version;
- uint16_t major_protocol_version;
- } s;
- /* Formerly min_protocol_version */
- uint32_t protocol_version;
- } p1;
- /* Formerly max_protocol_version */
- uint32_t protocol_version_2;
-} __packed nvsp_msg_init;
-
-/*
- * This message is used by the VSP to complete the initialization
- * of the channel. This message should never include anything other
- * then versioning (i.e. this message will be the same forever).
- */
-typedef struct nvsp_msg_init_complete_ {
- /* Deprecated */
- uint32_t negotiated_prot_vers;
- uint32_t max_mdl_chain_len;
- uint32_t status;
-} __packed nvsp_msg_init_complete;
-
-typedef union nvsp_msg_init_uber_ {
- nvsp_msg_init init;
- nvsp_msg_init_complete init_compl;
-} __packed nvsp_msg_init_uber;
-
-/*
- * Version 1 Messages
- */
-
-/*
- * This message is used by the VSC to send the NDIS version
- * to the VSP. The VSP can use this information when handling
- * OIDs sent by the VSC.
- */
-typedef struct nvsp_1_msg_send_ndis_version_ {
- uint32_t ndis_major_vers;
- /* Deprecated */
- uint32_t ndis_minor_vers;
-} __packed nvsp_1_msg_send_ndis_version;
-
-/*
- * This message is used by the VSC to send a receive buffer
- * to the VSP. The VSP can then use the receive buffer to
- * send data to the VSC.
- */
-typedef struct nvsp_1_msg_send_rx_buf_ {
- uint32_t gpadl_handle;
- uint16_t id;
-} __packed nvsp_1_msg_send_rx_buf;
-
-typedef struct nvsp_1_rx_buf_section_ {
- uint32_t offset;
- uint32_t sub_allocation_size;
- uint32_t num_sub_allocations;
- uint32_t end_offset;
-} __packed nvsp_1_rx_buf_section;
-
-/*
- * This message is used by the VSP to acknowledge a receive
- * buffer send by the VSC. This message must be sent by the
- * VSP before the VSP uses the receive buffer.
- */
-typedef struct nvsp_1_msg_send_rx_buf_complete_ {
- uint32_t status;
- uint32_t num_sections;
-
- /*
- * The receive buffer is split into two parts, a large
- * suballocation section and a small suballocation
- * section. These sections are then suballocated by a
- * certain size.
- *
- * For example, the following break up of the receive
- * buffer has 6 large suballocations and 10 small
- * suballocations.
- *
- * | Large Section | | Small Section |
- * ------------------------------------------------------------
- * | | | | | | | | | | | | | | | | | |
- * | |
- * LargeOffset SmallOffset
- */
- nvsp_1_rx_buf_section sections[1];
-
-} __packed nvsp_1_msg_send_rx_buf_complete;
-
-/*
- * This message is sent by the VSC to revoke the receive buffer.
- * After the VSP completes this transaction, the VSP should never
- * use the receive buffer again.
- */
-typedef struct nvsp_1_msg_revoke_rx_buf_ {
- uint16_t id;
-} __packed nvsp_1_msg_revoke_rx_buf;
-
-/*
- * This message is used by the VSC to send a send buffer
- * to the VSP. The VSC can then use the send buffer to
- * send data to the VSP.
- */
-typedef struct nvsp_1_msg_send_send_buf_ {
- uint32_t gpadl_handle;
- uint16_t id;
-} __packed nvsp_1_msg_send_send_buf;
-
-/*
- * This message is used by the VSP to acknowledge a send
- * buffer sent by the VSC. This message must be sent by the
- * VSP before the VSP uses the sent buffer.
- */
-typedef struct nvsp_1_msg_send_send_buf_complete_ {
- uint32_t status;
-
- /*
- * The VSC gets to choose the size of the send buffer and
- * the VSP gets to choose the sections size of the buffer.
- * This was done to enable dynamic reconfigurations when
- * the cost of GPA-direct buffers decreases.
- */
- uint32_t section_size;
-} __packed nvsp_1_msg_send_send_buf_complete;
-
-/*
- * This message is sent by the VSC to revoke the send buffer.
- * After the VSP completes this transaction, the vsp should never
- * use the send buffer again.
- */
-typedef struct nvsp_1_msg_revoke_send_buf_ {
- uint16_t id;
-} __packed nvsp_1_msg_revoke_send_buf;
-
-/*
- * This message is used by both the VSP and the VSC to send
- * an RNDIS message to the opposite channel endpoint.
- */
-typedef struct nvsp_1_msg_send_rndis_pkt_ {
- /*
- * This field is specified by RNIDS. They assume there's
- * two different channels of communication. However,
- * the Network VSP only has one. Therefore, the channel
- * travels with the RNDIS packet.
- */
- uint32_t chan_type;
-
- /*
- * This field is used to send part or all of the data
- * through a send buffer. This values specifies an
- * index into the send buffer. If the index is
- * 0xFFFFFFFF, then the send buffer is not being used
- * and all of the data was sent through other VMBus
- * mechanisms.
- */
- uint32_t send_buf_section_idx;
- uint32_t send_buf_section_size;
-} __packed nvsp_1_msg_send_rndis_pkt;
-
-/*
- * This message is used by both the VSP and the VSC to complete
- * a RNDIS message to the opposite channel endpoint. At this
- * point, the initiator of this message cannot use any resources
- * associated with the original RNDIS packet.
- */
-typedef struct nvsp_1_msg_send_rndis_pkt_complete_ {
- uint32_t status;
-} __packed nvsp_1_msg_send_rndis_pkt_complete;
-
-
-/*
- * Version 2 Messages
- */
-
-/*
- * This message is used by the VSC to send the NDIS version
- * to the VSP. The VSP can use this information when handling
- * OIDs sent by the VSC.
- */
-typedef struct nvsp_2_netvsc_capabilities_ {
- union {
- uint64_t as_uint64;
- struct {
- uint64_t vmq : 1;
- uint64_t chimney : 1;
- uint64_t sriov : 1;
- uint64_t ieee8021q : 1;
- uint64_t correlationid : 1;
- uint64_t teaming : 1;
- } u2;
- } u1;
-} __packed nvsp_2_netvsc_capabilities;
-
-typedef struct nvsp_2_msg_send_ndis_config_ {
- uint32_t mtu;
- uint32_t reserved;
- nvsp_2_netvsc_capabilities capabilities;
-} __packed nvsp_2_msg_send_ndis_config;
-
-/*
- * NvspMessage2TypeSendChimneyDelegatedBuffer
- */
-typedef struct nvsp_2_msg_send_chimney_buf_
-{
- /*
- * On WIN7 beta, delegated_obj_max_size is defined as a uint32_t
- * Since WIN7 RC, it was split into two uint16_t. To have the same
- * struct layout, delegated_obj_max_size shall be the first field.
- */
- uint16_t delegated_obj_max_size;
-
- /*
- * The revision # of chimney protocol used between NVSC and NVSP.
- *
- * This revision is NOT related to the chimney revision between
- * NDIS protocol and miniport drivers.
- */
- uint16_t revision;
-
- uint32_t gpadl_handle;
-} __packed nvsp_2_msg_send_chimney_buf;
-
-
-/* Unsupported chimney revision 0 (only present in WIN7 beta) */
-#define NVSP_CHIMNEY_REVISION_0 0
-
-/* WIN7 Beta Chimney QFE */
-#define NVSP_CHIMNEY_REVISION_1 1
-
-/* The chimney revision since WIN7 RC */
-#define NVSP_CHIMNEY_REVISION_2 2
-
-
-/*
- * NvspMessage2TypeSendChimneyDelegatedBufferComplete
- */
-typedef struct nvsp_2_msg_send_chimney_buf_complete_ {
- uint32_t status;
-
- /*
- * Maximum number outstanding sends and pre-posted receives.
- *
- * NVSC should not post more than SendQuota/ReceiveQuota packets.
- * Otherwise, it can block the non-chimney path for an indefinite
- * amount of time.
- * (since chimney sends/receives are affected by the remote peer).
- *
- * Note: NVSP enforces the quota restrictions on a per-VMBCHANNEL
- * basis. It doesn't enforce the restriction separately for chimney
- * send/receive. If NVSC doesn't voluntarily enforce "SendQuota",
- * it may kill its own network connectivity.
- */
- uint32_t send_quota;
- uint32_t rx_quota;
-} __packed nvsp_2_msg_send_chimney_buf_complete;
-
-/*
- * NvspMessage2TypeRevokeChimneyDelegatedBuffer
- */
-typedef struct nvsp_2_msg_revoke_chimney_buf_ {
- uint32_t gpadl_handle;
-} __packed nvsp_2_msg_revoke_chimney_buf;
-
-
-#define NVSP_CHIMNEY_OBJECT_TYPE_NEIGHBOR 0
-#define NVSP_CHIMNEY_OBJECT_TYPE_PATH4 1
-#define NVSP_CHIMNEY_OBJECT_TYPE_PATH6 2
-#define NVSP_CHIMNEY_OBJECT_TYPE_TCP 3
-
-/*
- * NvspMessage2TypeAllocateChimneyHandle
- */
-typedef struct nvsp_2_msg_alloc_chimney_handle_ {
- uint64_t vsc_context;
- uint32_t object_type;
-} __packed nvsp_2_msg_alloc_chimney_handle;
-
-/*
- * NvspMessage2TypeAllocateChimneyHandleComplete
- */
-typedef struct nvsp_2_msg_alloc_chimney_handle_complete_ {
- uint32_t vsp_handle;
-} __packed nvsp_2_msg_alloc_chimney_handle_complete;
-
-
-/*
- * NvspMessage2TypeResumeChimneyRXIndication
- */
-typedef struct nvsp_2_msg_resume_chimney_rx_indication {
- /*
- * Handle identifying the offloaded connection
- */
- uint32_t vsp_tcp_handle;
-} __packed nvsp_2_msg_resume_chimney_rx_indication;
-
-
-#define NVSP_2_MSG_TERMINATE_CHIMNEY_FLAGS_FIRST_STAGE (0x01u)
-#define NVSP_2_MSG_TERMINATE_CHIMNEY_FLAGS_RESERVED (~(0x01u))
-
-/*
- * NvspMessage2TypeTerminateChimney
- */
-typedef struct nvsp_2_msg_terminate_chimney_ {
- /*
- * Handle identifying the offloaded object
- */
- uint32_t vsp_handle;
-
- /*
- * Terminate Offload Flags
- * Bit 0:
- * When set to 0, terminate the offload at the destination NIC
- * Bit 1-31: Reserved, shall be zero
- */
- uint32_t flags;
-
- union {
- /*
- * This field is valid only when bit 0 of flags is clear.
- * It specifies the index into the premapped delegated
- * object buffer. The buffer was sent through the
- * NvspMessage2TypeSendChimneyDelegatedBuffer
- * message at initialization time.
- *
- * NVSP will write the delegated state into the delegated
- * buffer upon upload completion.
- */
- uint32_t index;
-
- /*
- * This field is valid only when bit 0 of flags is set.
- *
- * The seqence number of the most recently accepted RX
- * indication when VSC sets its TCP context into
- * "terminating" state.
- *
- * This allows NVSP to determines if there are any in-flight
- * RX indications for which the acceptance state is still
- * undefined.
- */
- uint64_t last_accepted_rx_seq_no;
- } f0;
-} __packed nvsp_2_msg_terminate_chimney;
-
-
-#define NVSP_TERMINATE_CHIMNEY_COMPLETE_FLAG_DATA_CORRUPTED 0x0000001u
-
-/*
- * NvspMessage2TypeTerminateChimneyComplete
- */
-typedef struct nvsp_2_msg_terminate_chimney_complete_ {
- uint64_t vsc_context;
- uint32_t flags;
-} __packed nvsp_2_msg_terminate_chimney_complete;
-
-/*
- * NvspMessage2TypeIndicateChimneyEvent
- */
-typedef struct nvsp_2_msg_indicate_chimney_event_ {
- /*
- * When VscTcpContext is 0, event_type is an NDIS_STATUS event code
- * Otherwise, EventType is an TCP connection event (defined in
- * NdisTcpOffloadEventHandler chimney DDK document).
- */
- uint32_t event_type;
-
- /*
- * When VscTcpContext is 0, EventType is an NDIS_STATUS event code
- * Otherwise, EventType is an TCP connection event specific information
- * (defined in NdisTcpOffloadEventHandler chimney DDK document).
- */
- uint32_t event_specific_info;
-
- /*
- * If not 0, the event is per-TCP connection event. This field
- * contains the VSC's TCP context.
- * If 0, the event indication is global.
- */
- uint64_t vsc_tcp_context;
-} __packed nvsp_2_msg_indicate_chimney_event;
-
-
-#define NVSP_1_CHIMNEY_SEND_INVALID_OOB_INDEX 0xffffu
-#define NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX 0xffffffff
-
-/*
- * NvspMessage2TypeSendChimneyPacket
- */
-typedef struct nvsp_2_msg_send_chimney_pkt_ {
- /*
- * Identify the TCP connection for which this chimney send is
- */
- uint32_t vsp_tcp_handle;
-
- /*
- * This field is used to send part or all of the data
- * through a send buffer. This values specifies an
- * index into the send buffer. If the index is
- * 0xFFFF, then the send buffer is not being used
- * and all of the data was sent through other VMBus
- * mechanisms.
- */
- uint16_t send_buf_section_index;
- uint16_t send_buf_section_size;
-
- /*
- * OOB Data Index
- * This an index to the OOB data buffer. If the index is 0xFFFFFFFF,
- * then there is no OOB data.
- *
- * This field shall be always 0xFFFFFFFF for now. It is reserved for
- * the future.
- */
- uint16_t oob_data_index;
-
- /*
- * DisconnectFlags = 0
- * Normal chimney send. See MiniportTcpOffloadSend for details.
- *
- * DisconnectFlags = TCP_DISCONNECT_GRACEFUL_CLOSE (0x01)
- * Graceful disconnect. See MiniportTcpOffloadDisconnect for details.
- *
- * DisconnectFlags = TCP_DISCONNECT_ABORTIVE_CLOSE (0x02)
- * Abortive disconnect. See MiniportTcpOffloadDisconnect for details.
- */
- uint16_t disconnect_flags;
-
- uint32_t seq_no;
-} __packed nvsp_2_msg_send_chimney_pkt;
-
-/*
- * NvspMessage2TypeSendChimneyPacketComplete
- */
-typedef struct nvsp_2_msg_send_chimney_pkt_complete_ {
- /*
- * The NDIS_STATUS for the chimney send
- */
- uint32_t status;
-
- /*
- * Number of bytes that have been sent to the peer (and ACKed by the peer).
- */
- uint32_t bytes_transferred;
-} __packed nvsp_2_msg_send_chimney_pkt_complete;
-
-
-#define NVSP_1_CHIMNEY_RECV_FLAG_NO_PUSH 0x0001u
-#define NVSP_1_CHIMNEY_RECV_INVALID_OOB_INDEX 0xffffu
-
-/*
- * NvspMessage2TypePostChimneyRecvRequest
- */
-typedef struct nvsp_2_msg_post_chimney_rx_request_ {
- /*
- * Identify the TCP connection which this chimney receive request
- * is for.
- */
- uint32_t vsp_tcp_handle;
-
- /*
- * OOB Data Index
- * This an index to the OOB data buffer. If the index is 0xFFFFFFFF,
- * then there is no OOB data.
- *
- * This field shall be always 0xFFFFFFFF for now. It is reserved for
- * the future.
- */
- uint32_t oob_data_index;
-
- /*
- * Bit 0
- * When it is set, this is a "no-push" receive.
- * When it is clear, this is a "push" receive.
- *
- * Bit 1-15: Reserved and shall be zero
- */
- uint16_t flags;
-
- /*
- * For debugging and diagnoses purpose.
- * The SeqNo is per TCP connection and starts from 0.
- */
- uint32_t seq_no;
-} __packed nvsp_2_msg_post_chimney_rx_request;
-
-/*
- * NvspMessage2TypePostChimneyRecvRequestComplete
- */
-typedef struct nvsp_2_msg_post_chimney_rx_request_complete_ {
- /*
- * The NDIS_STATUS for the chimney send
- */
- uint32_t status;
-
- /*
- * Number of bytes that have been sent to the peer (and ACKed by
- * the peer).
- */
- uint32_t bytes_xferred;
-} __packed nvsp_2_msg_post_chimney_rx_request_complete;
-
-/*
- * NvspMessage2TypeAllocateReceiveBuffer
- */
-typedef struct nvsp_2_msg_alloc_rx_buf_ {
- /*
- * Allocation ID to match the allocation request and response
- */
- uint32_t allocation_id;
-
- /*
- * Length of the VM shared memory receive buffer that needs to
- * be allocated
- */
- uint32_t length;
-} __packed nvsp_2_msg_alloc_rx_buf;
-
-/*
- * NvspMessage2TypeAllocateReceiveBufferComplete
- */
-typedef struct nvsp_2_msg_alloc_rx_buf_complete_ {
- /*
- * The NDIS_STATUS code for buffer allocation
- */
- uint32_t status;
-
- /*
- * Allocation ID from NVSP_2_MESSAGE_ALLOCATE_RECEIVE_BUFFER
- */
- uint32_t allocation_id;
-
- /*
- * GPADL handle for the allocated receive buffer
- */
- uint32_t gpadl_handle;
-
- /*
- * Receive buffer ID that is further used in
- * NvspMessage2SendVmqRndisPacket
- */
- uint64_t rx_buf_id;
-} __packed nvsp_2_msg_alloc_rx_buf_complete;
-
-/*
- * NvspMessage2TypeFreeReceiveBuffer
- */
-typedef struct nvsp_2_msg_free_rx_buf_ {
- /*
- * Receive buffer ID previous returned in
- * NvspMessage2TypeAllocateReceiveBufferComplete message
- */
- uint64_t rx_buf_id;
-} __packed nvsp_2_msg_free_rx_buf;
-
-/*
- * This structure is used in defining the buffers in
- * NVSP_2_MESSAGE_SEND_VMQ_RNDIS_PACKET structure
- */
-typedef struct nvsp_xfer_page_range_ {
- /*
- * Specifies the ID of the receive buffer that has the buffer. This
- * ID can be the general receive buffer ID specified in
- * NvspMessage1TypeSendReceiveBuffer or it can be the shared memory
- * receive buffer ID allocated by the VSC and specified in
- * NvspMessage2TypeAllocateReceiveBufferComplete message
- */
- uint64_t xfer_page_set_id;
-
- /*
- * Number of bytes
- */
- uint32_t byte_count;
-
- /*
- * Offset in bytes from the beginning of the buffer
- */
- uint32_t byte_offset;
-} __packed nvsp_xfer_page_range;
-
-/*
- * NvspMessage2SendVmqRndisPacket
- */
-typedef struct nvsp_2_msg_send_vmq_rndis_pkt_ {
- /*
- * This field is specified by RNIDS. They assume there's
- * two different channels of communication. However,
- * the Network VSP only has one. Therefore, the channel
- * travels with the RNDIS packet. It must be RMC_DATA
- */
- uint32_t channel_type;
-
- /*
- * Only the Range element corresponding to the RNDIS header of
- * the first RNDIS message in the multiple RNDIS messages sent
- * in one NVSP message. Information about the data portions as well
- * as the subsequent RNDIS messages in the same NVSP message are
- * embedded in the RNDIS header itself
- */
- nvsp_xfer_page_range range;
-} __packed nvsp_2_msg_send_vmq_rndis_pkt;
-
-/*
- * This message is used by the VSC to complete
- * a RNDIS VMQ message to the VSP. At this point,
- * the initiator of this message can use any resources
- * associated with the original RNDIS VMQ packet.
- */
-typedef struct nvsp_2_msg_send_vmq_rndis_pkt_complete_
-{
- uint32_t status;
-} __packed nvsp_2_msg_send_vmq_rndis_pkt_complete;
-
-/*
- * Version 5 messages
- */
-enum nvsp_subchannel_operation {
- NVSP_SUBCHANNEL_NONE = 0,
- NVSP_SUBCHANNE_ALLOCATE,
- NVSP_SUBCHANNE_MAX
-};
-
-typedef struct nvsp_5_subchannel_request_
-{
- uint32_t op;
- uint32_t num_subchannels;
-} __packed nvsp_5_subchannel_request;
-
-typedef struct nvsp_5_subchannel_complete_
-{
- uint32_t status;
- /* Actual number of subchannels allocated */
- uint32_t num_subchannels;
-} __packed nvsp_5_subchannel_complete;
-
-typedef struct nvsp_5_send_indirect_table_
-{
- /* The number of entries in the send indirection table */
- uint32_t count;
- /*
- * The offset of the send indireciton table from top of
- * this struct. The send indirection table tells which channel
- * to put the send traffic on. Each entry is a channel number.
- */
- uint32_t offset;
-} __packed nvsp_5_send_indirect_table;
-
-typedef union nvsp_1_msg_uber_ {
- nvsp_1_msg_send_ndis_version send_ndis_vers;
-
- nvsp_1_msg_send_rx_buf send_rx_buf;
- nvsp_1_msg_send_rx_buf_complete send_rx_buf_complete;
- nvsp_1_msg_revoke_rx_buf revoke_rx_buf;
-
- nvsp_1_msg_send_send_buf send_send_buf;
- nvsp_1_msg_send_send_buf_complete send_send_buf_complete;
- nvsp_1_msg_revoke_send_buf revoke_send_buf;
-
- nvsp_1_msg_send_rndis_pkt send_rndis_pkt;
- nvsp_1_msg_send_rndis_pkt_complete send_rndis_pkt_complete;
-} __packed nvsp_1_msg_uber;
-
-
-typedef union nvsp_2_msg_uber_ {
- nvsp_2_msg_send_ndis_config send_ndis_config;
-
- nvsp_2_msg_send_chimney_buf send_chimney_buf;
- nvsp_2_msg_send_chimney_buf_complete send_chimney_buf_complete;
- nvsp_2_msg_revoke_chimney_buf revoke_chimney_buf;
-
- nvsp_2_msg_resume_chimney_rx_indication resume_chimney_rx_indication;
- nvsp_2_msg_terminate_chimney terminate_chimney;
- nvsp_2_msg_terminate_chimney_complete terminate_chimney_complete;
- nvsp_2_msg_indicate_chimney_event indicate_chimney_event;
-
- nvsp_2_msg_send_chimney_pkt send_chimney_packet;
- nvsp_2_msg_send_chimney_pkt_complete send_chimney_packet_complete;
- nvsp_2_msg_post_chimney_rx_request post_chimney_rx_request;
- nvsp_2_msg_post_chimney_rx_request_complete
- post_chimney_rx_request_complete;
-
- nvsp_2_msg_alloc_rx_buf alloc_rx_buffer;
- nvsp_2_msg_alloc_rx_buf_complete alloc_rx_buffer_complete;
- nvsp_2_msg_free_rx_buf free_rx_buffer;
-
- nvsp_2_msg_send_vmq_rndis_pkt send_vmq_rndis_pkt;
- nvsp_2_msg_send_vmq_rndis_pkt_complete send_vmq_rndis_pkt_complete;
- nvsp_2_msg_alloc_chimney_handle alloc_chimney_handle;
- nvsp_2_msg_alloc_chimney_handle_complete alloc_chimney_handle_complete;
-} __packed nvsp_2_msg_uber;
-
-typedef union nvsp_5_msg_uber_
-{
- nvsp_5_subchannel_request subchannel_request;
- nvsp_5_subchannel_complete subchn_complete;
- nvsp_5_send_indirect_table send_table;
-} __packed nvsp_5_msg_uber;
-
-typedef union nvsp_all_msgs_ {
- nvsp_msg_init_uber init_msgs;
- nvsp_1_msg_uber vers_1_msgs;
- nvsp_2_msg_uber vers_2_msgs;
- nvsp_5_msg_uber vers_5_msgs;
-} __packed nvsp_all_msgs;
-
-/*
- * ALL Messages
- */
-typedef struct nvsp_msg_ {
- nvsp_msg_hdr hdr;
- nvsp_all_msgs msgs;
-} __packed nvsp_msg;
-
-
/*
* The following arguably belongs in a separate header file
*/
@@ -1061,13 +233,6 @@ typedef struct netvsc_dev_ {
uint32_t rx_buf_gpadl_handle;
uint32_t rx_section_count;
- /* Used for NetVSP initialization protocol */
- struct sema channel_init_sema;
- nvsp_msg channel_init_packet;
-
- nvsp_msg revoke_packet;
- /*uint8_t hw_mac_addr[ETHER_ADDR_LEN];*/
-
/* Holds rndis device info */
void *extension;
@@ -1079,7 +244,6 @@ typedef struct netvsc_dev_ {
struct hyperv_dma rxbuf_dma;
struct hyperv_dma txbuf_dma;
- uint32_t vrss_send_table[VRSS_SEND_TABLE_SIZE];
} netvsc_dev;
struct vmbus_channel;
@@ -1256,7 +420,7 @@ netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
-int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 4653e77..77e254d 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -792,13 +792,12 @@ 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,
- int dlen __unused)
+ struct vmbus_channel *chan, const void *data __unused, int dlen __unused)
{
struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
- if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
txr = txd->txr;
@@ -988,8 +987,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txr->hn_tx_chimney_tried++;
send_buf_section_idx =
hv_nv_get_next_send_section(net_dev);
- if (send_buf_section_idx !=
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
+ if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
uint8_t *dest = ((uint8_t *)net_dev->send_buf +
(send_buf_section_idx *
net_dev->send_section_size));
@@ -1045,7 +1043,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
gpa->gpa_len = segs[i].ds_len;
}
- send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
done:
txd->m = m_head;
@@ -1072,8 +1070,8 @@ again:
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
- error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx,
- txr->hn_gpa, txr->hn_gpa_cnt);
+ error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
+ &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index 5e3473b..3a73c8c 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -93,10 +93,10 @@ hv_rf_send_offload_request(struct hn_softc *sc,
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, int dlen);
+ const void *data, 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, int dlen);
+ const void *data, int dlen);
/*
* Set the Per-Packet-Info with the specified type
@@ -277,8 +277,7 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
if (tot_data_buf_len < net_dev->send_section_size) {
send_buf_section_idx = hv_nv_get_next_send_section(net_dev);
- if (send_buf_section_idx !=
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
+ if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
char *dest = ((char *)net_dev->send_buf +
send_buf_section_idx * net_dev->send_section_size);
@@ -289,14 +288,14 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
}
/* Failed to allocate chimney send buffer; move on */
}
- send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
sendit:
hn_send_ctx_init(&request->send_ctx, cb, request,
send_buf_section_idx, send_buf_section_size);
- return hv_nv_on_send(device->net_dev->sc->hn_prichan, false,
- &request->send_ctx, gpa, gpa_cnt);
+ return hv_nv_on_send(device->net_dev->sc->hn_prichan,
+ HN_NVS_RNDIS_MTYPE_CTRL, &request->send_ctx, gpa, gpa_cnt);
}
/*
@@ -545,7 +544,7 @@ hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
pkt->tot_data_buf_len -= data_offset;
if (pkt->tot_data_buf_len < rndis_pkt->data_length) {
- pkt->status = nvsp_status_failure;
+ pkt->status = HN_NVS_STATUS_FAILED;
if_printf(rxr->hn_ifp,
"total length %u is less than data length %u\n",
pkt->tot_data_buf_len, rndis_pkt->data_length);
@@ -556,7 +555,7 @@ hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message,
pkt->data = (void *)((unsigned long)pkt->data + data_offset);
if (hv_rf_find_recvinfo(rndis_pkt, &info)) {
- pkt->status = nvsp_status_failure;
+ pkt->status = HN_NVS_STATUS_FAILED;
if_printf(rxr->hn_ifp, "recvinfo parsing failed\n");
return;
}
@@ -581,13 +580,13 @@ hv_rf_on_receive(netvsc_dev *net_dev,
/* Make sure the rndis device state is initialized */
if (net_dev->extension == NULL) {
- pkt->status = nvsp_status_failure;
+ pkt->status = HN_NVS_STATUS_FAILED;
return (ENODEV);
}
rndis_dev = (rndis_device *)net_dev->extension;
if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
- pkt->status = nvsp_status_failure;
+ pkt->status = HN_NVS_STATUS_FAILED;
return (EINVAL);
}
@@ -1177,9 +1176,8 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
- ret = vmbus_chan_send(sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- req, sizeof(*req), (uint64_t)(uintptr_t)&sndc);
+ ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
+ req, sizeof(*req), &sndc);
if (ret != 0) {
if_printf(sc->hn_ifp, "send nvs subch req failed: %d\n", ret);
vmbus_xact_deactivate(xact);
@@ -1274,21 +1272,21 @@ 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 void *data __unused,
int dlen __unused)
{
- if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
}
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 void *data __unused,
int dlen __unused)
{
rndis_request *request = sndc->hn_cbarg;
- if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
/*
diff --git a/sys/dev/hyperv/netvsc/if_hnreg.h b/sys/dev/hyperv/netvsc/if_hnreg.h
index 109ece0..467c540 100644
--- a/sys/dev/hyperv/netvsc/if_hnreg.h
+++ b/sys/dev/hyperv/netvsc/if_hnreg.h
@@ -35,8 +35,20 @@
#define HN_NVS_RXBUF_SIG 0xcafe
#define HN_NVS_CHIM_SIG 0xface
+#define HN_NVS_CHIM_IDX_INVALID 0xffffffff
+
+#define HN_NVS_RNDIS_MTYPE_DATA 0
+#define HN_NVS_RNDIS_MTYPE_CTRL 1
+
+/*
+ * NVS message transacion status codes.
+ */
#define HN_NVS_STATUS_OK 1
+#define HN_NVS_STATUS_FAILED 2
+/*
+ * NVS request/response message types.
+ */
#define HN_NVS_TYPE_INIT 1
#define HN_NVS_TYPE_INIT_RESP 2
#define HN_NVS_TYPE_NDIS_INIT 100
@@ -46,9 +58,14 @@
#define HN_NVS_TYPE_CHIM_CONN 104
#define HN_NVS_TYPE_CHIM_CONNRESP 105
#define HN_NVS_TYPE_CHIM_DISCONN 106
+#define HN_NVS_TYPE_RNDIS 107
+#define HN_NVS_TYPE_RNDIS_ACK 108
#define HN_NVS_TYPE_NDIS_CONF 125
+#define HN_NVS_TYPE_VFASSOC_NOTE 128 /* notification */
+#define HN_NVS_TYPE_SET_DATAPATH 129
#define HN_NVS_TYPE_SUBCH_REQ 133
#define HN_NVS_TYPE_SUBCH_RESP 133 /* same as SUBCH_REQ */
+#define HN_NVS_TYPE_TXTBL_NOTE 134 /* notification */
/*
* Any size less than this one will _not_ work, e.g. hn_nvs_init
@@ -57,6 +74,11 @@
*/
#define HN_NVS_REQSIZE_MIN 32
+/* NVS message common header */
+struct hn_nvs_hdr {
+ uint32_t nvs_type;
+} __packed;
+
struct hn_nvs_init {
uint32_t nvs_type; /* HN_NVS_TYPE_INIT */
uint32_t nvs_ver_min;
@@ -162,4 +184,28 @@ struct hn_nvs_subch_resp {
uint32_t nvs_nsubch;
} __packed;
+struct hn_nvs_rndis {
+ uint32_t nvs_type; /* HN_NVS_TYPE_RNDIS */
+ uint32_t nvs_rndis_mtype;/* HN_NVS_RNDIS_MTYPE_ */
+ /*
+ * Chimney sending buffer index and size.
+ *
+ * NOTE:
+ * If nvs_chim_idx is set to HN_NVS_CHIM_IDX_INVALID
+ * and nvs_chim_sz is set to 0, then chimney sending
+ * buffer is _not_ used by this RNDIS message.
+ */
+ uint32_t nvs_chim_idx;
+ uint32_t nvs_chim_sz;
+ uint8_t nvs_rsvd[16];
+} __packed;
+CTASSERT(sizeof(struct hn_nvs_rndis) >= HN_NVS_REQSIZE_MIN);
+
+struct hn_nvs_rndis_ack {
+ uint32_t nvs_type; /* HN_NVS_TYPE_RNDIS_ACK */
+ uint32_t nvs_status; /* HN_NVS_STATUS_ */
+ uint8_t nvs_rsvd[24];
+} __packed;
+CTASSERT(sizeof(struct hn_nvs_rndis_ack) >= HN_NVS_REQSIZE_MIN);
+
#endif /* !_IF_HNREG_H_ */
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index 39f01ff..706131a 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -30,7 +30,9 @@
#define _IF_HNVAR_H_
#include <sys/param.h>
-#include <dev/hyperv/netvsc/hv_net_vsc.h>
+
+#include <dev/hyperv/include/vmbus.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
struct netvsc_dev_;
struct nvsp_msg_;
@@ -40,7 +42,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_ *, int);
+ struct vmbus_channel *, const void *, int);
struct hn_send_ctx {
hn_sent_callback_t hn_cb;
@@ -49,18 +51,19 @@ struct hn_send_ctx {
int hn_chim_sz;
};
-#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
-{ \
- .hn_cb = cb, \
- .hn_cbarg = cbarg, \
- .hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \
- .hn_chim_sz = 0 \
+#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
+{ \
+ .hn_cb = cb, \
+ .hn_cbarg = cbarg, \
+ .hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \
+ .hn_chim_sz = 0 \
}
static __inline void
hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
void *cbarg, uint32_t chim_idx, int chim_sz)
{
+
sndc->hn_cb = cb;
sndc->hn_cbarg = cbarg;
sndc->hn_chim_idx = chim_idx;
@@ -71,13 +74,31 @@ static __inline void
hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
void *cbarg)
{
- hn_send_ctx_init(sndc, cb, cbarg,
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0);
+
+ hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0);
+}
+
+static __inline int
+hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
+ void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
+{
+
+ return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
+ nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
+}
+
+static __inline int
+hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
+ void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
+{
+
+ return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
+ (uint64_t)(uintptr_t)sndc));
}
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);
+ const void *data, int dlen);
void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx);
#endif /* !_IF_HNVAR_H_ */
OpenPOWER on IntegriCloud