#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;
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;
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 *);
DPRINTF("\n");
- if (hvn_nvsp_attach(sc)) {
+ if (hvn_nvs_attach(sc)) {
printf(": failed to init NVSP\n");
return;
}
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);
}
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 */
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);
}
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);
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 */
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;
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);
km_free(sc->sc_tx_ring, sc->sc_tx_size, &kv_any, &kp_zero);
sc->sc_tx_ring = NULL;
-
return (0);
}
}
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);
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;
}
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,
}
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",
}
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:
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
}
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);
}
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;
}
}
{
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);
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);
}
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;
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) {
{
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) {
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);
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);
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);
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);
/*-
- * 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_ */