Update NVS protocol structure definitions to the 2016 version
authormikeb <mikeb@openbsd.org>
Thu, 18 Aug 2016 15:56:54 +0000 (15:56 +0000)
committermikeb <mikeb@openbsd.org>
Thu, 18 Aug 2016 15:56:54 +0000 (15:56 +0000)
Microsoft has considerably cleaned up the style and it makes sense
to keep in sync with the maintained upstream version in FreeBSD.

sys/dev/pv/if_hvn.c
sys/dev/pv/if_hvnreg.h

index 2e3408f..3383dff 100644 (file)
@@ -74,6 +74,9 @@
 
 #define HVN_DEBUG                      1
 
+#define HVN_NVS_BUFSIZE                        PAGE_SIZE
+#define HVN_NVS_MSGSIZE                        32
+
 /*
  * RNDIS control interface
  */
 
 struct rndis_cmd {
        uint32_t                         rc_id;
+       struct hvn_nvs_rndis             rc_msg;
        struct rndis                    *rc_req;
        bus_dmamap_t                     rc_dmap;
        uint64_t                         rc_pfn;
        struct rndis                     rc_cmp;
        uint32_t                         rc_cmplen;
        uint8_t                          rc_cmpbuf[HVN_RNDIS_CMPBUFSZ];
-       struct nvsp                      rc_nvsp;
        struct mutex                     rc_mtx;
        TAILQ_ENTRY(rndis_cmd)           rc_entry;
 };
 TAILQ_HEAD(rndis_queue, rndis_cmd);
 
-/*
- * Rx ring
- */
-#define HVN_RX_BUFID                   0xcafe
-
 /*
  * Tx ring
  */
 #define HVN_TX_DESC                    128
-#define HVN_TX_BUFID                   0xface
 
 struct hvn_softc {
        struct device                    sc_dev;
@@ -116,13 +113,12 @@ struct hvn_softc {
        int                              sc_link_state;
        int                              sc_promisc;
 
-       /* NVSP protocol */
+       /* NVS protocol */
        int                              sc_proto;
-       uint32_t                         sc_nvsptid;
-       struct nvsp                      sc_nvsp;
-       uint8_t                         *sc_nvspbuf;
-#define  HVN_NVSP_BUFSIZE               (PAGE_SIZE * 4)
-       struct mutex                     sc_nvsplck;
+       uint32_t                         sc_nvstid;
+       uint8_t                          sc_nvsrsp[HVN_NVS_MSGSIZE];
+       uint8_t                         *sc_nvsbuf;
+       struct mutex                     sc_nvslck;
 
        /* RNDIS protocol */
        uint32_t                         sc_rndisrid;
@@ -166,15 +162,15 @@ void      hvn_get_link_status(struct hvn_softc *);
 void   hvn_link_status(struct hvn_softc *);
 
 /* NSVP */
-int    hvn_nvsp_attach(struct hvn_softc *);
-void   hvn_nvsp_intr(void *);
-int    hvn_nvsp_output(struct hvn_softc *, struct nvsp *, uint64_t, int);
-int    hvn_nvsp_ack(struct hvn_softc *, struct nvsp *, uint64_t);
-void   hvn_nvsp_detach(struct hvn_softc *);
+int    hvn_nvs_attach(struct hvn_softc *);
+void   hvn_nvs_intr(void *);
+int    hvn_nvs_cmd(struct hvn_softc *, void *, size_t, uint64_t, int);
+int    hvn_nvs_ack(struct hvn_softc *, uint64_t);
+void   hvn_nvs_detach(struct hvn_softc *);
 
 /* RNDIS */
 int    hvn_rndis_attach(struct hvn_softc *);
-int    hvn_rndis_ctloutput(struct hvn_softc *, struct rndis_cmd *, int);
+int    hvn_rndis_cmd(struct hvn_softc *, struct rndis_cmd *, int);
 void   hvn_rndis_filter(struct hvn_softc *sc, uint64_t, void *);
 void   hvn_rndis_input(struct hvn_softc *, caddr_t, uint32_t,
            struct mbuf_list *);
@@ -220,7 +216,7 @@ hvn_attach(struct device *parent, struct device *self, void *aux)
 
        DPRINTF("\n");
 
-       if (hvn_nvsp_attach(sc)) {
+       if (hvn_nvs_attach(sc)) {
                printf(": failed to init NVSP\n");
                return;
        }
@@ -277,7 +273,7 @@ hvn_attach(struct device *parent, struct device *self, void *aux)
  detach:
        hvn_rx_ring_destroy(sc);
        hvn_tx_ring_destroy(sc);
-       hvn_nvsp_detach(sc);
+       hvn_nvs_detach(sc);
        if (ifp->if_start)
                if_detach(ifp);
 }
@@ -434,12 +430,11 @@ hvn_txeof(struct hvn_softc *sc, uint64_t tid)
 int
 hvn_rx_ring_create(struct hvn_softc *sc)
 {
-       struct nvsp *pkt = &sc->sc_nvsp;
-       struct nvsp_send_rx_buf *msg;
-       struct nvsp_send_rx_buf_comp *cmp;
+       struct hvn_nvs_rxbuf_conn cmd;
+       struct hvn_nvs_rxbuf_conn_resp *rsp;
        uint64_t tid;
 
-       if (sc->sc_proto <= NVSP_PROTOCOL_VERSION_2)
+       if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_2)
                sc->sc_rx_size = 15 * 1024 * 1024;      /* 15MB */
        else
                sc->sc_rx_size = 16 * 1024 * 1024;      /* 16MB */
@@ -457,25 +452,24 @@ hvn_rx_ring_create(struct hvn_softc *sc)
                goto errout;
        }
 
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_send_rx_buf;
-       msg = (struct nvsp_send_rx_buf *)&pkt->msg;
-       msg->gpadl_handle = sc->sc_rx_hndl;
-       msg->id = HVN_RX_BUFID;
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.nvs_type = HVN_NVS_TYPE_RXBUF_CONN;
+       cmd.nvs_gpadl = sc->sc_rx_hndl;
+       cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
 
-       tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-       if (hvn_nvsp_output(sc, pkt, tid, 100))
+       tid = atomic_inc_int_nv(&sc->sc_nvstid);
+       if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 100))
                goto errout;
 
-       cmp = (struct nvsp_send_rx_buf_comp *)&pkt->msg;
-       if (cmp->status != nvsp_status_success) {
+       rsp = (struct hvn_nvs_rxbuf_conn_resp *)&sc->sc_nvsrsp;
+       if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
                DPRINTF("%s: failed to set up the Rx ring\n",
                    sc->sc_dev.dv_xname);
                goto errout;
        }
-       if (cmp->num_sections > 1) {
+       if (rsp->nvs_nsect > 1) {
                DPRINTF("%s: invalid number of Rx ring sections: %d\n",
-                   sc->sc_dev.dv_xname, cmp->num_sections);
+                   sc->sc_dev.dv_xname, rsp->nvs_nsect);
                hvn_rx_ring_destroy(sc);
                return (-1);
        }
@@ -496,20 +490,18 @@ hvn_rx_ring_create(struct hvn_softc *sc)
 int
 hvn_rx_ring_destroy(struct hvn_softc *sc)
 {
-       struct nvsp *pkt = &sc->sc_nvsp;
-       struct nvsp_revoke_rx_buf *msg;
+       struct hvn_nvs_rxbuf_disconn cmd;
        uint64_t tid;
 
        if (sc->sc_rx_ring == NULL)
                return (0);
 
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_revoke_rx_buf;
-       msg = (struct nvsp_revoke_rx_buf *)&pkt->msg;
-       msg->id = HVN_RX_BUFID;
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.nvs_type = HVN_NVS_TYPE_RXBUF_DISCONN;
+       cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
 
-       tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-       if (hvn_nvsp_output(sc, pkt, tid, 0))
+       tid = atomic_inc_int_nv(&sc->sc_nvstid);
+       if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0))
                return (-1);
 
        delay(100);
@@ -527,9 +519,8 @@ hvn_rx_ring_destroy(struct hvn_softc *sc)
 int
 hvn_tx_ring_create(struct hvn_softc *sc)
 {
-       struct nvsp *pkt = &sc->sc_nvsp;
-       struct nvsp_send_tx_buf *msg;
-       struct nvsp_send_tx_buf_comp *cmp;
+       struct hvn_nvs_chim_conn cmd;
+       struct hvn_nvs_chim_conn_resp *rsp;
        uint64_t tid;
 
        sc->sc_tx_size = 15 * 1024 * 1024;      /* 15MB */
@@ -547,18 +538,17 @@ hvn_tx_ring_create(struct hvn_softc *sc)
                goto errout;
        }
 
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_send_tx_buf;
-       msg = (struct nvsp_send_tx_buf *)&pkt->msg;
-       msg->gpadl_handle = sc->sc_tx_hndl;
-       msg->id = HVN_TX_BUFID;
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.nvs_type = HVN_NVS_TYPE_CHIM_CONN;
+       cmd.nvs_gpadl = sc->sc_tx_hndl;
+       cmd.nvs_sig = HVN_NVS_CHIM_SIG;
 
-       tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-       if (hvn_nvsp_output(sc, pkt, tid, 100))
+       tid = atomic_inc_int_nv(&sc->sc_nvstid);
+       if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 100))
                goto errout;
 
-       cmp = (struct nvsp_send_tx_buf_comp *)&pkt->msg;
-       if (cmp->status != nvsp_status_success) {
+       rsp = (struct hvn_nvs_chim_conn_resp *)&sc->sc_nvsrsp;
+       if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
                DPRINTF("%s: failed to set up the Tx ring\n",
                    sc->sc_dev.dv_xname);
                goto errout;
@@ -580,20 +570,18 @@ hvn_tx_ring_create(struct hvn_softc *sc)
 int
 hvn_tx_ring_destroy(struct hvn_softc *sc)
 {
-       struct nvsp *pkt = &sc->sc_nvsp;
-       struct nvsp_revoke_tx_buf *msg;
+       struct hvn_nvs_chim_disconn cmd;
        uint64_t tid;
 
        if (sc->sc_tx_ring == NULL)
                return (0);
 
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_revoke_tx_buf;
-       msg = (struct nvsp_revoke_tx_buf *)&pkt->msg;
-       msg->id = HVN_TX_BUFID;
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.nvs_type = HVN_NVS_TYPE_CHIM_DISCONN;
+       cmd.nvs_sig = HVN_NVS_CHIM_SIG;
 
-       tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-       if (hvn_nvsp_output(sc, pkt, tid, 0))
+       tid = atomic_inc_int_nv(&sc->sc_nvstid);
+       if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0))
                return (-1);
 
        delay(100);
@@ -604,7 +592,6 @@ hvn_tx_ring_destroy(struct hvn_softc *sc)
 
        km_free(sc->sc_tx_ring, sc->sc_tx_size, &kv_any, &kp_zero);
        sc->sc_tx_ring = NULL;
-
        return (0);
 }
 
@@ -642,24 +629,23 @@ hvn_get_link_status(struct hvn_softc *sc)
 }
 
 int
-hvn_nvsp_attach(struct hvn_softc *sc)
+hvn_nvs_attach(struct hvn_softc *sc)
 {
        const uint32_t protos[] = {
-               NVSP_PROTOCOL_VERSION_5, NVSP_PROTOCOL_VERSION_4,
-               NVSP_PROTOCOL_VERSION_2, NVSP_PROTOCOL_VERSION_1
+               HVN_NVS_PROTO_VERSION_5, HVN_NVS_PROTO_VERSION_4,
+               HVN_NVS_PROTO_VERSION_2, HVN_NVS_PROTO_VERSION_1
        };
-       struct nvsp *pkt = &sc->sc_nvsp;
-       struct nvsp_init *init;
-       struct nvsp_init_comp *cmp;
-       struct nvsp_send_ndis_version *ver;
+       struct hvn_nvs_init cmd;
+       struct hvn_nvs_init_resp *rsp;
+       struct hvn_nvs_ndis_init ncmd;
        uint64_t tid;
        uint32_t ndisver;
        int i;
 
        /* 4 page sized buffer for channel messages */
-       sc->sc_nvspbuf = km_alloc(HVN_NVSP_BUFSIZE, &kv_any, &kp_zero,
+       sc->sc_nvsbuf = km_alloc(HVN_NVS_BUFSIZE, &kv_any, &kp_zero,
            (cold ? &kd_nowait : &kd_waitok));
-       if (sc->sc_nvspbuf == NULL) {
+       if (sc->sc_nvsbuf == NULL) {
                DPRINTF("%s: failed to allocate channel data buffer\n",
                    sc->sc_dev.dv_xname);
                return (-1);
@@ -667,25 +653,23 @@ hvn_nvsp_attach(struct hvn_softc *sc)
        sc->sc_chan->ch_buflen = PAGE_SIZE * 4;
 
        /* Associate our interrupt handler with the channel */
-       if (hv_channel_open(sc->sc_chan, NULL, 0, hvn_nvsp_intr, sc)) {
+       if (hv_channel_open(sc->sc_chan, NULL, 0, hvn_nvs_intr, sc)) {
                DPRINTF("%s: failed to open channel\n", sc->sc_dev.dv_xname);
-               km_free(sc->sc_nvspbuf, HVN_NVSP_BUFSIZE, &kv_any, &kp_zero);
+               km_free(sc->sc_nvsbuf, HVN_NVS_BUFSIZE, &kv_any, &kp_zero);
                return (-1);
        }
 
-       mtx_init(&sc->sc_nvsplck, IPL_NET);
-
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_init;
-       init = (struct nvsp_init *)&pkt->msg;
+       mtx_init(&sc->sc_nvslck, IPL_NET);
 
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.nvs_type = HVN_NVS_TYPE_INIT;
        for (i = 0; i < nitems(protos); i++) {
-               init->protocol_version = init->protocol_version_2 = protos[i];
-               tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-               if (hvn_nvsp_output(sc, pkt, tid, 100))
+               cmd.nvs_ver_min = cmd.nvs_ver_max = protos[i];
+               tid = atomic_inc_int_nv(&sc->sc_nvstid);
+               if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 100))
                        return (-1);
-               cmp = (struct nvsp_init_comp *)&pkt->msg;
-               if (cmp->status == nvsp_status_success) {
+               rsp = (struct hvn_nvs_init_resp *)&sc->sc_nvsrsp;
+               if (rsp->nvs_status == HVN_NVS_STATUS_OK) {
                        sc->sc_proto = protos[i];
                        break;
                }
@@ -696,18 +680,17 @@ hvn_nvsp_attach(struct hvn_softc *sc)
                return (-1);
        }
 
-       memset(pkt, 0, sizeof(*pkt));
-       pkt->msg_type = nvsp_type_send_ndis_vers;
-       ver = (struct nvsp_send_ndis_version *)&pkt->msg;
-       if (sc->sc_proto <= NVSP_PROTOCOL_VERSION_4)
+       memset(&ncmd, 0, sizeof(ncmd));
+       ncmd.nvs_type = HVN_NVS_TYPE_NDIS_INIT;
+       if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_4)
                ndisver = NDIS_VERSION_6_1;
        else
                ndisver = NDIS_VERSION_6_30;
-       ver->ndis_major_vers = (ndisver & 0xffff0000) >> 16;
-       ver->ndis_minor_vers = (ndisver & 0x0000ffff);
+       ncmd.nvs_ndis_major = (ndisver & 0xffff0000) >> 16;
+       ncmd.nvs_ndis_minor = (ndisver & 0x0000ffff);
 
-       tid = atomic_inc_int_nv(&sc->sc_nvsptid);
-       if (hvn_nvsp_output(sc, pkt, tid, 100))
+       tid = atomic_inc_int_nv(&sc->sc_nvstid);
+       if (hvn_nvs_cmd(sc, &ncmd, sizeof(ncmd), tid, 100))
                return (-1);
 
        DPRINTF("%s: NVSP %u.%u, NDIS %u.%u\n", sc->sc_dev.dv_xname,
@@ -718,54 +701,54 @@ hvn_nvsp_attach(struct hvn_softc *sc)
 }
 
 void
-hvn_nvsp_intr(void *arg)
+hvn_nvs_intr(void *arg)
 {
        struct hvn_softc *sc = arg;
        struct vmbus_chanpkt_hdr *cph;
-       struct nvsp *pkt;
+       struct hvn_nvs_hdr *nvs;
        uint64_t rid;
        uint32_t rlen;
        int rv;
 
        for (;;) {
-               rv = hv_channel_recv(sc->sc_chan, sc->sc_nvspbuf,
-                   HVN_NVSP_BUFSIZE, &rlen, &rid, 1);
+               rv = hv_channel_recv(sc->sc_chan, sc->sc_nvsbuf,
+                   HVN_NVS_BUFSIZE, &rlen, &rid, 1);
                if (rv != 0 || rlen == 0) {
                        if (rv != EAGAIN)
                                printf("%s: failed to receive an NVSP "
                                    "packet\n", sc->sc_dev.dv_xname);
                        break;
                }
-               cph = (struct vmbus_chanpkt_hdr *)sc->sc_nvspbuf;
-               pkt = (struct nvsp *)VMBUS_CHANPKT_CONST_DATA(cph);
+               cph = (struct vmbus_chanpkt_hdr *)sc->sc_nvsbuf;
+               nvs = (struct hvn_nvs_hdr *)VMBUS_CHANPKT_CONST_DATA(cph);
 
                if (cph->cph_type == VMBUS_CHANPKT_TYPE_COMP) {
-                       switch (pkt->msg_type) {
-                       case nvsp_type_init_comp:
-                       case nvsp_type_send_rx_buf_comp:
-                       case nvsp_type_send_tx_buf_comp:
-                       case nvsp_type_subchannel:
+                       switch (nvs->nvs_type) {
+                       case HVN_NVS_TYPE_INIT_RESP:
+                       case HVN_NVS_TYPE_RXBUF_CONNRESP:
+                       case HVN_NVS_TYPE_CHIM_CONNRESP:
+                       case HVN_NVS_TYPE_SUBCH_RESP:
                                /* copy the response back */
-                               memcpy(&sc->sc_nvsp, pkt, sizeof(sc->sc_nvsp));
-                               wakeup_one(&sc->sc_nvsp);
+                               memcpy(&sc->sc_nvsrsp, nvs, HVN_NVS_MSGSIZE);
+                               wakeup_one(&sc->sc_nvsrsp);
                                break;
-                       case nvsp_type_send_rndis_pkt_comp:
+                       case HVN_NVS_TYPE_RNDIS_ACK:
                                hvn_txeof(sc, cph->cph_tid);
                                break;
                        default:
                                printf("%s: unhandled NVSP packet type %d "
                                    "on completion\n", sc->sc_dev.dv_xname,
-                                   pkt->msg_type);
+                                   nvs->nvs_type);
                        }
                } else if (cph->cph_type == VMBUS_CHANPKT_TYPE_RXBUF) {
-                       switch (pkt->msg_type) {
-                       case nvsp_type_send_rndis_pkt:
+                       switch (nvs->nvs_type) {
+                       case HVN_NVS_TYPE_RNDIS:
                                hvn_rndis_filter(sc, cph->cph_tid, cph);
                                break;
                        default:
                                printf("%s: unhandled NVSP packet type %d "
                                    "on receive\n", sc->sc_dev.dv_xname,
-                                   pkt->msg_type);
+                                   nvs->nvs_type);
                        }
                } else
                        printf("%s: unknown NVSP packet type %u\n",
@@ -774,32 +757,34 @@ hvn_nvsp_intr(void *arg)
 }
 
 int
-hvn_nvsp_output(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid, int timo)
+hvn_nvs_cmd(struct hvn_softc *sc, void *cmd, size_t cmdsize, uint64_t tid,
+    int timo)
 {
+       struct hvn_nvs_hdr *hdr = cmd;
        int tries = 10;
        int rv;
 
        do {
-               rv = hv_channel_send(sc->sc_chan, pkt, sizeof(*pkt),
+               rv = hv_channel_send(sc->sc_chan, cmd, cmdsize,
                    tid, VMBUS_CHANPKT_TYPE_INBAND,
                    timo ? VMBUS_CHANPKT_FLAG_RC : 0);
                if (rv == EAGAIN) {
                        if (timo)
-                               tsleep(pkt, PRIBIO, "hvnsend", timo / 10);
+                               tsleep(cmd, PRIBIO, "hvnsend", timo / 10);
                        else
                                delay(100);
                } else if (rv) {
                        DPRINTF("%s: NVSP operation %d send error %d\n",
-                           sc->sc_dev.dv_xname, pkt->msg_type, rv);
+                           sc->sc_dev.dv_xname, hdr->nvs_type, rv);
                        return (rv);
                }
        } while (rv != 0 && --tries > 0);
 
        if (timo) {
-               mtx_enter(&sc->sc_nvsplck);
-               rv = msleep(&sc->sc_nvsp, &sc->sc_nvsplck, PRIBIO, "hvnvsp",
+               mtx_enter(&sc->sc_nvslck);
+               rv = msleep(&sc->sc_nvsrsp, &sc->sc_nvslck, PRIBIO, "hvnvsp",
                    timo);
-               mtx_leave(&sc->sc_nvsplck);
+               mtx_leave(&sc->sc_nvslck);
 #ifdef HVN_DEBUG
                switch (rv) {
                case EINTR:
@@ -807,7 +792,7 @@ hvn_nvsp_output(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid, int timo)
                        break;
                case EWOULDBLOCK:
                        printf("%s: NVSP opertaion %d timed out\n",
-                           sc->sc_dev.dv_xname, pkt->msg_type);
+                           sc->sc_dev.dv_xname, hdr->nvs_type);
                }
        }
 #endif
@@ -815,13 +800,16 @@ hvn_nvsp_output(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid, int timo)
 }
 
 int
-hvn_nvsp_ack(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid)
+hvn_nvs_ack(struct hvn_softc *sc, uint64_t tid)
 {
+       struct hvn_nvs_rndis_ack cmd;
        int tries = 5;
        int rv;
 
+       cmd.nvs_type = HVN_NVS_TYPE_RNDIS_ACK;
+       cmd.nvs_status = HVN_NVS_STATUS_OK;
        do {
-               rv = hv_channel_send(sc->sc_chan, pkt, sizeof(*pkt),
+               rv = hv_channel_send(sc->sc_chan, &cmd, sizeof(cmd),
                    tid, VMBUS_CHANPKT_TYPE_COMP, 0);
                if (rv == EAGAIN)
                        delay(100);
@@ -835,11 +823,11 @@ hvn_nvsp_ack(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid)
 }
 
 void
-hvn_nvsp_detach(struct hvn_softc *sc)
+hvn_nvs_detach(struct hvn_softc *sc)
 {
        if (hv_channel_close(sc->sc_chan) == 0) {
-               km_free(sc->sc_nvspbuf, HVN_NVSP_BUFSIZE, &kv_any, &kp_zero);
-               sc->sc_nvspbuf = NULL;
+               km_free(sc->sc_nvsbuf, HVN_NVS_BUFSIZE, &kv_any, &kp_zero);
+               sc->sc_nvsbuf = NULL;
        }
 }
 
@@ -908,7 +896,7 @@ hvn_free_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
 {
        memset(rc->rc_req, 0, sizeof(*rc->rc_req));
        memset(&rc->rc_cmp, 0, sizeof(rc->rc_cmp));
-       memset(&rc->rc_nvsp, 0, sizeof(rc->rc_nvsp));
+       memset(&rc->rc_msg, 0, sizeof(rc->rc_msg));
        mtx_enter(&sc->sc_cntl_fqlck);
        TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry);
        mtx_leave(&sc->sc_cntl_fqlck);
@@ -978,7 +966,7 @@ hvn_rndis_attach(struct hvn_softc *sc)
        bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
            BUS_DMASYNC_PREWRITE);
 
-       if ((rv = hvn_rndis_ctloutput(sc, rc, 500)) != 0) {
+       if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
                DPRINTF("%s: INITIALIZE_MSG failed, error %u\n",
                    sc->sc_dev.dv_xname, rv);
                hvn_free_cmd(sc, rc);
@@ -1012,19 +1000,18 @@ errout:
 }
 
 int
-hvn_rndis_ctloutput(struct hvn_softc *sc, struct rndis_cmd *rc, int timo)
+hvn_rndis_cmd(struct hvn_softc *sc, struct rndis_cmd *rc, int timo)
 {
-       struct nvsp_send_rndis_pkt *msg;
+       struct hvn_nvs_rndis *msg = &rc->rc_msg;
        struct vmbus_gpa sgl[1];
        int tries = 10;
        int rv;
 
        KASSERT(timo > 0);
 
-       rc->rc_nvsp.msg_type = nvsp_type_send_rndis_pkt;
-       msg = (struct nvsp_send_rndis_pkt *)&rc->rc_nvsp.msg;
-       msg->chan_type = 1; /* control */
-       msg->send_buf_section_idx = NVSP_INVALID_SECTION_INDEX;
+       msg->nvs_type = HVN_NVS_TYPE_RNDIS;
+       msg->nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_CTRL;
+       msg->nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID;
 
        sgl[0].gpa_page = rc->rc_pfn;
        sgl[0].gpa_len = rc->rc_req->msg_len;
@@ -1033,8 +1020,8 @@ hvn_rndis_ctloutput(struct hvn_softc *sc, struct rndis_cmd *rc, int timo)
        hvn_submit_cmd(sc, rc);
 
        do {
-               rv = hv_channel_send_sgl(sc->sc_chan, sgl, 1, &rc->rc_nvsp,
-                   sizeof(struct nvsp), rc->rc_id);
+               rv = hv_channel_send_sgl(sc->sc_chan, sgl, 1, &rc->rc_msg,
+                   sizeof(struct hvn_nvs_rndis), rc->rc_id);
                if (rv == EAGAIN)
                        tsleep(rc, PRIBIO, "hvnsendbuf", timo / 10);
                else if (rv) {
@@ -1078,10 +1065,8 @@ hvn_rndis_filter(struct hvn_softc *sc, uint64_t tid, void *arg)
 {
        struct ifnet *ifp = &sc->sc_ac.ac_if;
        struct mbuf_list ml = MBUF_LIST_INITIALIZER();
-       struct nvsp pkt;
        struct vmbus_chanpkt_prplist *cp = arg;
-       struct nvsp_send_rndis_pkt_comp *cmp;
-       uint32_t off, len, type, status = 0;
+       uint32_t off, len, type;
        int i;
 
        if (sc->sc_rx_ring == NULL) {
@@ -1121,11 +1106,7 @@ hvn_rndis_filter(struct hvn_softc *sc, uint64_t tid, void *arg)
                            sc->sc_dev.dv_xname, type);
                }
        }
-       memset(&pkt, 0, sizeof(pkt));
-       pkt.msg_type = nvsp_type_send_rndis_pkt_comp;
-       cmp = (struct nvsp_send_rndis_pkt_comp *)&pkt.msg;
-       cmp->status = status;   /* XXX */
-       hvn_nvsp_ack(sc, &pkt, tid);
+       hvn_nvs_ack(sc, tid);
 
        if (MBUF_LIST_FIRST(&ml))
                if_input(ifp, &ml);
@@ -1308,7 +1289,7 @@ hvn_rndis_query(struct hvn_softc *sc, uint32_t oid, void *res, size_t *length)
        bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
            BUS_DMASYNC_PREWRITE);
 
-       if ((rv = hvn_rndis_ctloutput(sc, rc, 500)) != 0) {
+       if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
                DPRINTF("%s: QUERY_MSG failed, error %d\n",
                    sc->sc_dev.dv_xname, rv);
                hvn_free_cmd(sc, rc);
@@ -1367,7 +1348,7 @@ hvn_rndis_set(struct hvn_softc *sc, uint32_t oid, void *data, size_t length)
        bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
            BUS_DMASYNC_PREWRITE);
 
-       if ((rv = hvn_rndis_ctloutput(sc, rc, 500)) != 0) {
+       if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0) {
                DPRINTF("%s: SET_MSG failed, error %u\n",
                    sc->sc_dev.dv_xname, rv);
                hvn_free_cmd(sc, rc);
@@ -1439,7 +1420,7 @@ hvn_rndis_detach(struct hvn_softc *sc)
        bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
            BUS_DMASYNC_PREWRITE);
 
-       if ((rv = hvn_rndis_ctloutput(sc, rc, 500)) != 0)
+       if ((rv = hvn_rndis_cmd(sc, rc, 500)) != 0)
                DPRINTF("%s: HALT_MSG failed, error %u\n",
                    sc->sc_dev.dv_xname, rv);
 
index af57d44..a204617 100644 (file)
@@ -1,7 +1,5 @@
 /*-
- * Copyright (c) 2009-2012 Microsoft Corp.
- * Copyright (c) 2010-2012 Citrix Inc.
- * Copyright (c) 2012 NetApp Inc.
+ * Copyright (c) 2016 Microsoft Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef _IF_HVNREG_H_
 #define _IF_HVNREG_H_
 
-#define NVSP_PROTOCOL_VERSION_1                        0x00002
-#define NVSP_PROTOCOL_VERSION_2                        0x30002
-#define NVSP_PROTOCOL_VERSION_4                        0x40000
-#define NVSP_PROTOCOL_VERSION_5                        0x50000
+#define HVN_NVS_PROTO_VERSION_1                0x00002
+#define HVN_NVS_PROTO_VERSION_2                0x30002
+#define HVN_NVS_PROTO_VERSION_4                0x40000
+#define HVN_NVS_PROTO_VERSION_5                0x50000
 
-#define VERSION_4_OFFLOAD_SIZE                  22
+#define HVN_NVS_RXBUF_SIG              0x2409
+#define HVN_NVS_CHIM_SIG               0x1984
 
-#define NVSP_OPERATIONAL_STATUS_OK             0x00000000
-#define NVSP_OPERATIONAL_STATUS_DEGRADED       0x00000001
-#define NVSP_OPERATIONAL_STATUS_NONRECOVERABLE 0x00000002
-#define NVSP_OPERATIONAL_STATUS_NO_CONTACT     0x00000003
-#define NVSP_OPERATIONAL_STATUS_LOST_COMM      0x00000004
+#define HVN_NVS_CHIM_IDX_INVALID       0xffffffff
 
-/*
- * Maximun number of transfer pages (packets) the VSP will use on a receive
- */
-#define NVSP_MAX_PACKETS_PER_RECEIVE           375
-
-enum nvsp_type {
-       nvsp_type_none = 0,
-
-       /*
-        * Init Messages
-        */
-       nvsp_type_init = 1,
-       nvsp_type_init_comp = 2,
-
-       nvsp_type_version_start = 100,
-
-       /*
-        * Version 1 Messages
-        */
-       nvsp_type_send_ndis_vers = nvsp_type_version_start,
-
-       nvsp_type_send_rx_buf,
-       nvsp_type_send_rx_buf_comp,
-       nvsp_type_revoke_rx_buf,
-
-       nvsp_type_send_tx_buf,
-       nvsp_type_send_tx_buf_comp,
-       nvsp_type_revoke_tx_buf,
-
-       nvsp_type_send_rndis_pkt,
-       nvsp_type_send_rndis_pkt_comp,
-
-       /*
-        * Version 2 Messages
-        */
-       nvsp_type_send_chimney_delegated_buf,
-       nvsp_type_send_chimney_delegated_buf_comp,
-       nvsp_type_revoke_chimney_delegated_buf,
-
-       nvsp_type_resume_chimney_rx_indication,
-
-       nvsp_type_terminate_chimney,
-       nvsp_type_terminate_chimney_comp,
-
-       nvsp_type_indicate_chimney_event,
-
-       nvsp_type_send_chimney_packet,
-       nvsp_type_send_chimney_packet_comp,
-
-       nvsp_type_post_chimney_rx_req,
-       nvsp_type_post_chimney_rx_req_comp,
-
-       nvsp_type_alloc_rx_buf,
-       nvsp_type_alloc_rx_buf_comp,
-
-       nvsp_type_free_rx_buf,
-
-       nvsp_type_send_vmq_rndis_pkt,
-       nvsp_type_send_vmq_rndis_pkt_comp,
-
-       nvsp_type_send_ndis_config,
-
-       nvsp_type_alloc_chimney_handle,
-       nvsp_type_alloc_chimney_handle_comp,
-
-       /*
-        * Version 4 Messages
-        */
-       nvsp_type_send_vf_association,
-       nvsp_type_switch_data_path,
-       nvsp_type_uplink_connect_state_deprecated,
-
-       /*
-        * Version 5 Messages
-        */
-       nvsp_type_oid_query_ex,
-       nvsp_type_oid_query_ex_comp,
-       nvsp_type_subchannel,
-       nvsp_type_send_indirection_table,
-};
-
-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,
-};
+#define HVN_NVS_RNDIS_MTYPE_DATA       0
+#define HVN_NVS_RNDIS_MTYPE_CTRL       1
 
 /*
- * Init Messages
+ * NVS message transacion status codes.
  */
+#define HVN_NVS_STATUS_OK              1
+#define HVN_NVS_STATUS_FAILED          2
 
 /*
- * 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.
+ * NVS request/response message types.
  */
-struct nvsp_init {
-       uint32_t                                protocol_version;
-       uint32_t                                protocol_version_2;
-} __packed;
+#define HVN_NVS_TYPE_INIT              1
+#define HVN_NVS_TYPE_INIT_RESP         2
+#define HVN_NVS_TYPE_NDIS_INIT         100
+#define HVN_NVS_TYPE_RXBUF_CONN                101
+#define HVN_NVS_TYPE_RXBUF_CONNRESP    102
+#define HVN_NVS_TYPE_RXBUF_DISCONN     103
+#define HVN_NVS_TYPE_CHIM_CONN         104
+#define HVN_NVS_TYPE_CHIM_CONNRESP     105
+#define HVN_NVS_TYPE_CHIM_DISCONN      106
+#define HVN_NVS_TYPE_RNDIS             107
+#define HVN_NVS_TYPE_RNDIS_ACK         108
+#define HVN_NVS_TYPE_NDIS_CONF         125
+#define HVN_NVS_TYPE_VFASSOC_NOTE      128     /* notification */
+#define HVN_NVS_TYPE_SET_DATAPATH      129
+#define HVN_NVS_TYPE_SUBCH_REQ         133
+#define HVN_NVS_TYPE_SUBCH_RESP                133     /* same as SUBCH_REQ */
+#define HVN_NVS_TYPE_TXTBL_NOTE                134     /* notification */
 
 /*
- * 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).
+ * 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.
  */
-struct nvsp_init_comp {
-       /* Deprecated */
-       uint32_t                                negotiated_prot_vers;
-       uint32_t                                max_mdl_chain_len;
-       uint32_t                                status;
-} __packed;
+#define HVN_NVS_REQSIZE_MIN            32
 
-/*
- * 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.
- */
-struct nvsp_send_ndis_version {
-       uint32_t                                ndis_major_vers;
-       /* Deprecated */
-       uint32_t                                ndis_minor_vers;
+/* NVS message common header */
+struct hvn_nvs_hdr {
+       uint32_t        nvs_type;
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_send_rx_buf {
-       uint32_t                                gpadl_handle;
-       uint16_t                                id;
+struct hvn_nvs_init {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_INIT */
+       uint32_t        nvs_ver_min;
+       uint32_t        nvs_ver_max;
+       uint8_t         nvs_rsvd[20];
 } __packed;
 
-struct nvsp_rx_buf_section {
-       uint32_t                                offset;
-       uint32_t                                sub_allocation_size;
-       uint32_t                                num_sub_allocations;
-       uint32_t                                end_offset;
+struct hvn_nvs_init_resp {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_INIT_RESP */
+       uint32_t        nvs_ver;        /* deprecated */
+       uint32_t        nvs_rsvd;
+       uint32_t        nvs_status;     /* HVN_NVS_STATUS_ */
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_send_rx_buf_comp {
-       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
-        */
-       struct nvsp_rx_buf_section              sections[1];
+/* No reponse */
+struct hvn_nvs_ndis_conf {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_NDIS_CONF */
+       uint32_t        nvs_mtu;
+       uint32_t        nvs_rsvd;
+       uint64_t        nvs_caps;       /* HVN_NVS_NDIS_CONF_ */
+       uint8_t         nvs_rsvd1[12];
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_revoke_rx_buf {
-       uint16_t                                id;
-} __packed;
+#define HVN_NVS_NDIS_CONF_SRIOV                0x0004
+#define HVN_NVS_NDIS_CONF_VLAN         0x0008
 
-/*
- * 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.
- */
-struct nvsp_send_tx_buf {
-       uint32_t                                gpadl_handle;
-       uint16_t                                id;
+/* No response */
+struct hvn_nvs_ndis_init {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_NDIS_INIT */
+       uint32_t        nvs_ndis_major; /* NDIS_VERSION_MAJOR_ */
+       uint32_t        nvs_ndis_minor; /* NDIS_VERSION_MINOR_ */
+       uint8_t         nvs_rsvd[20];
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_send_tx_buf_comp {
-       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;
+struct hvn_nvs_rxbuf_conn {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_RXBUF_CONN */
+       uint32_t        nvs_gpadl;      /* RXBUF vmbus GPADL */
+       uint16_t        nvs_sig;        /* HVN_NVS_RXBUF_SIG */
+       uint8_t         nvs_rsvd[22];
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_revoke_tx_buf {
-       uint16_t                                id;
+struct hvn_nvs_rxbuf_sect {
+       uint32_t        nvs_start;
+       uint32_t        nvs_slotsz;
+       uint32_t        nvs_slotcnt;
+       uint32_t        nvs_end;
 } __packed;
 
-/*
- * This message is used by both the VSP and the VSC to send
- * an RNDIS message to the opposite channel endpoint.
- */
-struct nvsp_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;
+struct hvn_nvs_rxbuf_conn_resp {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_RXBUF_CONNRESP */
+       uint32_t        nvs_status;     /* HVN_NVS_STATUS_ */
+       uint32_t        nvs_nsect;      /* # of elem in nvs_sect */
+       struct hvn_nvs_rxbuf_sect nvs_sect[0];
 } __packed;
 
-/*
- * 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.
- */
-struct nvsp_send_rndis_pkt_comp {
-       uint32_t                                status;
-} __packed;
-
-
-/*
- * 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.
- */
-struct nvsp_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;
-               } ;
-       };
-} __packed;
-
-struct nvsp_send_ndis_config {
-       uint32_t                                mtu;
-       uint32_t                                reserved;
-       struct nvsp_netvsc_capabilities
-                                               capabilities;
-} __packed;
-
-/*
- * NvspMessage2TypeSendChimneyDelegatedBuffer
- */
-struct nvsp_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;
-
-
-/* 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
- */
-struct nvsp_send_chimney_buf_comp {
-       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                                tx_quota;
-       uint32_t                                rx_quota;
+/* No response */
+struct hvn_nvs_rxbuf_disconn {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_RXBUF_DISCONN */
+       uint16_t        nvs_sig;        /* HVN_NVS_RXBUF_SIG */
+       uint8_t         nvs_rsvd[26];
 } __packed;
 
-/*
- * NvspMessage2TypeRevokeChimneyDelegatedBuffer
- */
-struct nvsp_revoke_chimney_buf {
-       uint32_t                                gpadl_handle;
+struct hvn_nvs_chim_conn {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_CHIM_CONN */
      uint32_t        nvs_gpadl;      /* chimney buf vmbus GPADL */
+       uint16_t        nvs_sig;        /* NDIS_NVS_CHIM_SIG */
+       uint8_t         nvs_rsvd[22];
 } __packed;
 
-
-#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
- */
-struct nvsp_alloc_chimney_handle {
-       uint64_t                                vsc_context;
-       uint32_t                                object_type;
+struct hvn_nvs_chim_conn_resp {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_CHIM_CONNRESP */
+       uint32_t        nvs_status;     /* HVN_NVS_STATUS_ */
+       uint32_t        nvs_sectsz;     /* section size */
 } __packed;
 
-/*
- * NvspMessage2TypeAllocateChimneyHandleComplete
- */
-struct nvsp_alloc_chimney_handle_comp {
-       uint32_t                                vsp_handle;
-} __packed;
-
-
-/*
- * NvspMessage2TypeResumeChimneyRXIndication
- */
-struct nvsp_resume_chimney_rx_indication {
-       /*
-        * Handle identifying the offloaded connection
-        */
-       uint32_t                                vsp_tcp_handle;
+/* No response */
+struct hvn_nvs_chim_disconn {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_CHIM_DISCONN */
+       uint16_t        nvs_sig;        /* HVN_NVS_CHIM_SIG */
+       uint8_t         nvs_rsvd[26];
 } __packed;
 
-/*
- * NvspMessage2TypeTerminateChimney
- */
-struct nvsp_terminate_chimney {
-       /*
-       * Handle identifying the offloaded object
-       */
-       uint32_t                                vsp_handle;
+#define HVN_NVS_SUBCH_OP_ALLOC         1
 
-       /*
-        * 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;
-       };
+struct hvn_nvs_subch_req {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_SUBCH_REQ */
+       uint32_t        nvs_op;         /* HVN_NVS_SUBCH_OP_ */
+       uint32_t        nvs_nsubch;
+       uint8_t         nvs_rsvd[20];
 } __packed;
 
-/*
- * NvspMessage2TypeTerminateChimneyComplete
- */
-struct nvsp_terminate_chimney_comp {
-       uint64_t                                vsc_context;
-       uint32_t                                flags;
+struct hvn_nvs_subch_resp {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_SUBCH_RESP */
+       uint32_t        nvs_status;     /* HVN_NVS_STATUS_ */
+       uint32_t        nvs_nsubch;
 } __packed;
 
-/*
- * NvspMessage2TypeIndicateChimneyEvent
- */
-struct nvsp_indicate_chimney_event {
-       /*
-        * When VscTcpContext is 0, event_type is an NDIS_STATUS;
-        * Otherwise, EventType is an TCP connection event (defined
-        * in NdisTcpOffloadEventHandler chimney DDK document).
-        */
-       uint32_t                                event_type;
-
+struct hvn_nvs_rndis {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_RNDIS */
+       uint32_t        nvs_rndis_mtype;/* HVN_NVS_RNDIS_MTYPE_ */
        /*
-        * When VscTcpContext is 0, EventType is an NDIS_STATUS;
-        * 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;
-
-
-#define NVSP_INVALID_OOB_INDEX                 0xffffu
-#define NVSP_INVALID_SECTION_INDEX             0xffffffff
-
-/*
- * NvspMessage2TypeSendChimneyPacket
- */
-struct nvsp_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;
-
-/*
- * NvspMessage2TypeSendChimneyPacketComplete
- */
-struct nvsp_send_chimney_pkt_comp {
-       /*
-        * 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;
-
-/*
- * NvspMessage2TypePostChimneyRecvRequest
- */
-struct nvsp_post_chimney_rx_req {
-       /*
-        * 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.
+        * Chimney sending buffer index and size.
         *
-        * 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;
-
-/*
- * NvspMessage2TypePostChimneyRecvRequestComplete
- */
-struct nvsp_post_chimney_rx_req_comp {
-       /*
-        * 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;
-
-/*
- * NvspMessage2TypeAllocateReceiveBuffer
- */
-struct nvsp_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;
-
-/*
- * NvspMessage2TypeAllocateReceiveBufferComplete
- */
-struct nvsp_alloc_rx_buf_comp {
-       /*
-        * The NDIS_STATUS code for buffer allocation
-        */
-       uint32_t                                status;
-
-       /*
-        * Allocation ID from NVSP_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;
-
-/*
- * NvspMessage2TypeFreeReceiveBuffer
- */
-struct nvsp_free_rx_buf {
-       /*
-        * Receive buffer ID previous returned in
-        * NvspMessage2TypeAllocateReceiveBufferComplete message
-        */
-       uint64_t                                rx_buf_id;
-} __packed;
-
-/*
- * This structure is used in defining the buffers in
- * NVSP_MESSAGE_SEND_VMQ_RNDIS_PACKET structure
- */
-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;
-
-/*
- * NvspMessage2SendVmqRndisPacket
- */
-struct nvsp_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
-        */
-       struct nvsp_xfer_page_range             range;
-} __packed;
-
-/*
- * 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.
- */
-struct nvsp_send_vmq_rndis_pkt_comp {
-       uint32_t                                status;
-} __packed;
-
-/*
- * Version 5 messages
- */
-enum nvsp_subchannel_operation {
-       NVSP_SUBCHANNEL_NONE = 0,
-       NVSP_SUBCHANNE_ALLOCATE,
-       NVSP_SUBCHANNE_MAX
-};
-
-struct nvsp_subchannel_req {
-       uint32_t                                op;
-       uint32_t                                num_subchannels;
-} __packed;
-
-struct nvsp_subchannel_comp {
-       uint32_t                                status;
-       /* Actual number of subchannels allocated */
-       uint32_t                                num_subchannels;
-} __packed;
-
-struct nvsp_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.
+        * NOTE:
+        * If nvs_chim_idx is set to HVN_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                                offset;
+       uint32_t        nvs_chim_idx;
+       uint32_t        nvs_chim_sz;
+       uint8_t         nvs_rsvd[16];
 } __packed;
 
-/*
- * All messages
- */
-struct nvsp {
-       uint32_t                                msg_type;
-
-       union {
-       struct nvsp_init                        init;
-       struct nvsp_init_comp                   init_compl;
-
-       /* Version 1 */
-       struct nvsp_send_ndis_version           send_ndis_vers;
-
-       struct nvsp_send_rx_buf                 send_rx_buf;
-       struct nvsp_send_rx_buf_comp            send_rx_buf_comp;
-       struct nvsp_revoke_rx_buf               revoke_rx_buf;
-
-       struct nvsp_send_tx_buf                 send_tx_buf;
-       struct nvsp_send_tx_buf_comp            send_tx_buf_comp;
-       struct nvsp_revoke_tx_buf               revoke_tx_buf;
-
-       struct nvsp_send_rndis_pkt              send_rndis_pkt;
-       struct nvsp_send_rndis_pkt_comp         send_rndis_pkt_comp;
-
-       /* Version 2 */
-       struct nvsp_send_ndis_config            send_ndis_config;
-
-       struct nvsp_send_chimney_buf            send_chimney_buf;
-       struct nvsp_send_chimney_buf_comp       send_chimney_buf_comp;
-       struct nvsp_revoke_chimney_buf          revoke_chimney_buf;
-
-       struct nvsp_resume_chimney_rx_indication resume_chimney_rx_indication;
-       struct nvsp_terminate_chimney           terminate_chimney;
-       struct nvsp_terminate_chimney_comp      terminate_chimney_comp;
-       struct nvsp_indicate_chimney_event      indicate_chimney_event;
-
-       struct nvsp_send_chimney_pkt            send_chimney_packet;
-       struct nvsp_send_chimney_pkt_comp       send_chimney_packet_comp;
-       struct nvsp_post_chimney_rx_req         post_chimney_rx_req;
-       struct nvsp_post_chimney_rx_req_comp    post_chimney_rx_req_comp;
-
-       struct nvsp_alloc_rx_buf                alloc_rx_buffer;
-       struct nvsp_alloc_rx_buf_comp           alloc_rx_buffer_comp;
-       struct nvsp_free_rx_buf                 free_rx_buffer;
-
-       struct nvsp_send_vmq_rndis_pkt          send_vmq_rndis_pkt;
-       struct nvsp_send_vmq_rndis_pkt_comp     send_vmq_rndis_pkt_comp;
-       struct nvsp_alloc_chimney_handle        alloc_chimney_handle;
-       struct nvsp_alloc_chimney_handle_comp   alloc_chimney_handle_comp;
-
-       /* Version 5 */
-       struct nvsp_subchannel_req              subchannel_req;
-       struct nvsp_subchannel_comp             subchn_comp;
-       struct nvsp_send_indirect_table         send_table;
-       }                                       msg;
+struct hvn_nvs_rndis_ack {
+       uint32_t        nvs_type;       /* HVN_NVS_TYPE_RNDIS_ACK */
+       uint32_t        nvs_status;     /* HVN_NVS_STATUS_ */
+       uint8_t         nvs_rsvd[24];
 } __packed;
 
 #endif /* _IF_HVNREG_H_ */