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