From owner-svn-src-all@freebsd.org Thu Oct 27 05:13:01 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DFCD2C22AC0; Thu, 27 Oct 2016 05:13:01 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A68A7303; Thu, 27 Oct 2016 05:13:01 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9R5D0vL005822; Thu, 27 Oct 2016 05:13:00 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9R5D0uT005818; Thu, 27 Oct 2016 05:13:00 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610270513.u9R5D0uT005818@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 05:13:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r307989 - head/sys/dev/hyperv/netvsc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Oct 2016 05:13:02 -0000 Author: sephe Date: Thu Oct 27 05:13:00 2016 New Revision: 307989 URL: https://svnweb.freebsd.org/changeset/base/307989 Log: hyperv/hn: Move hn_softc to if_hnvar.h While I'm here, use consistent macro names. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8345 Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c head/sys/dev/hyperv/netvsc/hv_net_vsc.h head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c head/sys/dev/hyperv/netvsc/if_hnvar.h Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 27 05:04:54 2016 (r307988) +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 27 05:13:00 2016 (r307989) @@ -138,9 +138,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 +219,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 +266,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"); } Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 27 05:04:54 2016 (r307988) +++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 27 05:13:00 2016 (r307989) @@ -28,13 +28,6 @@ * $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__ @@ -64,224 +57,5 @@ #include -#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 - */ - -struct vmbus_channel; - -#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; -}; - -#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 - #endif /* __HV_NET_VSC_H__ */ Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 27 05:04:54 2016 (r307988) +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 27 05:13:00 2016 (r307989) @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -91,6 +92,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -116,11 +118,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include +#include +#include #include #include -#include #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 @@ -1855,7 +1860,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 +2636,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 +2670,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 +2686,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 +2833,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 +3093,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 +3511,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", @@ -4126,7 +4129,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 +4184,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 +4213,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 +4234,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: head/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- head/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 27 05:04:54 2016 (r307988) +++ head/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 27 05:13:00 2016 (r307989) @@ -29,14 +29,30 @@ #ifndef _IF_HNVAR_H_ #define _IF_HNVAR_H_ -#include +#define HN_USE_TXDESC_BUFRING -#include -#include +#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) + +/* Claimed to be 12232B */ +#define HN_MTU_MAX (9 * 1024) + +#define HN_PKTBUF_LEN 4096 + +#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 struct vmbus_channel; +struct hn_softc; struct hn_send_ctx; typedef void (*hn_sent_callback_t) @@ -48,6 +64,12 @@ struct hn_send_ctx { void *hn_cbarg; }; +#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ +{ \ + .hn_cb = cb, \ + .hn_cbarg = cbarg \ +} + #define HN_NDIS_VLAN_INFO_INVALID 0xffffffff #define HN_NDIS_RXCSUM_INFO_INVALID 0 #define HN_NDIS_HASH_INFO_INVALID 0 @@ -59,11 +81,185 @@ struct hn_recvinfo { uint32_t hash_value; }; -#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ -{ \ - .hn_cb = cb, \ - .hn_cbarg = cbarg \ -} +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; + + 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; +}; + +#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 static __inline void hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg)