Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Nov 2016 03:19:17 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r308624 - stable/11/sys/dev/hyperv/netvsc
Message-ID:  <201611140319.uAE3JHeU049937@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Mon Nov 14 03:19:17 2016
New Revision: 308624
URL: https://svnweb.freebsd.org/changeset/base/308624

Log:
  MFC 307989-307991,308010
  
  307989
      hyperv/hn: Move hn_softc to if_hnvar.h
  
      While I'm here, use consistent macro names.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8345
  
  307990
      hyperv/hn: Move send context to NVS domain.
  
      Since all sends are encapsulated in NVS messages.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8346
  
  307991
      hyperv/hn: NVS inclusion cleanup and forward declare functions.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8347
  
  308010
      hyperv/hn: Change header guardian; in preparation for the upcoming rename.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8352

Modified:
  stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
  stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h
  stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  stable/11/sys/dev/hyperv/netvsc/if_hnvar.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c	Mon Nov 14 03:14:43 2016	(r308623)
+++ stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c	Mon Nov 14 03:19:17 2016	(r308624)
@@ -24,47 +24,59 @@
  * 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$
  */
 
-/**
- * HyperV vmbus network VSC (virtual services client) module
- *
+/*
+ * Network Virtualization Service.
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet6.h"
+#include "opt_inet.h"
 
 #include <sys/param.h>
 #include <sys/kernel.h>
-#include <sys/socket.h>
 #include <sys/limits.h>
-#include <sys/lock.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
 #include <net/if.h>
 #include <net/if_var.h>
-#include <net/if_arp.h>
-#include <machine/bus.h>
-#include <machine/atomic.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp_lro.h>
 
 #include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
 #include <dev/hyperv/include/vmbus_xact.h>
-#include <dev/hyperv/netvsc/hv_net_vsc.h>
-#include <dev/hyperv/netvsc/hv_rndis_filter.h>
+
+#include <dev/hyperv/netvsc/ndis.h>
 #include <dev/hyperv/netvsc/if_hnreg.h>
 #include <dev/hyperv/netvsc/if_hnvar.h>
+#include <dev/hyperv/netvsc/hv_net_vsc.h>
 
-/*
- * Forward declarations
- */
-static int  hn_nvs_conn_chim(struct hn_softc *sc);
-static int  hn_nvs_conn_rxbuf(struct hn_softc *);
-static int  hn_nvs_disconn_chim(struct hn_softc *sc);
-static int  hn_nvs_disconn_rxbuf(struct hn_softc *sc);
-static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
-    struct hn_softc *, struct vmbus_channel *chan,
-    const void *, int);
+static int			hn_nvs_conn_chim(struct hn_softc *);
+static int			hn_nvs_conn_rxbuf(struct hn_softc *);
+static int			hn_nvs_disconn_chim(struct hn_softc *);
+static int			hn_nvs_disconn_rxbuf(struct hn_softc *);
+static int			hn_nvs_conf_ndis(struct hn_softc *, int);
+static int			hn_nvs_init_ndis(struct hn_softc *);
+static int			hn_nvs_doinit(struct hn_softc *, uint32_t);
+static int			hn_nvs_init(struct hn_softc *);
+static const void		*hn_nvs_xact_execute(struct hn_softc *,
+				    struct vmbus_xact *, void *, int,
+				    size_t *, uint32_t);
+static void			hn_nvs_sent_none(struct hn_nvs_sendctx *,
+				    struct hn_softc *, struct vmbus_channel *,
+				    const void *, int);
 
-struct hn_send_ctx	hn_send_ctx_none =
-    HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
+struct hn_nvs_sendctx		hn_nvs_sendctx_none =
+    HN_NVS_SENDCTX_INITIALIZER(hn_nvs_sent_none, NULL);
 
 static const uint32_t		hn_nvs_version[] = {
 	HN_NVS_VERSION_5,
@@ -77,7 +89,7 @@ static const void *
 hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
     void *req, int reqlen, size_t *resplen0, uint32_t type)
 {
-	struct hn_send_ctx sndc;
+	struct hn_nvs_sendctx sndc;
 	size_t resplen, min_resplen = *resplen0;
 	const struct hn_nvs_hdr *hdr;
 	int error;
@@ -88,7 +100,7 @@ hn_nvs_xact_execute(struct hn_softc *sc,
 	/*
 	 * Execute the xact setup by the caller.
 	 */
-	hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact);
+	hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);
 
 	vmbus_xact_activate(xact);
 	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
@@ -121,7 +133,7 @@ hn_nvs_req_send(struct hn_softc *sc, voi
 {
 
 	return (hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
-	    req, reqlen, &hn_send_ctx_none));
+	    req, reqlen, &hn_nvs_sendctx_none));
 }
 
 static int 
@@ -138,9 +150,9 @@ hn_nvs_conn_rxbuf(struct hn_softc *sc)
 	 * Limit RXBUF size for old NVS.
 	 */
 	if (sc->hn_nvs_ver <= HN_NVS_VERSION_2)
-		rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
+		rxbuf_size = HN_RXBUF_SIZE_COMPAT;
 	else
-		rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+		rxbuf_size = HN_RXBUF_SIZE;
 
 	/*
 	 * Connect the RXBUF GPADL to the primary channel.
@@ -219,8 +231,7 @@ hn_nvs_conn_chim(struct hn_softc *sc)
 	 * Sub-channels just share this chimney sending buffer.
 	 */
 	error = vmbus_chan_gpadl_connect(sc->hn_prichan,
-  	    sc->hn_chim_dma.hv_paddr, NETVSC_SEND_BUFFER_SIZE,
-	    &sc->hn_chim_gpadl);
+  	    sc->hn_chim_dma.hv_paddr, HN_CHIM_SIZE, &sc->hn_chim_gpadl);
 	if (error) {
 		if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error);
 		goto cleanup;
@@ -267,8 +278,8 @@ hn_nvs_conn_chim(struct hn_softc *sc)
 	}
 
 	sc->hn_chim_szmax = sectsz;
-	sc->hn_chim_cnt = NETVSC_SEND_BUFFER_SIZE / sc->hn_chim_szmax;
-	if (NETVSC_SEND_BUFFER_SIZE % sc->hn_chim_szmax != 0) {
+	sc->hn_chim_cnt = HN_CHIM_SIZE / sc->hn_chim_szmax;
+	if (HN_CHIM_SIZE % sc->hn_chim_szmax != 0) {
 		if_printf(sc->hn_ifp, "chimney sending sections are "
 		    "not properly aligned\n");
 	}
@@ -605,7 +616,7 @@ hn_nvs_detach(struct hn_softc *sc)
 }
 
 void
-hn_nvs_sent_xact(struct hn_send_ctx *sndc,
+hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc,
     struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
     const void *data, int dlen)
 {
@@ -614,7 +625,7 @@ hn_nvs_sent_xact(struct hn_send_ctx *snd
 }
 
 static void
-hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
+hn_nvs_sent_none(struct hn_nvs_sendctx *sndc __unused,
     struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
     const void *data __unused, int dlen __unused)
 {
@@ -671,3 +682,12 @@ done:
 	vmbus_xact_put(xact);
 	return (error);
 }
+
+int
+hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
+    struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
+{
+
+	return hn_nvs_send_rndis_sglist(chan, HN_NVS_RNDIS_MTYPE_CTRL,
+	    sndc, gpa, gpa_cnt);
+}

Modified: stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h	Mon Nov 14 03:14:43 2016	(r308623)
+++ stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h	Mon Nov 14 03:19:17 2016	(r308624)
@@ -28,260 +28,79 @@
  * $FreeBSD$
  */
 
-/*
- * HyperV vmbus (virtual machine bus) network VSC (virtual services client)
- * header file
- *
- * (Updated from unencumbered NvspProtocol.h)
- */
-
-#ifndef __HV_NET_VSC_H__
-#define __HV_NET_VSC_H__
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/queue.h>
-#include <sys/taskqueue.h>
-#include <sys/sema.h>
-#include <sys/sx.h>
-
-#include <machine/bus.h>
-#include <sys/bus.h>
-#include <sys/bus_dma.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp_lro.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_media.h>
-
-#include <dev/hyperv/include/hyperv.h>
-#include <dev/hyperv/include/hyperv_busdma.h>
-#include <dev/hyperv/include/vmbus.h>
-
-#include <dev/hyperv/netvsc/ndis.h>
-
-#define HN_USE_TXDESC_BUFRING
-
-/*
- * The following arguably belongs in a separate header file
- */
-
-/*
- * Defines
- */
-
-#define NETVSC_SEND_BUFFER_SIZE			(1024*1024*15)   /* 15M */
-
-#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY	(1024*1024*15) /* 15MB */
-#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*16) /* 16MB */
-
-/*
- * Maximum MTU we permit to be configured for a netvsc interface.
- * When the code was developed, a max MTU of 12232 was tested and
- * proven to work.  9K is a reasonable maximum for an Ethernet.
- */
-#define NETVSC_MAX_CONFIGURABLE_MTU		(9 * 1024)
-
-#define NETVSC_PACKET_SIZE			PAGE_SIZE
-
-/*
- * Data types
- */
+#ifndef _HN_NVS_H_
+#define _HN_NVS_H_
 
+struct hn_nvs_sendctx;
 struct vmbus_channel;
+struct hn_softc;
 
-#define NETVSC_DEVICE_RING_BUFFER_SIZE	(128 * PAGE_SIZE)
-#define NETVSC_PACKET_MAXPAGE		32
-
-#define HN_XACT_REQ_PGCNT		2
-#define HN_XACT_RESP_PGCNT		2
-#define HN_XACT_REQ_SIZE		(HN_XACT_REQ_PGCNT * PAGE_SIZE)
-#define HN_XACT_RESP_SIZE		(HN_XACT_RESP_PGCNT * PAGE_SIZE)
-
-struct hn_txdesc;
-#ifndef HN_USE_TXDESC_BUFRING
-SLIST_HEAD(hn_txdesc_list, hn_txdesc);
-#else
-struct buf_ring;
-#endif
-
-struct hn_tx_ring;
-
-struct hn_rx_ring {
-	struct ifnet	*hn_ifp;
-	struct hn_tx_ring *hn_txr;
-	void		*hn_rdbuf;
-	uint8_t		*hn_rxbuf;	/* shadow sc->hn_rxbuf */
-	int		hn_rx_idx;
-
-	/* Trust csum verification on host side */
-	int		hn_trust_hcsum;	/* HN_TRUST_HCSUM_ */
-	struct lro_ctrl	hn_lro;
-
-	u_long		hn_csum_ip;
-	u_long		hn_csum_tcp;
-	u_long		hn_csum_udp;
-	u_long		hn_csum_trusted;
-	u_long		hn_lro_tried;
-	u_long		hn_small_pkts;
-	u_long		hn_pkts;
-	u_long		hn_rss_pkts;
-
-	/* Rarely used stuffs */
-	struct sysctl_oid *hn_rx_sysctl_tree;
-	int		hn_rx_flags;
-
-	void		*hn_br;		/* TX/RX bufring */
-	struct hyperv_dma hn_br_dma;
-} __aligned(CACHE_LINE_SIZE);
-
-#define HN_TRUST_HCSUM_IP	0x0001
-#define HN_TRUST_HCSUM_TCP	0x0002
-#define HN_TRUST_HCSUM_UDP	0x0004
-
-#define HN_RX_FLAG_ATTACHED	0x1
-
-struct hn_tx_ring {
-#ifndef HN_USE_TXDESC_BUFRING
-	struct mtx	hn_txlist_spin;
-	struct hn_txdesc_list hn_txlist;
-#else
-	struct buf_ring	*hn_txdesc_br;
-#endif
-	int		hn_txdesc_cnt;
-	int		hn_txdesc_avail;
-	u_short		hn_has_txeof;
-	u_short		hn_txdone_cnt;
-
-	int		hn_sched_tx;
-	void		(*hn_txeof)(struct hn_tx_ring *);
-	struct taskqueue *hn_tx_taskq;
-	struct task	hn_tx_task;
-	struct task	hn_txeof_task;
-
-	struct buf_ring	*hn_mbuf_br;
-	int		hn_oactive;
-	int		hn_tx_idx;
-	int		hn_tx_flags;
-
-	struct mtx	hn_tx_lock;
-	struct hn_softc	*hn_sc;
-	struct vmbus_channel *hn_chan;
-
-	int		hn_direct_tx_size;
-	int		hn_chim_size;
-	bus_dma_tag_t	hn_tx_data_dtag;
-	uint64_t	hn_csum_assist;
-
-	int		(*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *);
-	int		hn_suspended;
-	int		hn_gpa_cnt;
-	struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE];
-
-	u_long		hn_no_txdescs;
-	u_long		hn_send_failed;
-	u_long		hn_txdma_failed;
-	u_long		hn_tx_collapsed;
-	u_long		hn_tx_chimney_tried;
-	u_long		hn_tx_chimney;
-	u_long		hn_pkts;
-
-	/* Rarely used stuffs */
-	struct hn_txdesc *hn_txdesc;
-	bus_dma_tag_t	hn_tx_rndis_dtag;
-	struct sysctl_oid *hn_tx_sysctl_tree;
-} __aligned(CACHE_LINE_SIZE);
-
-#define HN_TX_FLAG_ATTACHED	0x1
-#define HN_TX_FLAG_HASHVAL	0x2	/* support HASHVAL pktinfo */
-
-/*
- * Device-specific softc structure
- */
-struct hn_softc {
-	struct ifnet    *hn_ifp;
-	struct ifmedia	hn_media;
-	device_t        hn_dev;
-	int             hn_if_flags;
-	struct sx	hn_lock;
-	struct vmbus_channel *hn_prichan;
-
-	int		hn_rx_ring_cnt;
-	int		hn_rx_ring_inuse;
-	struct hn_rx_ring *hn_rx_ring;
-
-	int		hn_tx_ring_cnt;
-	int		hn_tx_ring_inuse;
-	struct hn_tx_ring *hn_tx_ring;
-
-	uint8_t		*hn_chim;
-	u_long		*hn_chim_bmap;
-	int		hn_chim_bmap_cnt;
-	int		hn_chim_cnt;
-	int		hn_chim_szmax;
-
-	int		hn_cpu;
-	struct taskqueue *hn_tx_taskq;
-	struct sysctl_oid *hn_tx_sysctl_tree;
-	struct sysctl_oid *hn_rx_sysctl_tree;
-	struct vmbus_xact_ctx *hn_xact;
-	uint32_t	hn_nvs_ver;
-	uint32_t	hn_rx_filter;
-
-	struct taskqueue	*hn_mgmt_taskq;
-	struct taskqueue	*hn_mgmt_taskq0;
-	struct task		hn_link_task;
-	struct task		hn_netchg_init;
-	struct timeout_task	hn_netchg_status;
-	uint32_t		hn_link_flags;	/* HN_LINK_FLAG_ */
-
-	uint32_t		hn_caps;	/* HN_CAP_ */
-	uint32_t		hn_flags;	/* HN_FLAG_ */
-	void			*hn_rxbuf;
-	uint32_t		hn_rxbuf_gpadl;
-	struct hyperv_dma	hn_rxbuf_dma;
-
-	uint32_t		hn_chim_gpadl;
-	struct hyperv_dma	hn_chim_dma;
-
-	uint32_t		hn_rndis_rid;
-	uint32_t		hn_ndis_ver;
-	int			hn_ndis_tso_szmax;
-	int			hn_ndis_tso_sgmin;
-
-	int			hn_rss_ind_size;
-	uint32_t		hn_rss_hash;	/* NDIS_HASH_ */
-	struct ndis_rssprm_toeplitz hn_rss;
+typedef void		(*hn_nvs_sent_t)
+			(struct hn_nvs_sendctx *, struct hn_softc *,
+			 struct vmbus_channel *, const void *, int);
+
+struct hn_nvs_sendctx {
+	hn_nvs_sent_t	hn_cb;
+	void		*hn_cbarg;
 };
 
-#define HN_FLAG_RXBUF_CONNECTED		0x0001
-#define HN_FLAG_CHIM_CONNECTED		0x0002
-#define HN_FLAG_HAS_RSSKEY		0x0004
-#define HN_FLAG_HAS_RSSIND		0x0008
-#define HN_FLAG_SYNTH_ATTACHED		0x0010
-
-#define HN_CAP_VLAN			0x0001
-#define HN_CAP_MTU			0x0002
-#define HN_CAP_IPCS			0x0004
-#define HN_CAP_TCP4CS			0x0008
-#define HN_CAP_TCP6CS			0x0010
-#define HN_CAP_UDP4CS			0x0020
-#define HN_CAP_UDP6CS			0x0040
-#define HN_CAP_TSO4			0x0080
-#define HN_CAP_TSO6			0x0100
-#define HN_CAP_HASHVAL			0x0200
-
-/* Capability description for use with printf(9) %b identifier. */
-#define HN_CAP_BITS				\
-	"\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS"	\
-	"\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL"
-
-#define HN_LINK_FLAG_LINKUP		0x0001
-#define HN_LINK_FLAG_NETCHG		0x0002
+#define HN_NVS_SENDCTX_INITIALIZER(cb, cbarg)	\
+{						\
+	.hn_cb		= cb,			\
+	.hn_cbarg	= cbarg			\
+}
+
+static __inline void
+hn_nvs_sendctx_init(struct hn_nvs_sendctx *sndc, hn_nvs_sent_t cb, void *cbarg)
+{
+
+	sndc->hn_cb = cb;
+	sndc->hn_cbarg = cbarg;
+}
+
+static __inline int
+hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
+    void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc)
+{
+
+	return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
+	    nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
+}
+
+static __inline int
+hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
+    void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc)
+{
+
+	return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
+	    (uint64_t)(uintptr_t)sndc));
+}
+
+static __inline int
+hn_nvs_send_rndis_sglist(struct vmbus_channel *chan, uint32_t rndis_mtype,
+    struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
+{
+	struct hn_nvs_rndis rndis;
+
+	rndis.nvs_type = HN_NVS_TYPE_RNDIS;
+	rndis.nvs_rndis_mtype = rndis_mtype;
+	rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID;
+	rndis.nvs_chim_sz = 0;
+
+	return (hn_nvs_send_sglist(chan, gpa, gpa_cnt,
+	    &rndis, sizeof(rndis), sndc));
+}
+
+int		hn_nvs_attach(struct hn_softc *sc, int mtu);
+void		hn_nvs_detach(struct hn_softc *sc);
+int		hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch);
+void		hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc,
+		    struct hn_softc *sc, struct vmbus_channel *chan,
+		    const void *data, int dlen);
+int		hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
+		    struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa,
+		    int gpa_cnt);
 
-#endif  /* __HV_NET_VSC_H__ */
+extern struct hn_nvs_sendctx	hn_nvs_sendctx_none;
 
+#endif  /* !_HN_NVS_H_ */

Modified: stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Mon Nov 14 03:14:43 2016	(r308623)
+++ stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Mon Nov 14 03:19:17 2016	(r308624)
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/smp.h>
 #include <sys/sysctl.h>
 #include <sys/buf_ring.h>
+#include <sys/taskqueue.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -91,6 +92,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip.h>
 #include <netinet/if_ether.h>
 #include <netinet/tcp.h>
+#include <netinet/tcp_lro.h>
 #include <netinet/udp.h>
 #include <netinet/ip6.h>
 
@@ -116,11 +118,14 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/hyperv/include/hyperv.h>
 #include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
 #include <dev/hyperv/include/vmbus_xact.h>
 
+#include <dev/hyperv/netvsc/ndis.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
 #include <dev/hyperv/netvsc/hv_net_vsc.h>
 #include <dev/hyperv/netvsc/hv_rndis_filter.h>
-#include <dev/hyperv/netvsc/ndis.h>
 
 #include "vmbus_if.h"
 
@@ -155,7 +160,7 @@ __FBSDID("$FreeBSD$");
 #define HN_TX_DATA_MAXSIZE		IP_MAXPACKET
 #define HN_TX_DATA_SEGSIZE		PAGE_SIZE
 /* -1 for RNDIS packet message */
-#define HN_TX_DATA_SEGCNT_MAX		(NETVSC_PACKET_MAXPAGE - 1)
+#define HN_TX_DATA_SEGCNT_MAX		(HN_GPACNT_MAX - 1)
 
 #define HN_DIRECT_TX_SIZE_DEF		128
 
@@ -169,7 +174,7 @@ struct hn_txdesc {
 	struct hn_tx_ring *txr;
 	int		refs;
 	uint32_t	flags;		/* HN_TXD_FLAG_ */
-	struct hn_send_ctx send_ctx;
+	struct hn_nvs_sendctx send_ctx;
 	uint32_t	chim_index;
 	int		chim_size;
 
@@ -407,37 +412,13 @@ hn_set_lro_lenlim(struct hn_softc *sc, i
 }
 #endif
 
-static __inline int
-hn_nvs_send_rndis_sglist1(struct vmbus_channel *chan, uint32_t rndis_mtype,
-    struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
-{
-	struct hn_nvs_rndis rndis;
-
-	rndis.nvs_type = HN_NVS_TYPE_RNDIS;
-	rndis.nvs_rndis_mtype = rndis_mtype;
-	rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID;
-	rndis.nvs_chim_sz = 0;
-
-	return (hn_nvs_send_sglist(chan, gpa, gpa_cnt,
-	    &rndis, sizeof(rndis), sndc));
-}
-
-int
-hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
-    struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
-{
-
-	return hn_nvs_send_rndis_sglist1(chan, HN_NVS_RNDIS_MTYPE_CTRL,
-	    sndc, gpa, gpa_cnt);
-}
-
 static int
 hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
 {
 
 	KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
 	    txd->chim_size == 0, ("invalid rndis sglist txd"));
-	return (hn_nvs_send_rndis_sglist1(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
+	return (hn_nvs_send_rndis_sglist(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
 	    &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt));
 }
 
@@ -1185,7 +1166,7 @@ hn_txeof(struct hn_tx_ring *txr)
 }
 
 static void
-hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc,
+hn_tx_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc,
     struct vmbus_channel *chan, const void *data __unused, int dlen __unused)
 {
 	struct hn_txdesc *txd = sndc->hn_cbarg;
@@ -1424,7 +1405,7 @@ done:
 	txd->m = m_head;
 
 	/* Set the completion routine */
-	hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd);
+	hn_nvs_sendctx_init(&txd->send_ctx, hn_tx_done, txd);
 
 	return 0;
 }
@@ -1855,7 +1836,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 
 	switch (cmd) {
 	case SIOCSIFMTU:
-		if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
+		if (ifr->ifr_mtu > HN_MTU_MAX) {
 			error = EINVAL;
 			break;
 		}
@@ -2631,7 +2612,7 @@ hn_create_rx_data(struct hn_softc *sc, i
 	 *   may further limit the usable space.
 	 */
 	sc->hn_rxbuf = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
-	    PAGE_SIZE, 0, NETVSC_RECEIVE_BUFFER_SIZE, &sc->hn_rxbuf_dma,
+	    PAGE_SIZE, 0, HN_RXBUF_SIZE, &sc->hn_rxbuf_dma,
 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
 	if (sc->hn_rxbuf == NULL) {
 		device_printf(sc->hn_dev, "allocate rxbuf failed\n");
@@ -2665,9 +2646,7 @@ hn_create_rx_data(struct hn_softc *sc, i
 		struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
 
 		rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
-		    PAGE_SIZE, 0,
-		    NETVSC_DEVICE_RING_BUFFER_SIZE +
-		    NETVSC_DEVICE_RING_BUFFER_SIZE,
+		    PAGE_SIZE, 0, HN_TXBR_SIZE + HN_RXBR_SIZE,
 		    &rxr->hn_br_dma, BUS_DMA_WAITOK);
 		if (rxr->hn_br == NULL) {
 			device_printf(dev, "allocate bufring failed\n");
@@ -2683,7 +2662,7 @@ hn_create_rx_data(struct hn_softc *sc, i
 		rxr->hn_ifp = sc->hn_ifp;
 		if (i < sc->hn_tx_ring_cnt)
 			rxr->hn_txr = &sc->hn_tx_ring[i];
-		rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_DEVBUF, M_WAITOK);
+		rxr->hn_pktbuf = malloc(HN_PKTBUF_LEN, M_DEVBUF, M_WAITOK);
 		rxr->hn_rx_idx = i;
 		rxr->hn_rxbuf = sc->hn_rxbuf;
 
@@ -2830,7 +2809,7 @@ hn_destroy_rx_data(struct hn_softc *sc)
 #if defined(INET) || defined(INET6)
 		tcp_lro_free(&rxr->hn_lro);
 #endif
-		free(rxr->hn_rdbuf, M_DEVBUF);
+		free(rxr->hn_pktbuf, M_DEVBUF);
 	}
 	free(sc->hn_rx_ring, M_DEVBUF);
 	sc->hn_rx_ring = NULL;
@@ -3090,7 +3069,7 @@ hn_create_tx_data(struct hn_softc *sc, i
 	 * NOTE: It is shared by all channels.
 	 */
 	sc->hn_chim = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
-	    PAGE_SIZE, 0, NETVSC_SEND_BUFFER_SIZE, &sc->hn_chim_dma,
+	    PAGE_SIZE, 0, HN_CHIM_SIZE, &sc->hn_chim_dma,
 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
 	if (sc->hn_chim == NULL) {
 		device_printf(sc->hn_dev, "allocate txbuf failed\n");
@@ -3508,8 +3487,8 @@ hn_chan_attach(struct hn_softc *sc, stru
 	 */
 	cbr.cbr = rxr->hn_br;
 	cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr;
-	cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
-	cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
+	cbr.cbr_txsz = HN_TXBR_SIZE;
+	cbr.cbr_rxsz = HN_RXBR_SIZE;
 	error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
 	if (error) {
 		if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
@@ -4067,9 +4046,9 @@ static void
 hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan,
     const struct vmbus_chanpkt_hdr *pkt)
 {
-	struct hn_send_ctx *sndc;
+	struct hn_nvs_sendctx *sndc;
 
-	sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
+	sndc = (struct hn_nvs_sendctx *)(uintptr_t)pkt->cph_xactid;
 	sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt),
 	    VMBUS_CHANPKT_DATALEN(pkt));
 	/*
@@ -4126,7 +4105,7 @@ hn_nvs_handle_rxbuf(struct hn_softc *sc,
 
 		ofs = pkt->cp_rxbuf[i].rb_ofs;
 		len = pkt->cp_rxbuf[i].rb_len;
-		if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) {
+		if (__predict_false(ofs + len > HN_RXBUF_SIZE)) {
 			if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, "
 			    "ofs %d, len %d\n", i, ofs, len);
 			continue;
@@ -4181,9 +4160,9 @@ hn_chan_callback(struct vmbus_channel *c
 	struct hn_rx_ring *rxr = xrxr;
 	struct hn_softc *sc = rxr->hn_ifp->if_softc;
 	void *buffer;
-	int bufferlen = NETVSC_PACKET_SIZE;
+	int bufferlen = HN_PKTBUF_LEN;
 
-	buffer = rxr->hn_rdbuf;
+	buffer = rxr->hn_pktbuf;
 	do {
 		struct vmbus_chanpkt_hdr *pkt = buffer;
 		uint32_t bytes_rxed;
@@ -4210,7 +4189,7 @@ hn_chan_callback(struct vmbus_channel *c
 			}
 		} else if (ret == ENOBUFS) {
 			/* Handle large packet */
-			if (bufferlen > NETVSC_PACKET_SIZE) {
+			if (bufferlen > HN_PKTBUF_LEN) {
 				free(buffer, M_DEVBUF);
 				buffer = NULL;
 			}
@@ -4231,7 +4210,7 @@ hn_chan_callback(struct vmbus_channel *c
 		}
 	} while (1);
 
-	if (bufferlen > NETVSC_PACKET_SIZE)
+	if (bufferlen > HN_PKTBUF_LEN)
 		free(buffer, M_DEVBUF);
 
 	hv_rf_channel_rollup(rxr, rxr->hn_txr);

Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Mon Nov 14 03:14:43 2016	(r308623)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Mon Nov 14 03:19:17 2016	(r308624)
@@ -34,26 +34,30 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/taskqueue.h>
+
+#include <machine/atomic.h>
+
+#include <net/ethernet.h>
 #include <net/if.h>
-#include <net/if_arp.h>
 #include <net/if_var.h>
-#include <net/ethernet.h>
+#include <net/if_media.h>
 #include <net/rndis.h>
+
 #include <netinet/in.h>
 #include <netinet/ip.h>
-#include <sys/types.h>
-#include <machine/atomic.h>
-#include <sys/sema.h>
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
+#include <netinet/tcp_lro.h>
 
 #include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
 #include <dev/hyperv/include/vmbus_xact.h>
+
+#include <dev/hyperv/netvsc/ndis.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
 #include <dev/hyperv/netvsc/hv_net_vsc.h>
 #include <dev/hyperv/netvsc/hv_rndis_filter.h>
-#include <dev/hyperv/netvsc/if_hnreg.h>
-#include <dev/hyperv/netvsc/ndis.h>
 
 #define HV_RF_RECVINFO_VLAN	0x1
 #define HV_RF_RECVINFO_CSUM	0x2
@@ -549,7 +553,7 @@ hn_rndis_get_linkstatus(struct hn_softc 
 
 static const void *
 hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
-    struct hn_send_ctx *sndc, size_t *comp_len)
+    struct hn_nvs_sendctx *sndc, size_t *comp_len)
 {
 	struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
 	int gpa_cnt, error;
@@ -608,7 +612,7 @@ hn_rndis_xact_execute(struct hn_softc *s
 	/*
 	 * Execute the xact setup by the caller.
 	 */
-	comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none,
+	comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_nvs_sendctx_none,
 	    &comp_len);
 	if (comp == NULL)
 		return (NULL);
@@ -1214,7 +1218,7 @@ hn_rndis_halt(struct hn_softc *sc)
 {
 	struct vmbus_xact *xact;
 	struct rndis_halt_req *halt;
-	struct hn_send_ctx sndc;
+	struct hn_nvs_sendctx sndc;
 	size_t comp_len;
 
 	xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt));
@@ -1228,7 +1232,7 @@ hn_rndis_halt(struct hn_softc *sc)
 	halt->rm_rid = hn_rndis_rid(sc);
 
 	/* No RNDIS completion; rely on NVS message send completion */
-	hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact);
+	hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);
 	hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);
 
 	vmbus_xact_put(xact);

Modified: stable/11/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Nov 14 03:14:43 2016	(r308623)
+++ stable/11/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Nov 14 03:19:17 2016	(r308624)
@@ -29,24 +29,27 @@
 #ifndef _IF_HNVAR_H_
 #define _IF_HNVAR_H_
 
-#include <sys/param.h>
+#define HN_USE_TXDESC_BUFRING
 
-#include <dev/hyperv/include/vmbus.h>
-#include <dev/hyperv/netvsc/if_hnreg.h>
+#define HN_CHIM_SIZE			(15 * 1024 * 1024)
 
-struct hn_softc;
+#define HN_RXBUF_SIZE			(16 * 1024 * 1024)
+#define HN_RXBUF_SIZE_COMPAT		(15 * 1024 * 1024)
 
-struct vmbus_channel;
-struct hn_send_ctx;
+/* Claimed to be 12232B */
+#define HN_MTU_MAX			(9 * 1024)
 
-typedef void		(*hn_sent_callback_t)
-			(struct hn_send_ctx *, struct hn_softc *,
-			 struct vmbus_channel *, const void *, int);
+#define HN_PKTBUF_LEN			4096
 
-struct hn_send_ctx {
-	hn_sent_callback_t	hn_cb;
-	void			*hn_cbarg;
-};
+#define HN_TXBR_SIZE			(128 * PAGE_SIZE)
+#define HN_RXBR_SIZE			(128 * PAGE_SIZE)
+
+#define HN_XACT_REQ_PGCNT		2
+#define HN_XACT_RESP_PGCNT		2
+#define HN_XACT_REQ_SIZE		(HN_XACT_REQ_PGCNT * PAGE_SIZE)
+#define HN_XACT_RESP_SIZE		(HN_XACT_RESP_PGCNT * PAGE_SIZE)
+
+#define HN_GPACNT_MAX			32
 
 #define HN_NDIS_VLAN_INFO_INVALID	0xffffffff
 #define HN_NDIS_RXCSUM_INFO_INVALID	0
@@ -59,39 +62,186 @@ struct hn_recvinfo {
 	uint32_t			hash_value;
 };
 
-#define HN_SEND_CTX_INITIALIZER(cb, cbarg)	\
-{						\
-	.hn_cb		= cb,			\
-	.hn_cbarg	= cbarg			\
-}
-
-static __inline void
-hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg)
-{
-
-	sndc->hn_cb = cb;
-	sndc->hn_cbarg = cbarg;
-}
-
-static __inline int
-hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
-    void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
-{
-
-	return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
-	    nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
-}
-
-static __inline int
-hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
-    void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
-{
-
-	return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
-	    (uint64_t)(uintptr_t)sndc));
-}
+struct hn_txdesc;
+#ifndef HN_USE_TXDESC_BUFRING
+SLIST_HEAD(hn_txdesc_list, hn_txdesc);
+#else
+struct buf_ring;
+#endif
+struct hn_tx_ring;
+
+struct hn_rx_ring {
+	struct ifnet	*hn_ifp;
+	struct hn_tx_ring *hn_txr;
+	void		*hn_pktbuf;
+	uint8_t		*hn_rxbuf;	/* shadow sc->hn_rxbuf */
+	int		hn_rx_idx;
+
+	/* Trust csum verification on host side */
+	int		hn_trust_hcsum;	/* HN_TRUST_HCSUM_ */
+	struct lro_ctrl	hn_lro;
+
+	u_long		hn_csum_ip;
+	u_long		hn_csum_tcp;
+	u_long		hn_csum_udp;
+	u_long		hn_csum_trusted;
+	u_long		hn_lro_tried;
+	u_long		hn_small_pkts;
+	u_long		hn_pkts;
+	u_long		hn_rss_pkts;
+
+	/* Rarely used stuffs */
+	struct sysctl_oid *hn_rx_sysctl_tree;
+	int		hn_rx_flags;
+
+	void		*hn_br;		/* TX/RX bufring */
+	struct hyperv_dma hn_br_dma;
+} __aligned(CACHE_LINE_SIZE);
+
+#define HN_TRUST_HCSUM_IP	0x0001
+#define HN_TRUST_HCSUM_TCP	0x0002
+#define HN_TRUST_HCSUM_UDP	0x0004
+
+#define HN_RX_FLAG_ATTACHED	0x1
+
+struct hn_tx_ring {
+#ifndef HN_USE_TXDESC_BUFRING
+	struct mtx	hn_txlist_spin;
+	struct hn_txdesc_list hn_txlist;
+#else
+	struct buf_ring	*hn_txdesc_br;
+#endif
+	int		hn_txdesc_cnt;
+	int		hn_txdesc_avail;
+	u_short		hn_has_txeof;
+	u_short		hn_txdone_cnt;
+
+	int		hn_sched_tx;
+	void		(*hn_txeof)(struct hn_tx_ring *);
+	struct taskqueue *hn_tx_taskq;
+	struct task	hn_tx_task;
+	struct task	hn_txeof_task;
+
+	struct buf_ring	*hn_mbuf_br;
+	int		hn_oactive;
+	int		hn_tx_idx;
+	int		hn_tx_flags;
+
+	struct mtx	hn_tx_lock;
+	struct hn_softc	*hn_sc;
+	struct vmbus_channel *hn_chan;
+
+	int		hn_direct_tx_size;
+	int		hn_chim_size;
+	bus_dma_tag_t	hn_tx_data_dtag;
+	uint64_t	hn_csum_assist;
+
+	int		(*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *);
+	int		hn_suspended;
+	int		hn_gpa_cnt;
+	struct vmbus_gpa hn_gpa[HN_GPACNT_MAX];
+
+	u_long		hn_no_txdescs;
+	u_long		hn_send_failed;
+	u_long		hn_txdma_failed;
+	u_long		hn_tx_collapsed;
+	u_long		hn_tx_chimney_tried;
+	u_long		hn_tx_chimney;
+	u_long		hn_pkts;
+
+	/* Rarely used stuffs */
+	struct hn_txdesc *hn_txdesc;
+	bus_dma_tag_t	hn_tx_rndis_dtag;
+	struct sysctl_oid *hn_tx_sysctl_tree;
+} __aligned(CACHE_LINE_SIZE);
+
+#define HN_TX_FLAG_ATTACHED	0x1
+#define HN_TX_FLAG_HASHVAL	0x2	/* support HASHVAL pktinfo */
+
+/*
+ * Device-specific softc structure
+ */
+struct hn_softc {
+	struct ifnet    *hn_ifp;
+	struct ifmedia	hn_media;
+	device_t        hn_dev;
+	int             hn_if_flags;
+	struct sx	hn_lock;
+	struct vmbus_channel *hn_prichan;
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611140319.uAE3JHeU049937>