svn commit: r308504 - stable/10/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Fri Nov 11 05:37:06 UTC 2016
Author: sephe
Date: Fri Nov 11 05:37:04 2016
New Revision: 308504
URL: https://svnweb.freebsd.org/changeset/base/308504
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/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_hnvar.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 Fri Nov 11 05:17:03 2016 (r308503)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Nov 11 05:37:04 2016 (r308504)
@@ -24,46 +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_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,
@@ -76,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;
@@ -87,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,
@@ -120,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
@@ -137,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.
@@ -218,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;
@@ -266,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");
}
@@ -604,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)
{
@@ -613,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)
{
@@ -670,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/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Nov 11 05:17:03 2016 (r308503)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Nov 11 05:37:04 2016 (r308504)
@@ -28,261 +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 arpcom arpcom;
- 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/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Nov 11 05:17:03 2016 (r308503)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Nov 11 05:37:04 2016 (r308504)
@@ -74,6 +74,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>
@@ -92,6 +93,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>
@@ -118,11 +120,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"
@@ -157,7 +162,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
@@ -171,7 +176,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;
@@ -409,37 +414,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));
}
@@ -1201,7 +1182,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;
@@ -1446,7 +1427,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;
}
@@ -1875,7 +1856,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;
}
@@ -2651,7 +2632,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");
@@ -2685,9 +2666,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");
@@ -2703,7 +2682,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;
@@ -2850,7 +2829,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;
@@ -3110,7 +3089,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");
@@ -3528,8 +3507,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",
@@ -4087,9 +4066,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));
/*
@@ -4146,7 +4125,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;
@@ -4201,9 +4180,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;
@@ -4230,7 +4209,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;
}
@@ -4251,7 +4230,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/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Nov 11 05:17:03 2016 (r308503)
+++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Nov 11 05:37:04 2016 (r308504)
@@ -35,26 +35,31 @@ __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
@@ -550,7 +555,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;
@@ -609,7 +614,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);
@@ -1215,7 +1220,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));
@@ -1229,7 +1234,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/10/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Nov 11 05:17:03 2016 (r308503)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Nov 11 05:37:04 2016 (r308504)
@@ -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,187 @@ 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 arpcom arpcom;
+ 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 ***
More information about the svn-src-stable
mailing list