diff options
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_net_vsc.c | 16 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_net_vsc.h | 130 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 205 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_rndis.h | 908 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hv_rndis_filter.c | 59 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hnreg.h | 12 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hnvar.h | 8 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/ndis.h | 29 |
8 files changed, 183 insertions, 1184 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 51f32f3..91666a4 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -47,9 +47,9 @@ #include <dev/hyperv/include/hyperv.h> #include <dev/hyperv/include/vmbus_xact.h> #include <dev/hyperv/netvsc/hv_net_vsc.h> -#include <dev/hyperv/netvsc/hv_rndis.h> #include <dev/hyperv/netvsc/hv_rndis_filter.h> #include <dev/hyperv/netvsc/if_hnreg.h> +#include <dev/hyperv/netvsc/if_hnvar.h> MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); @@ -512,15 +512,15 @@ hv_nv_connect_to_vsp(struct hn_softc *sc) for (i = protocol_number - 1; i >= 0; i--) { if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { sc->hn_nvs_ver = protocol_list[i]; - sc->hn_ndis_ver = NDIS_VERSION_6_30; + sc->hn_ndis_ver = HN_NDIS_VERSION_6_30; if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) - sc->hn_ndis_ver = NDIS_VERSION_6_1; + sc->hn_ndis_ver = HN_NDIS_VERSION_6_1; if (bootverbose) { if_printf(sc->hn_ifp, "NVS version 0x%x, " "NDIS version %u.%u\n", sc->hn_nvs_ver, - NDIS_VERSION_MAJOR(sc->hn_ndis_ver), - NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } break; } @@ -546,8 +546,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc) memset(&ndis, 0, sizeof(ndis)); ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; - ndis.nvs_ndis_major = NDIS_VERSION_MAJOR(sc->hn_ndis_ver); - ndis.nvs_ndis_minor = NDIS_VERSION_MINOR(sc->hn_ndis_ver); + ndis.nvs_ndis_major = HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver); + ndis.nvs_ndis_minor = HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver); /* NOTE: No response. */ ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); @@ -763,7 +763,7 @@ hv_nv_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, } pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; - if (__predict_false(pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID)) { + if (__predict_false(pkt->cp_rxbuf_id != HN_NVS_RXBUF_SIG)) { if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n", pkt->cp_rxbuf_id); return; diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 4eb9225..4abe920 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -74,110 +74,6 @@ MALLOC_DECLARE(M_NETVSC); #define NVSP_PROTOCOL_VERSION_2 0x30002 #define NVSP_PROTOCOL_VERSION_4 0x40000 #define NVSP_PROTOCOL_VERSION_5 0x50000 -#define NVSP_MIN_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_1) -#define NVSP_MAX_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_2) - -#define NVSP_PROTOCOL_VERSION_CURRENT NVSP_PROTOCOL_VERSION_2 - -#define VERSION_4_OFFLOAD_SIZE 22 - -#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_COMMUNICATION (0x00000004) - -/* - * Maximun number of transfer pages (packets) the VSP will use on a receive - */ -#define NVSP_MAX_PACKETS_PER_RECEIVE 375 - -/* vRSS stuff */ -#define RNDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 -#define RNDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 - -#define RNDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2 -#define RNDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 - -struct rndis_obj_header { - uint8_t type; - uint8_t rev; - uint16_t size; -} __packed; - -/* rndis_recv_scale_cap/cap_flag */ -#define RNDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000 -#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000 -#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000 -#define RNDIS_RSS_CAPS_USING_MSI_X 0x08000000 -#define RNDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000 -#define RNDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400 - -/* RNDIS_RECEIVE_SCALE_CAPABILITIES */ -struct rndis_recv_scale_cap { - struct rndis_obj_header hdr; - uint32_t cap_flag; - uint32_t num_int_msg; - uint32_t num_recv_que; - uint16_t num_indirect_tabent; -} __packed; - -/* rndis_recv_scale_param flags */ -#define RNDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001 -#define RNDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002 -#define RNDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004 -#define RNDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008 -#define RNDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010 - -/* Hash info bits */ -#define RNDIS_HASH_FUNC_TOEPLITZ 0x00000001 -#define RNDIS_HASH_IPV4 0x00000100 -#define RNDIS_HASH_TCP_IPV4 0x00000200 -#define RNDIS_HASH_IPV6 0x00000400 -#define RNDIS_HASH_IPV6_EX 0x00000800 -#define RNDIS_HASH_TCP_IPV6 0x00001000 -#define RNDIS_HASH_TCP_IPV6_EX 0x00002000 - -#define RNDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4) -#define RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 - -#define ITAB_NUM 128 -#define HASH_KEYLEN RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 - -/* RNDIS_RECEIVE_SCALE_PARAMETERS */ -typedef struct rndis_recv_scale_param_ { - struct rndis_obj_header hdr; - - /* Qualifies the rest of the information */ - uint16_t flag; - - /* The base CPU number to do receive processing. not used */ - uint16_t base_cpu_number; - - /* This describes the hash function and type being enabled */ - uint32_t hashinfo; - - /* The size of indirection table array */ - uint16_t indirect_tabsize; - - /* The offset of the indirection table from the beginning of this - * structure - */ - uint32_t indirect_taboffset; - - /* The size of the hash secret key */ - uint16_t hashkey_size; - - /* The offset of the secret key from the beginning of this structure */ - uint32_t hashkey_offset; - - uint32_t processor_masks_offset; - uint32_t num_processor_masks; - uint32_t processor_masks_entry_size; -} rndis_recv_scale_param; /* * The following arguably belongs in a separate header file @@ -188,18 +84,10 @@ typedef struct rndis_recv_scale_param_ { */ #define NETVSC_SEND_BUFFER_SIZE (1024*1024*15) /* 15M */ -#define NETVSC_SEND_BUFFER_ID 0xface #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */ #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */ -#define NETVSC_RECEIVE_BUFFER_ID 0xcafe - -#define NETVSC_RECEIVE_SG_COUNT 1 - -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT 256 - /* * Maximum MTU we permit to be configured for a netvsc interface. * When the code was developed, a max MTU of 12232 was tested and @@ -208,7 +96,6 @@ typedef struct rndis_recv_scale_param_ { #define NETVSC_MAX_CONFIGURABLE_MTU (9 * 1024) #define NETVSC_PACKET_SIZE PAGE_SIZE -#define VRSS_SEND_TABLE_SIZE 16 /* * Data types @@ -216,26 +103,9 @@ typedef struct rndis_recv_scale_param_ { struct vmbus_channel; -typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *); - #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) #define NETVSC_PACKET_MAXPAGE 32 -#define NETVSC_VLAN_PRIO_MASK 0xe000 -#define NETVSC_VLAN_PRIO_SHIFT 13 -#define NETVSC_VLAN_VID_MASK 0x0fff - -#define TYPE_IPV4 2 -#define TYPE_IPV6 4 -#define TYPE_TCP 2 -#define TYPE_UDP 4 - -#define TRANSPORT_TYPE_NOT_IP 0 -#define TRANSPORT_TYPE_IPV4_TCP ((TYPE_IPV4 << 16) | TYPE_TCP) -#define TRANSPORT_TYPE_IPV4_UDP ((TYPE_IPV4 << 16) | TYPE_UDP) -#define TRANSPORT_TYPE_IPV6_TCP ((TYPE_IPV6 << 16) | TYPE_TCP) -#define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP) - typedef struct { uint8_t mac_addr[ETHER_ADDR_LEN]; uint32_t link_state; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 56f01fb..f6dc3a6 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$"); #include <net/ethernet.h> #include <net/if_dl.h> #include <net/if_media.h> - +#include <net/rndis.h> #include <net/bpf.h> #include <net/if_types.h> @@ -120,7 +120,6 @@ __FBSDID("$FreeBSD$"); #include <dev/hyperv/include/vmbus_xact.h> #include <dev/hyperv/netvsc/hv_net_vsc.h> -#include <dev/hyperv/netvsc/hv_rndis.h> #include <dev/hyperv/netvsc/hv_rndis_filter.h> #include <dev/hyperv/netvsc/ndis.h> @@ -144,14 +143,14 @@ __FBSDID("$FreeBSD$"); #define HN_RING_CNT_DEF_MAX 8 -#define HN_RNDIS_MSG_LEN \ - (sizeof(rndis_msg) + \ - RNDIS_HASHVAL_PPI_SIZE + \ - RNDIS_VLAN_PPI_SIZE + \ - RNDIS_TSO_PPI_SIZE + \ - RNDIS_CSUM_PPI_SIZE) -#define HN_RNDIS_MSG_BOUNDARY PAGE_SIZE -#define HN_RNDIS_MSG_ALIGN CACHE_LINE_SIZE +#define HN_RNDIS_PKT_LEN \ + (sizeof(struct rndis_packet_msg) + \ + HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_VLAN_INFO_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_LSO2_INFO_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_TXCSUM_INFO_SIZE)) +#define HN_RNDIS_PKT_BOUNDARY PAGE_SIZE +#define HN_RNDIS_PKT_ALIGN CACHE_LINE_SIZE #define HN_TX_DATA_BOUNDARY PAGE_SIZE #define HN_TX_DATA_MAXSIZE IP_MAXPACKET @@ -175,9 +174,9 @@ struct hn_txdesc { bus_dmamap_t data_dmap; - bus_addr_t rndis_msg_paddr; - rndis_msg *rndis_msg; - bus_dmamap_t rndis_msg_dmap; + bus_addr_t rndis_pkt_paddr; + struct rndis_packet_msg *rndis_pkt; + bus_dmamap_t rndis_pkt_dmap; }; #define HN_TXD_FLAG_ONLIST 0x1 @@ -839,7 +838,7 @@ hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc, } void -netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) +hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { #if defined(INET) || defined(INET6) struct lro_ctrl *lro = &rxr->hn_lro; @@ -863,6 +862,15 @@ netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) hn_txeof(txr); } +static __inline uint32_t +hn_rndis_pktmsg_offset(uint32_t ofs) +{ + + KASSERT(ofs >= sizeof(struct rndis_packet_msg), + ("invalid RNDIS packet msg offset %u", ofs)); + return (ofs - __offsetof(struct rndis_packet_msg, rm_dataoffset)); +} + /* * NOTE: * If this function fails, then both txd and m_head0 will be freed. @@ -873,14 +881,10 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX]; int error, nsegs, i; struct mbuf *m_head = *m_head0; - rndis_msg *rndis_mesg; - rndis_packet *rndis_pkt; - rndis_per_packet_info *rppi; - struct rndis_hash_value *hash_value; - uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx; - int send_buf_section_size; - - tot_data_buf_len = m_head->m_pkthdr.len; + struct rndis_packet_msg *pkt; + uint32_t send_buf_section_idx; + int send_buf_section_size, pktlen; + uint32_t *pi_data; /* * extension points to the area reserved for the @@ -888,45 +892,34 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) * the netvsc_packet (and rppi struct, if present; * length is updated later). */ - rndis_mesg = txd->rndis_msg; - /* XXX not necessary */ - memset(rndis_mesg, 0, HN_RNDIS_MSG_LEN); - rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; - - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset = sizeof(rndis_packet); - rndis_pkt->data_length = tot_data_buf_len; - rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet); - - rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); + pkt = txd->rndis_pkt; + pkt->rm_type = REMOTE_NDIS_PACKET_MSG; + pkt->rm_len = sizeof(*pkt) + m_head->m_pkthdr.len; + pkt->rm_dataoffset = sizeof(*pkt); + pkt->rm_datalen = m_head->m_pkthdr.len; + pkt->rm_pktinfooffset = sizeof(*pkt); + pkt->rm_pktinfolen = 0; /* * Set the hash value for this packet, so that the host could * dispatch the TX done event for this packet back to this TX * ring's channel. */ - rndis_msg_size += RNDIS_HASHVAL_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASHVAL_PPI_SIZE, - nbl_hash_value); - hash_value = (struct rndis_hash_value *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - hash_value->hash_value = txr->hn_tx_idx; + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL); + *pi_data = txr->hn_tx_idx; if (m_head->m_flags & M_VLANTAG) { - ndis_8021q_info *rppi_vlan_info; - - rndis_msg_size += RNDIS_VLAN_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE, - ieee_8021q_info); - - rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - rppi_vlan_info->u1.s1.vlan_id = - m_head->m_pkthdr.ether_vtag & 0xfff; + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN); + *pi_data = NDIS_VLAN_INFO_MAKE( + EVL_VLANOFTAG(m_head->m_pkthdr.ether_vtag), + EVL_PRIOFTAG(m_head->m_pkthdr.ether_vtag), + EVL_CFIOFTAG(m_head->m_pkthdr.ether_vtag)); } if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - rndis_tcp_tso_info *tso_info; +#if defined(INET6) || defined(INET) struct ether_vlan_header *eh; int ether_len; @@ -939,15 +932,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) else ether_len = ETHER_HDR_LEN; - rndis_msg_size += RNDIS_TSO_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE, - tcp_large_send_info); - - tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - tso_info->lso_v2_xmit.type = - RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; - + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO); #ifdef INET if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) { struct ip *ip = @@ -956,13 +942,12 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + iph_len); - tso_info->lso_v2_xmit.ip_version = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4; ip->ip_len = 0; ip->ip_sum = 0; - th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(IPPROTO_TCP)); + *pi_data = NDIS_LSO2_INFO_MAKEIPV4(0, + m_head->m_pkthdr.tso_segsz); } #endif #if defined(INET6) && defined(INET) @@ -974,53 +959,47 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) (m_head->m_data + ether_len); struct tcphdr *th = (struct tcphdr *)(ip6 + 1); - tso_info->lso_v2_xmit.ip_version = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; ip6->ip6_plen = 0; th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + *pi_data = NDIS_LSO2_INFO_MAKEIPV6(0, + m_head->m_pkthdr.tso_segsz); } #endif - tso_info->lso_v2_xmit.tcp_header_offset = 0; - tso_info->lso_v2_xmit.mss = m_head->m_pkthdr.tso_segsz; +#endif /* INET6 || INET */ } else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) { - rndis_tcp_ip_csum_info *csum_info; - - rndis_msg_size += RNDIS_CSUM_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE, - tcpip_chksum_info); - csum_info = (rndis_tcp_ip_csum_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM); + *pi_data = NDIS_TXCSUM_INFO_IPV4; - csum_info->xmit.is_ipv4 = 1; if (m_head->m_pkthdr.csum_flags & CSUM_IP) - csum_info->xmit.ip_header_csum = 1; + *pi_data |= NDIS_TXCSUM_INFO_IPCS; - if (m_head->m_pkthdr.csum_flags & CSUM_TCP) { - csum_info->xmit.tcp_csum = 1; - csum_info->xmit.tcp_header_offset = 0; - } else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) { - csum_info->xmit.udp_csum = 1; - } + if (m_head->m_pkthdr.csum_flags & CSUM_TCP) + *pi_data |= NDIS_TXCSUM_INFO_TCPCS; + else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) + *pi_data |= NDIS_TXCSUM_INFO_UDPCS; } - rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size; - tot_data_buf_len = rndis_mesg->msg_len; + pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; + /* Convert RNDIS packet message offsets */ + pkt->rm_dataoffset = hn_rndis_pktmsg_offset(pkt->rm_dataoffset); + pkt->rm_pktinfooffset = hn_rndis_pktmsg_offset(pkt->rm_pktinfooffset); /* * Chimney send, if the packet could fit into one chimney buffer. */ - if (tot_data_buf_len < txr->hn_chim_size) { + if (pkt->rm_len < txr->hn_chim_size) { txr->hn_tx_chimney_tried++; send_buf_section_idx = hn_chim_alloc(txr->hn_sc); if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) { uint8_t *dest = txr->hn_sc->hn_chim + (send_buf_section_idx * txr->hn_sc->hn_chim_szmax); - memcpy(dest, rndis_mesg, rndis_msg_size); - dest += rndis_msg_size; + memcpy(dest, pkt, pktlen); + dest += pktlen; m_copydata(m_head, 0, m_head->m_pkthdr.len, dest); - send_buf_section_size = tot_data_buf_len; + send_buf_section_size = pkt->rm_len; txr->hn_gpa_cnt = 0; txr->hn_tx_chimney++; goto done; @@ -1051,9 +1030,9 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) txr->hn_gpa_cnt = nsegs + 1; /* send packet with page buffer */ - txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr); - txr->hn_gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; - txr->hn_gpa[0].gpa_len = rndis_msg_size; + txr->hn_gpa[0].gpa_page = atop(txd->rndis_pkt_paddr); + txr->hn_gpa[0].gpa_ofs = txd->rndis_pkt_paddr & PAGE_MASK; + txr->hn_gpa[0].gpa_len = pktlen; /* * Fill the page buffers with mbuf info after the page @@ -1301,7 +1280,7 @@ hn_lro_rx(struct lro_ctrl *lc, struct mbuf *m) * Note: This is no longer used as a callback */ int -netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, +hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info) { struct ifnet *ifp = rxr->hn_ifp; @@ -2154,8 +2133,8 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS) char verstr[16]; snprintf(verstr, sizeof(verstr), "%u.%u", - NDIS_VERSION_MAJOR(sc->hn_ndis_ver), - NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); } @@ -2515,16 +2494,16 @@ hn_create_tx_ring(struct hn_softc *sc, int id) parent_dtag = bus_get_dma_tag(dev); - /* DMA tag for RNDIS messages. */ + /* DMA tag for RNDIS packet messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ - HN_RNDIS_MSG_ALIGN, /* alignment */ - HN_RNDIS_MSG_BOUNDARY, /* boundary */ + HN_RNDIS_PKT_ALIGN, /* alignment */ + HN_RNDIS_PKT_BOUNDARY, /* boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - HN_RNDIS_MSG_LEN, /* maxsize */ + HN_RNDIS_PKT_LEN, /* maxsize */ 1, /* nsegments */ - HN_RNDIS_MSG_LEN, /* maxsegsize */ + HN_RNDIS_PKT_LEN, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockfuncarg */ @@ -2559,28 +2538,28 @@ hn_create_tx_ring(struct hn_softc *sc, int id) txd->txr = txr; /* - * Allocate and load RNDIS messages. + * Allocate and load RNDIS packet message. */ error = bus_dmamem_alloc(txr->hn_tx_rndis_dtag, - (void **)&txd->rndis_msg, - BUS_DMA_WAITOK | BUS_DMA_COHERENT, - &txd->rndis_msg_dmap); + (void **)&txd->rndis_pkt, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, + &txd->rndis_pkt_dmap); if (error) { device_printf(dev, - "failed to allocate rndis_msg, %d\n", i); + "failed to allocate rndis_packet_msg, %d\n", i); return error; } error = bus_dmamap_load(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap, - txd->rndis_msg, HN_RNDIS_MSG_LEN, - hyperv_dma_map_paddr, &txd->rndis_msg_paddr, + txd->rndis_pkt_dmap, + txd->rndis_pkt, HN_RNDIS_PKT_LEN, + hyperv_dma_map_paddr, &txd->rndis_pkt_paddr, BUS_DMA_NOWAIT); if (error) { device_printf(dev, - "failed to load rndis_msg, %d\n", i); + "failed to load rndis_packet_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2591,9 +2570,9 @@ hn_create_tx_ring(struct hn_softc *sc, int id) device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap); + txd->rndis_pkt_dmap); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2651,9 +2630,9 @@ hn_txdesc_dmamap_destroy(struct hn_txdesc *txd) KASSERT(txd->m == NULL, ("still has mbuf installed")); KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("still dma mapped")); - bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); - bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, - txd->rndis_msg_dmap); + bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_pkt_dmap); + bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_pkt, + txd->rndis_pkt_dmap); bus_dmamap_destroy(txr->hn_tx_data_dtag, txd->data_dmap); } diff --git a/sys/dev/hyperv/netvsc/hv_rndis.h b/sys/dev/hyperv/netvsc/hv_rndis.h deleted file mode 100644 index f765745..0000000 --- a/sys/dev/hyperv/netvsc/hv_rndis.h +++ /dev/null @@ -1,908 +0,0 @@ -/*- - * Copyright (c) 2009-2012,2016 Microsoft Corp. - * Copyright (c) 2010-2012 Citrix Inc. - * Copyright (c) 2012 NetApp Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef __HV_RNDIS_H__ -#define __HV_RNDIS_H__ - -#include <net/rndis.h> - -/* - * NDIS protocol version numbers - */ -#define NDIS_VERSION_5_0 0x00050000 -#define NDIS_VERSION_5_1 0x00050001 -#define NDIS_VERSION_6_0 0x00060000 -#define NDIS_VERSION_6_1 0x00060001 -#define NDIS_VERSION_6_30 0x0006001e - -#define NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) -#define NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) - -/* - * Object Identifiers used by NdisRequest Query/Set Information - */ - -/* - * General Objects - */ - -#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define RNDIS_OID_GEN_LINK_SPEED 0x00010107 -#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C -#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110 -#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113 -#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A -#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B - -/* - * For receive side scale - */ -/* Query only */ -#define RNDIS_OID_GEN_RSS_CAPABILITIES 0x00010203 -/* Query and set */ -#define RNDIS_OID_GEN_RSS_PARAMETERS 0x00010204 - -#define RNDIS_OID_GEN_XMIT_OK 0x00020101 -#define RNDIS_OID_GEN_RCV_OK 0x00020102 -#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103 -#define RNDIS_OID_GEN_RCV_ERROR 0x00020104 -#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105 - -#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C - -#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D -#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E - -#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F -#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210 - -/* - * These are connection-oriented general OIDs. - * These replace the above OIDs for connection-oriented media. - */ -#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105 -#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106 -#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 -#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108 -#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 -#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A -#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B -#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C -#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D - -#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201 -#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202 - -/* - * These are connection-oriented statistics OIDs. - */ -#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101 -#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102 -#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 -#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 -#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 - - -#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201 -#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 -#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204 -#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 -#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206 - -/* - * These are objects for Connection-oriented media call-managers. - */ -#define RNDIS_OID_CO_ADD_PVC 0xFF000001 -#define RNDIS_OID_CO_DELETE_PVC 0xFF000002 -#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003 -#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004 -#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005 -#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006 -#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007 -#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008 -#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009 - - -/* - * 802.3 Objects (Ethernet) - */ - -#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102 -#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103 -#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105 - -/* - * - */ -#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 - -#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 - -#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201 -#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203 -#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204 -#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - - -/* - * RNDIS MP custom OID for test - */ -#define OID_RNDISMP_GET_RECEIVE_BUFFERS 0xFFA0C90D // Query only - -/* - * Remote NDIS offload parameters - */ -#define RNDIS_OBJECT_TYPE_DEFAULT 0x80 - -#define RNDIS_OFFLOAD_PARAMETERS_REVISION_3 3 -#define RNDIS_OFFLOAD_PARAMETERS_NO_CHANGE 0 -#define RNDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED 1 -#define RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED 2 -#define RNDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED 2 -#define RNDIS_OFFLOAD_PARAMETERS_RSC_DISABLED 1 -#define RNDIS_OFFLOAD_PARAMETERS_RSC_ENABLED 2 -#define RNDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED 1 -#define RNDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED 2 -#define RNDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED 3 -#define RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED 4 - -#define RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE 1 -#define RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4 0 -#define RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6 1 - - -#define RNDIS_OID_TCP_OFFLOAD_CURRENT_CONFIG 0xFC01020B /* query only */ -#define RNDIS_OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C /* set only */ -#define RNDIS_OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020D/* query only */ -#define RNDIS_OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG 0xFC01020E /* query only */ -#define RNDIS_OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020F /* query */ -#define RNDIS_OID_OFFLOAD_ENCAPSULATION 0x0101010A /* set/query */ - -/* - * NdisInitialize message - */ -typedef struct rndis_initialize_request_ { - /* RNDIS request ID */ - uint32_t request_id; - uint32_t major_version; - uint32_t minor_version; - uint32_t max_xfer_size; -} rndis_initialize_request; - -/* - * Response to NdisInitialize - */ -typedef struct rndis_initialize_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; - uint32_t major_version; - uint32_t minor_version; - uint32_t device_flags; - /* RNDIS medium */ - uint32_t medium; - uint32_t max_pkts_per_msg; - uint32_t max_xfer_size; - uint32_t pkt_align_factor; - uint32_t af_list_offset; - uint32_t af_list_size; -} rndis_initialize_complete; - -/* - * Call manager devices only: Information about an address family - * supported by the device is appended to the response to NdisInitialize. - */ -typedef struct rndis_co_address_family_ { - /* RNDIS AF */ - uint32_t address_family; - uint32_t major_version; - uint32_t minor_version; -} rndis_co_address_family; - -/* - * NdisHalt message - */ -typedef struct rndis_halt_request_ { - /* RNDIS request ID */ - uint32_t request_id; -} rndis_halt_request; - -/* - * NdisQueryRequest message - */ -typedef struct rndis_query_request_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS OID */ - uint32_t oid; - uint32_t info_buffer_length; - uint32_t info_buffer_offset; - /* RNDIS handle */ - uint32_t device_vc_handle; -} rndis_query_request; - -/* - * Response to NdisQueryRequest - */ -typedef struct rndis_query_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; - uint32_t info_buffer_length; - uint32_t info_buffer_offset; -} rndis_query_complete; - -/* - * NdisSetRequest message - */ -typedef struct rndis_set_request_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS OID */ - uint32_t oid; - uint32_t info_buffer_length; - uint32_t info_buffer_offset; - /* RNDIS handle */ - uint32_t device_vc_handle; -} rndis_set_request; - -/* - * Response to NdisSetRequest - */ -typedef struct rndis_set_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; -} rndis_set_complete; - -/* - * NdisReset message - */ -typedef struct rndis_reset_request_ { - uint32_t reserved; -} rndis_reset_request; - -/* - * Response to NdisReset - */ -typedef struct rndis_reset_complete_ { - /* RNDIS status */ - uint32_t status; - uint32_t addressing_reset; -} rndis_reset_complete; - -/* - * NdisMIndicateStatus message - */ -typedef struct rndis_indicate_status_ { - /* RNDIS status */ - uint32_t status; - uint32_t status_buf_length; - uint32_t status_buf_offset; -} rndis_indicate_status; - -/* - * Diagnostic information passed as the status buffer in - * rndis_indicate_status messages signifying error conditions. - */ -typedef struct rndis_diagnostic_info_ { - /* RNDIS status */ - uint32_t diag_status; - uint32_t error_offset; -} rndis_diagnostic_info; - -/* - * NdisKeepAlive message - */ -typedef struct rndis_keepalive_request_ { - /* RNDIS request ID */ - uint32_t request_id; -} rndis_keepalive_request; - -/* - * Response to NdisKeepAlive - */ -typedef struct rndis_keepalive_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; -} rndis_keepalive_complete; - -/* - * Data message. All offset fields contain byte offsets from the beginning - * of the rndis_packet structure. All length fields are in bytes. - * VcHandle is set to 0 for connectionless data, otherwise it - * contains the VC handle. - */ -typedef struct rndis_packet_ { - uint32_t data_offset; - uint32_t data_length; - uint32_t oob_data_offset; - uint32_t oob_data_length; - uint32_t num_oob_data_elements; - uint32_t per_pkt_info_offset; - uint32_t per_pkt_info_length; - /* RNDIS handle */ - uint32_t vc_handle; - uint32_t reserved; -} rndis_packet; - -typedef struct rndis_packet_ex_ { - uint32_t data_offset; - uint32_t data_length; - uint32_t oob_data_offset; - uint32_t oob_data_length; - uint32_t num_oob_data_elements; - uint32_t per_pkt_info_offset; - uint32_t per_pkt_info_length; - /* RNDIS handle */ - uint32_t vc_handle; - uint32_t reserved; - uint64_t data_buf_id; - uint32_t data_buf_offset; - uint64_t next_header_buf_id; - uint32_t next_header_byte_offset; - uint32_t next_header_byte_count; -} rndis_packet_ex; - -/* - * Optional Out of Band data associated with a Data message. - */ -typedef struct rndis_oobd_ { - uint32_t size; - /* RNDIS class ID */ - uint32_t type; - uint32_t class_info_offset; -} rndis_oobd; - -/* - * Packet extension field contents associated with a Data message. - */ -typedef struct rndis_per_packet_info_ { - uint32_t size; - uint32_t type; - uint32_t per_packet_info_offset; -} rndis_per_packet_info; - -typedef enum ndis_per_pkt_infotype_ { - tcpip_chksum_info, - ipsec_info, - tcp_large_send_info, - classification_handle_info, - ndis_reserved, - sgl_info, - ieee_8021q_info, - original_pkt_info, - pkt_cancel_id, - original_netbuf_list, - cached_netbuf_list, - short_pkt_padding_info, - max_perpkt_info -} ndis_per_pkt_infotype; - -#define nbl_hash_value pkt_cancel_id -#define nbl_hash_info original_netbuf_list - -typedef struct ndis_8021q_info_ { - union { - struct { - uint32_t user_pri : 3; /* User Priority */ - uint32_t cfi : 1; /* Canonical Format ID */ - uint32_t vlan_id : 12; - uint32_t reserved : 16; - } s1; - uint32_t value; - } u1; -} ndis_8021q_info; - -struct rndis_object_header { - uint8_t type; - uint8_t revision; - uint16_t size; -}; - -typedef struct rndis_offload_params_ { - struct rndis_object_header header; - uint8_t ipv4_csum; - uint8_t tcp_ipv4_csum; - uint8_t udp_ipv4_csum; - uint8_t tcp_ipv6_csum; - uint8_t udp_ipv6_csum; - uint8_t lso_v1; - uint8_t ip_sec_v1; - uint8_t lso_v2_ipv4; - uint8_t lso_v2_ipv6; - uint8_t tcp_connection_ipv4; - uint8_t tcp_connection_ipv6; - uint32_t flags; - uint8_t ip_sec_v2; - uint8_t ip_sec_v2_ipv4; - struct { - uint8_t rsc_ipv4; - uint8_t rsc_ipv6; - }; - struct { - uint8_t encapsulated_packet_task_offload; - uint8_t encapsulation_types; - }; - -} rndis_offload_params; - - -typedef struct rndis_tcp_ip_csum_info_ { - union { - struct { - uint32_t is_ipv4:1; - uint32_t is_ipv6:1; - uint32_t tcp_csum:1; - uint32_t udp_csum:1; - uint32_t ip_header_csum:1; - uint32_t reserved:11; - uint32_t tcp_header_offset:10; - } xmit; - struct { - uint32_t tcp_csum_failed:1; - uint32_t udp_csum_failed:1; - uint32_t ip_csum_failed:1; - uint32_t tcp_csum_succeeded:1; - uint32_t udp_csum_succeeded:1; - uint32_t ip_csum_succeeded:1; - uint32_t loopback:1; - uint32_t tcp_csum_value_invalid:1; - uint32_t ip_csum_value_invalid:1; - } receive; - uint32_t value; - }; -} rndis_tcp_ip_csum_info; - -struct rndis_hash_value { - uint32_t hash_value; -} __packed; - -struct rndis_hash_info { - uint32_t hash_info; -} __packed; - -typedef struct rndis_tcp_tso_info_ { - union { - struct { - uint32_t unused:30; - uint32_t type:1; - uint32_t reserved2:1; - } xmit; - struct { - uint32_t mss:20; - uint32_t tcp_header_offset:10; - uint32_t type:1; - uint32_t reserved2:1; - } lso_v1_xmit; - struct { - uint32_t tcp_payload:30; - uint32_t type:1; - uint32_t reserved2:1; - } lso_v1_xmit_complete; - struct { - uint32_t mss:20; - uint32_t tcp_header_offset:10; - uint32_t type:1; - uint32_t ip_version:1; - } lso_v2_xmit; - struct { - uint32_t reserved:30; - uint32_t type:1; - uint32_t reserved2:1; - } lso_v2_xmit_complete; - uint32_t value; - }; -} rndis_tcp_tso_info; - -#define RNDIS_HASHVAL_PPI_SIZE (sizeof(rndis_per_packet_info) + \ - sizeof(struct rndis_hash_value)) - -#define RNDIS_VLAN_PPI_SIZE (sizeof(rndis_per_packet_info) + \ - sizeof(ndis_8021q_info)) - -#define RNDIS_CSUM_PPI_SIZE (sizeof(rndis_per_packet_info) + \ - sizeof(rndis_tcp_ip_csum_info)) - -#define RNDIS_TSO_PPI_SIZE (sizeof(rndis_per_packet_info) + \ - sizeof(rndis_tcp_tso_info)) - -/* - * Format of Information buffer passed in a SetRequest for the OID - * OID_GEN_RNDIS_CONFIG_PARAMETER. - */ -typedef struct rndis_config_parameter_info_ { - uint32_t parameter_name_offset; - uint32_t parameter_name_length; - uint32_t parameter_type; - uint32_t parameter_value_offset; - uint32_t parameter_value_length; -} rndis_config_parameter_info; - -/* - * Values for ParameterType in rndis_config_parameter_info - */ -#define RNDIS_CONFIG_PARAM_TYPE_INTEGER 0 -#define RNDIS_CONFIG_PARAM_TYPE_STRING 2 - - -/* - * CONDIS Miniport messages for connection oriented devices - * that do not implement a call manager. - */ - -/* - * CoNdisMiniportCreateVc message - */ -typedef struct rcondis_mp_create_vc_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS handle */ - uint32_t ndis_vc_handle; -} rcondis_mp_create_vc; - -/* - * Response to CoNdisMiniportCreateVc - */ -typedef struct rcondis_mp_create_vc_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS handle */ - uint32_t device_vc_handle; - /* RNDIS status */ - uint32_t status; -} rcondis_mp_create_vc_complete; - -/* - * CoNdisMiniportDeleteVc message - */ -typedef struct rcondis_mp_delete_vc_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS handle */ - uint32_t device_vc_handle; -} rcondis_mp_delete_vc; - -/* - * Response to CoNdisMiniportDeleteVc - */ -typedef struct rcondis_mp_delete_vc_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; -} rcondis_mp_delete_vc_complete; - -/* - * CoNdisMiniportQueryRequest message - */ -typedef struct rcondis_mp_query_request_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS request type */ - uint32_t request_type; - /* RNDIS OID */ - uint32_t oid; - /* RNDIS handle */ - uint32_t device_vc_handle; - uint32_t info_buf_length; - uint32_t info_buf_offset; -} rcondis_mp_query_request; - -/* - * CoNdisMiniportSetRequest message - */ -typedef struct rcondis_mp_set_request_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS request type */ - uint32_t request_type; - /* RNDIS OID */ - uint32_t oid; - /* RNDIS handle */ - uint32_t device_vc_handle; - uint32_t info_buf_length; - uint32_t info_buf_offset; -} rcondis_mp_set_request; - -/* - * CoNdisIndicateStatus message - */ -typedef struct rcondis_indicate_status_ { - /* RNDIS handle */ - uint32_t ndis_vc_handle; - /* RNDIS status */ - uint32_t status; - uint32_t status_buf_length; - uint32_t status_buf_offset; -} rcondis_indicate_status; - -/* - * CONDIS Call/VC parameters - */ - -typedef struct rcondis_specific_parameters_ { - uint32_t parameter_type; - uint32_t parameter_length; - uint32_t parameter_offset; -} rcondis_specific_parameters; - -typedef struct rcondis_media_parameters_ { - uint32_t flags; - uint32_t reserved1; - uint32_t reserved2; - rcondis_specific_parameters media_specific; -} rcondis_media_parameters; - -typedef struct rndis_flowspec_ { - uint32_t token_rate; - uint32_t token_bucket_size; - uint32_t peak_bandwidth; - uint32_t latency; - uint32_t delay_variation; - uint32_t service_type; - uint32_t max_sdu_size; - uint32_t minimum_policed_size; -} rndis_flowspec; - -typedef struct rcondis_call_manager_parameters_ { - rndis_flowspec transmit; - rndis_flowspec receive; - rcondis_specific_parameters call_mgr_specific; -} rcondis_call_manager_parameters; - -/* - * CoNdisMiniportActivateVc message - */ -typedef struct rcondis_mp_activate_vc_request_ { - /* RNDIS request ID */ - uint32_t request_id; - uint32_t flags; - /* RNDIS handle */ - uint32_t device_vc_handle; - uint32_t media_params_offset; - uint32_t media_params_length; - uint32_t call_mgr_params_offset; - uint32_t call_mgr_params_length; -} rcondis_mp_activate_vc_request; - -/* - * Response to CoNdisMiniportActivateVc - */ -typedef struct rcondis_mp_activate_vc_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; -} rcondis_mp_activate_vc_complete; - -/* - * CoNdisMiniportDeactivateVc message - */ -typedef struct rcondis_mp_deactivate_vc_request_ { - /* RNDIS request ID */ - uint32_t request_id; - uint32_t flags; - /* RNDIS handle */ - uint32_t device_vc_handle; -} rcondis_mp_deactivate_vc_request; - -/* - * Response to CoNdisMiniportDeactivateVc - */ -typedef struct rcondis_mp_deactivate_vc_complete_ { - /* RNDIS request ID */ - uint32_t request_id; - /* RNDIS status */ - uint32_t status; -} rcondis_mp_deactivate_vc_complete; - -/* - * union with all of the RNDIS messages - */ -typedef union rndis_msg_container_ { - rndis_packet packet; - rndis_initialize_request init_request; - rndis_halt_request halt_request; - rndis_query_request query_request; - rndis_set_request set_request; - rndis_reset_request reset_request; - rndis_keepalive_request keepalive_request; - rndis_indicate_status indicate_status; - rndis_initialize_complete init_complete; - rndis_query_complete query_complete; - rndis_set_complete set_complete; - rndis_reset_complete reset_complete; - rndis_keepalive_complete keepalive_complete; - rcondis_mp_create_vc co_miniport_create_vc; - rcondis_mp_delete_vc co_miniport_delete_vc; - rcondis_indicate_status co_miniport_status; - rcondis_mp_activate_vc_request co_miniport_activate_vc; - rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc; - rcondis_mp_create_vc_complete co_miniport_create_vc_complete; - rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete; - rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete; - rcondis_mp_deactivate_vc_complete co_miniport_deactivate_vc_complete; - rndis_packet_ex packet_ex; -} rndis_msg_container; - -/* - * Remote NDIS message format - */ -typedef struct rndis_msg_ { - uint32_t ndis_msg_type; - - /* - * Total length of this message, from the beginning - * of the rndis_msg struct, in bytes. - */ - uint32_t msg_len; - - /* Actual message */ - rndis_msg_container msg; -} rndis_msg; - - -/* - * Handy macros - */ - -/* - * get the size of an RNDIS message. Pass in the message type, - * rndis_set_request, rndis_packet for example - */ -#define RNDIS_MESSAGE_SIZE(message) \ - (sizeof(message) + (sizeof(rndis_msg) - sizeof(rndis_msg_container))) - -/* - * get pointer to info buffer with message pointer - */ -#define MESSAGE_TO_INFO_BUFFER(message) \ - (((PUCHAR)(message)) + message->InformationBufferOffset) - -/* - * get pointer to status buffer with message pointer - */ -#define MESSAGE_TO_STATUS_BUFFER(message) \ - (((PUCHAR)(message)) + message->StatusBufferOffset) - -/* - * get pointer to OOBD buffer with message pointer - */ -#define MESSAGE_TO_OOBD_BUFFER(message) \ - (((PUCHAR)(message)) + message->OOBDataOffset) - -/* - * get pointer to data buffer with message pointer - */ -#define MESSAGE_TO_DATA_BUFFER(message) \ - (((PUCHAR)(message)) + message->PerPacketInfoOffset) - -/* - * get pointer to contained message from NDIS_MESSAGE pointer - */ -#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(rndis_message) \ - ((void *) &rndis_message->Message) - -/* - * get pointer to contained message from NDIS_MESSAGE pointer - */ -#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(rndis_message) \ - ((void *) rndis_message) - - - -/* - * Structures used in OID_RNDISMP_GET_RECEIVE_BUFFERS - */ - -#define RNDISMP_RECEIVE_BUFFER_ELEM_FLAG_VMQ_RECEIVE_BUFFER 0x00000001 - -typedef struct rndismp_rx_buf_elem_ { - uint32_t flags; - uint32_t length; - uint64_t rx_buf_id; - uint32_t gpadl_handle; - void *rx_buf; -} rndismp_rx_buf_elem; - -typedef struct rndismp_rx_bufs_info_ { - uint32_t num_rx_bufs; - rndismp_rx_buf_elem rx_buf_elems[1]; -} rndismp_rx_bufs_info; - - - -#define RNDIS_HEADER_SIZE (sizeof(rndis_msg) - sizeof(rndis_msg_container)) - -/* - * Externs - */ -struct hn_rx_ring; -struct hn_tx_ring; -struct hn_recvinfo; - -int netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, - const struct hn_recvinfo *info); -void netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); - -void* hv_set_rppi_data(rndis_msg *rndis_mesg, - uint32_t rppi_size, - int pkt_type); - -#endif /* __HV_RNDIS_H__ */ - diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 91ecc2c..71bd4d4 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_arp.h> #include <net/if_var.h> #include <net/ethernet.h> +#include <net/rndis.h> #include <sys/types.h> #include <machine/atomic.h> #include <sys/sema.h> @@ -49,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include <dev/hyperv/include/hyperv.h> #include <dev/hyperv/include/vmbus_xact.h> #include <dev/hyperv/netvsc/hv_net_vsc.h> -#include <dev/hyperv/netvsc/hv_rndis.h> #include <dev/hyperv/netvsc/hv_rndis_filter.h> #include <dev/hyperv/netvsc/if_hnreg.h> #include <dev/hyperv/netvsc/ndis.h> @@ -103,29 +103,40 @@ again: return ((rid & 0xffff) << 16); } -/* - * Set the Per-Packet-Info with the specified type - */ void * -hv_set_rppi_data(rndis_msg *rndis_mesg, uint32_t rppi_size, - int pkt_type) +hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, + size_t pi_dlen, uint32_t pi_type) { - rndis_packet *rndis_pkt; - rndis_per_packet_info *rppi; + const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen); + struct rndis_pktinfo *pi; + + KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0, + ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen)); - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset += rppi_size; + /* + * Per-packet-info does not move; it only grows. + * + * NOTE: + * rm_pktinfooffset in this phase counts from the beginning + * of rndis_packet_msg. + */ + KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize, + ("%u pktinfo overflows RNDIS packet msg", pi_type)); + pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset + + pkt->rm_pktinfolen); + pkt->rm_pktinfolen += pi_size; - rppi = (rndis_per_packet_info *)((char *)rndis_pkt + - rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_length); + pi->rm_size = pi_size; + pi->rm_type = pi_type; + pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET; - rppi->size = rppi_size; - rppi->type = pkt_type; - rppi->per_packet_info_offset = sizeof(rndis_per_packet_info); + /* Data immediately follow per-packet-info. */ + pkt->rm_dataoffset += pi_size; - rndis_pkt->per_pkt_info_length += rppi_size; + /* Update RNDIS packet msg length */ + pkt->rm_len += pi_size; - return (rppi); + return (pi->rm_data); } /* @@ -409,7 +420,7 @@ hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen) pkt->rm_len, data_off, data_len); return; } - netvsc_recv(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); + hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); } /* @@ -721,7 +732,7 @@ hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) /* * Only NDIS 6.30+ is supported. */ - KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); *rxr_cnt = 0; @@ -817,7 +828,7 @@ hn_rndis_conf_offload(struct hn_softc *sc) memset(¶ms, 0, sizeof(params)); params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; - if (sc->hn_ndis_ver < NDIS_VERSION_6_30) { + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30) { params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1; } else { @@ -829,7 +840,7 @@ hn_rndis_conf_offload(struct hn_softc *sc) params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; - if (sc->hn_ndis_ver >= NDIS_VERSION_6_30) { + if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; } @@ -856,7 +867,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, int nchan) /* * Only NDIS 6.30+ is supported. */ - KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); memset(rss, 0, sizeof(*rss)); @@ -1049,7 +1060,7 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, hv_rf_query_device_link_status(sc, &dev_info->link_state); - if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) { + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) { /* * Either RSS is not supported, or multiple RX/TX rings * are not requested. @@ -1179,5 +1190,5 @@ void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { - netvsc_channel_rollup(rxr, txr); + hn_chan_rollup(rxr, txr); } diff --git a/sys/dev/hyperv/netvsc/if_hnreg.h b/sys/dev/hyperv/netvsc/if_hnreg.h index 5dfadbf..4d54412 100644 --- a/sys/dev/hyperv/netvsc/if_hnreg.h +++ b/sys/dev/hyperv/netvsc/if_hnreg.h @@ -32,6 +32,14 @@ #include <sys/param.h> #include <sys/systm.h> +/* + * NDIS protocol version numbers + */ +#define HN_NDIS_VERSION_6_1 0x00060001 +#define HN_NDIS_VERSION_6_30 0x0006001e +#define HN_NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) +#define HN_NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) + #define HN_NVS_RXBUF_SIG 0xcafe #define HN_NVS_CHIM_SIG 0xface @@ -221,4 +229,8 @@ CTASSERT(sizeof(struct hn_nvs_rndis_ack) >= HN_NVS_REQSIZE_MIN); #define HN_NDIS_HASH_VALUE_SIZE sizeof(uint32_t) #define HN_NDIS_PKTINFO_TYPE_HASHVAL NDIS_PKTINFO_TYPE_PKT_CANCELID +/* Per-packet-info size */ +#define HN_RNDIS_PKTINFO_SIZE(dlen) \ + __offsetof(struct rndis_pktinfo, rm_data[dlen]) + #endif /* !_IF_HNREG_H_ */ diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 00ef144..8be1aa3 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -112,6 +112,7 @@ hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, } struct vmbus_xact; +struct rndis_packet_msg; const void *hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, @@ -121,6 +122,13 @@ void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, uint32_t hn_chim_alloc(struct hn_softc *sc); void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); +void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, + size_t pktsize, size_t pi_dlen, uint32_t pi_type); + +int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, + const struct hn_recvinfo *info); +void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); + extern struct hn_send_ctx hn_send_ctx_none; #endif /* !_IF_HNVAR_H_ */ diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h index 9e65b4f..895f756 100644 --- a/sys/dev/hyperv/netvsc/ndis.h +++ b/sys/dev/hyperv/netvsc/ndis.h @@ -213,7 +213,7 @@ struct ndis_rssprm_toeplitz { #define NDIS_VLAN_INFO_CFI_MASK 0x0008 #define NDIS_VLAN_INFO_ID_MASK 0xfff0 #define NDIS_VLAN_INFO_MAKE(id, pri, cfi) \ - (((pri) & NVIS_VLAN_INFO_PRI_MASK) | \ + (((pri) & NDIS_VLAN_INFO_PRI_MASK) | \ (((cfi) & 0x1) << 3) | (((id) & 0xfff) << 4)) #define NDIS_VLAN_INFO_ID(inf) (((inf) & NDIS_VLAN_INFO_ID_MASK) >> 4) #define NDIS_VLAN_INFO_CFI(inf) (((inf) & NDIS_VLAN_INFO_CFI_MASK) >> 3) @@ -231,4 +231,31 @@ struct ndis_rssprm_toeplitz { #define NDIS_RXCSUM_INFO_TCPCS_INVAL 0x0080 #define NDIS_RXCSUM_INFO_IPCS_INVAL 0x0100 +/* LSOv2 */ +#define NDIS_LSO2_INFO_SIZE sizeof(uint32_t) +#define NDIS_LSO2_INFO_MSS_MASK 0x000fffff +#define NDIS_LSO2_INFO_THOFF_MASK 0x3ff00000 +#define NDIS_LSO2_INFO_ISLSO2 0x40000000 +#define NDIS_LSO2_INFO_ISIPV6 0x80000000 + +#define NDIS_LSO2_INFO_MAKE(thoff, mss) \ + ((((uint32_t)(mss)) & NDIS_LSO2_INFO_MSS_MASK) | \ + ((((uint32_t)(thoff)) & 0x3ff) << 20) | \ + NDIS_LSO2_INFO_ISLSO2) + +#define NDIS_LSO2_INFO_MAKEIPV4(thoff, mss) \ + NDIS_LSO2_INFO_MAKE((thoff), (mss)) + +#define NDIS_LSO2_INFO_MAKEIPV6(thoff, mss) \ + (NDIS_LSO2_INFO_MAKE((thoff), (mss)) | NDIS_LSO2_INFO_ISIPV6) + +/* Transmission checksum */ +#define NDIS_TXCSUM_INFO_SIZE sizeof(uint32_t) +#define NDIS_TXCSUM_INFO_IPV4 0x00000001 +#define NDIS_TXCSUM_INFO_IPV6 0x00000002 +#define NDIS_TXCSUM_INFO_TCPCS 0x00000004 +#define NDIS_TXCSUM_INFO_UDPCS 0x00000008 +#define NDIS_TXCSUM_INFO_IPCS 0x00000010 +#define NDIS_TXCSUM_INFO_THOFF 0x03ff0000 + #endif /* !_NET_NDIS_H_ */ |