Author: sephe
Date: Thu Oct 13 07:52:39 2016
New Revision: 307199
URL: https://svnweb.freebsd.org/changeset/base/307199

Log:
  MFC 305454,305455,305521,305524-305526
  
  305454
      hyperv/hn: Fix VLAN tag setup for outgoing VLAN packets.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7785
  
  305455
      hyperv/hn: Avoid bit fields for LSOv2 setup.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7786
  
  305521
      hyperv/hn: Avoid bit fields for TXCSUM setup.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7792
  
  305524
      hyperv/hn: Cleanup RNDIS packet message encapsulation.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7793
  
  305525
      hyperv/hn: Simplify per-packet-info construction.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7794
  
  305526
      hyperv/hn: Nuke unused bits
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7795

Deleted:
  stable/10/sys/dev/hyperv/netvsc/hv_rndis.h
Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  stable/10/sys/dev/hyperv/netvsc/if_hnreg.h
  stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
  stable/10/sys/dev/hyperv/netvsc/ndis.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c        Thu Oct 13 07:42:44 
2016        (r307198)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c        Thu Oct 13 07:52:39 
2016        (r307199)
@@ -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, st
        }
        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;

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h        Thu Oct 13 07:42:44 
2016        (r307198)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h        Thu Oct 13 07:52:39 
2016        (r307199)
@@ -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;

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Thu Oct 13 
07:42:44 2016        (r307198)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Thu Oct 13 
07:52:39 2016        (r307199)
@@ -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, str
 }
 
 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 
        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 
        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 
         * 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 
                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 
                        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 
                            (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 
        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 mb
  * 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_AR
        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, i
 
        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, i
                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, i
                        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_txdes
        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);
 }
 

Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c   Thu Oct 13 07:42:44 
2016        (r307198)
+++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c   Thu Oct 13 07:52:39 
2016        (r307199)
@@ -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;
 
-       rndis_pkt = &rndis_mesg->msg.packet;
-       rndis_pkt->data_offset += rppi_size;
+       KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0,
+           ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen));
 
-       rppi = (rndis_per_packet_info *)((char *)rndis_pkt +
-           rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_length);
+       /*
+        * 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;
+
+       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 *rx
                    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
        /*
         * 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 *s
        memset(&params, 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 *s
        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, i
        /*
         * 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,
 
        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);
 }

Modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnreg.h  Thu Oct 13 07:42:44 2016        
(r307198)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h  Thu Oct 13 07:52:39 2016        
(r307199)
@@ -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)
 #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_ */

Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Oct 13 07:42:44 2016        
(r307198)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Oct 13 07:52:39 2016        
(r307199)
@@ -112,6 +112,7 @@ hn_nvs_send_sglist(struct vmbus_channel 
 }
 
 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_ct
 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_ */

Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/ndis.h      Thu Oct 13 07:42:44 2016        
(r307198)
+++ stable/10/sys/dev/hyperv/netvsc/ndis.h      Thu Oct 13 07:52:39 2016        
(r307199)
@@ -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_ */
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to