Home | History | Annotate | Line # | Download | only in hyperv
if_hvn.c revision 1.27.2.1
      1  1.27.2.1  perseant /*	$NetBSD: if_hvn.c,v 1.27.2.1 2025/08/02 05:56:39 perseant Exp $	*/
      2       1.1    nonaka /*	$OpenBSD: if_hvn.c,v 1.39 2018/03/11 14:31:34 mikeb Exp $	*/
      3       1.1    nonaka 
      4       1.1    nonaka /*-
      5       1.1    nonaka  * Copyright (c) 2009-2012,2016 Microsoft Corp.
      6       1.1    nonaka  * Copyright (c) 2010-2012 Citrix Inc.
      7       1.1    nonaka  * Copyright (c) 2012 NetApp Inc.
      8       1.1    nonaka  * Copyright (c) 2016 Mike Belopuhov <mike (at) esdenera.com>
      9       1.1    nonaka  * All rights reserved.
     10       1.1    nonaka  *
     11       1.1    nonaka  * Redistribution and use in source and binary forms, with or without
     12       1.1    nonaka  * modification, are permitted provided that the following conditions
     13       1.1    nonaka  * are met:
     14       1.1    nonaka  * 1. Redistributions of source code must retain the above copyright
     15       1.1    nonaka  *    notice unmodified, this list of conditions, and the following
     16       1.1    nonaka  *    disclaimer.
     17       1.1    nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     18       1.1    nonaka  *    notice, this list of conditions and the following disclaimer in the
     19       1.1    nonaka  *    documentation and/or other materials provided with the distribution.
     20       1.1    nonaka  *
     21       1.1    nonaka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22       1.1    nonaka  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23       1.1    nonaka  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24       1.1    nonaka  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25       1.1    nonaka  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26       1.1    nonaka  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27       1.1    nonaka  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28       1.1    nonaka  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29       1.1    nonaka  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30       1.1    nonaka  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31       1.1    nonaka  */
     32       1.1    nonaka 
     33       1.1    nonaka /*
     34       1.1    nonaka  * The OpenBSD port was done under funding by Esdenera Networks GmbH.
     35       1.1    nonaka  */
     36       1.1    nonaka 
     37       1.1    nonaka #include <sys/cdefs.h>
     38  1.27.2.1  perseant __KERNEL_RCSID(0, "$NetBSD: if_hvn.c,v 1.27.2.1 2025/08/02 05:56:39 perseant Exp $");
     39       1.1    nonaka 
     40       1.1    nonaka #ifdef _KERNEL_OPT
     41      1.22    nonaka #include "opt_if_hvn.h"
     42       1.1    nonaka #include "opt_inet.h"
     43       1.1    nonaka #include "opt_inet6.h"
     44       1.1    nonaka #endif
     45       1.1    nonaka 
     46       1.1    nonaka #include <sys/param.h>
     47       1.1    nonaka #include <sys/systm.h>
     48       1.1    nonaka #include <sys/kernel.h>
     49       1.1    nonaka #include <sys/device.h>
     50      1.22    nonaka #include <sys/bitops.h>
     51       1.1    nonaka #include <sys/bus.h>
     52      1.22    nonaka #include <sys/condvar.h>
     53      1.22    nonaka #include <sys/cpu.h>
     54      1.22    nonaka #include <sys/evcnt.h>
     55       1.1    nonaka #include <sys/intr.h>
     56       1.1    nonaka #include <sys/kmem.h>
     57      1.22    nonaka #include <sys/kthread.h>
     58      1.22    nonaka #include <sys/mutex.h>
     59      1.22    nonaka #include <sys/pcq.h>
     60      1.22    nonaka #include <sys/sysctl.h>
     61      1.22    nonaka #include <sys/workqueue.h>
     62       1.1    nonaka 
     63       1.1    nonaka #include <net/if.h>
     64       1.1    nonaka #include <net/if_ether.h>
     65       1.1    nonaka #include <net/if_media.h>
     66      1.22    nonaka #include <net/if_vlanvar.h>
     67      1.22    nonaka #include <net/rss_config.h>
     68      1.22    nonaka #include <netinet/in.h>
     69      1.22    nonaka #include <netinet/ip.h>
     70      1.22    nonaka #include <netinet/ip6.h>
     71      1.22    nonaka #include <netinet/udp.h>
     72       1.1    nonaka 
     73       1.1    nonaka #include <net/bpf.h>
     74       1.1    nonaka 
     75       1.1    nonaka #include <dev/ic/ndisreg.h>
     76       1.1    nonaka #include <dev/ic/rndisreg.h>
     77       1.1    nonaka 
     78       1.1    nonaka #include <dev/hyperv/vmbusvar.h>
     79       1.1    nonaka #include <dev/hyperv/if_hvnreg.h>
     80       1.1    nonaka 
     81       1.1    nonaka #ifndef EVL_PRIO_BITS
     82       1.1    nonaka #define EVL_PRIO_BITS	13
     83       1.1    nonaka #endif
     84      1.15    nonaka #ifndef EVL_CFI_BITS
     85      1.15    nonaka #define EVL_CFI_BITS	12
     86      1.15    nonaka #endif
     87       1.1    nonaka 
     88      1.22    nonaka #define HVN_CHIM_SIZE			(15 * 1024 * 1024)
     89      1.22    nonaka 
     90       1.1    nonaka #define HVN_NVS_MSGSIZE			32
     91       1.1    nonaka #define HVN_NVS_BUFSIZE			PAGE_SIZE
     92       1.1    nonaka 
     93      1.22    nonaka #define HVN_RING_BUFSIZE		(128 * PAGE_SIZE)
     94      1.22    nonaka #define HVN_RING_IDX2CPU(sc, idx)	((idx) % ncpu)
     95      1.22    nonaka 
     96      1.22    nonaka #ifndef HVN_CHANNEL_MAX_COUNT_DEFAULT
     97      1.22    nonaka #define HVN_CHANNEL_MAX_COUNT_DEFAULT	8
     98      1.22    nonaka #endif
     99      1.22    nonaka 
    100      1.22    nonaka #ifndef HVN_LINK_STATE_CHANGE_DELAY
    101      1.22    nonaka #define HVN_LINK_STATE_CHANGE_DELAY	5000
    102      1.22    nonaka #endif
    103      1.22    nonaka 
    104      1.22    nonaka #define HVN_WORKQUEUE_PRI		PRI_SOFTNET
    105      1.22    nonaka 
    106       1.1    nonaka /*
    107       1.1    nonaka  * RNDIS control interface
    108       1.1    nonaka  */
    109       1.1    nonaka #define HVN_RNDIS_CTLREQS		4
    110       1.1    nonaka #define HVN_RNDIS_BUFSIZE		512
    111       1.1    nonaka 
    112       1.1    nonaka struct rndis_cmd {
    113       1.1    nonaka 	uint32_t			rc_id;
    114       1.1    nonaka 	struct hvn_nvs_rndis		rc_msg;
    115       1.1    nonaka 	void				*rc_req;
    116       1.1    nonaka 	bus_dmamap_t			rc_dmap;
    117       1.1    nonaka 	bus_dma_segment_t		rc_segs;
    118       1.1    nonaka 	int				rc_nsegs;
    119       1.1    nonaka 	uint64_t			rc_gpa;
    120       1.1    nonaka 	struct rndis_packet_msg		rc_cmp;
    121       1.1    nonaka 	uint32_t			rc_cmplen;
    122       1.1    nonaka 	uint8_t				rc_cmpbuf[HVN_RNDIS_BUFSIZE];
    123       1.1    nonaka 	int				rc_done;
    124       1.1    nonaka 	TAILQ_ENTRY(rndis_cmd)		rc_entry;
    125      1.22    nonaka 	kmutex_t			rc_lock;
    126      1.22    nonaka 	kcondvar_t			rc_cv;
    127       1.1    nonaka };
    128       1.1    nonaka TAILQ_HEAD(rndis_queue, rndis_cmd);
    129       1.1    nonaka 
    130      1.22    nonaka #define HVN_MTU_MIN			68
    131      1.22    nonaka #define HVN_MTU_MAX			(65535 - ETHER_ADDR_LEN)
    132       1.1    nonaka 
    133       1.1    nonaka #define HVN_RNDIS_XFER_SIZE		2048
    134       1.1    nonaka 
    135      1.22    nonaka #define HVN_NDIS_TXCSUM_CAP_IP4 \
    136      1.22    nonaka 	(NDIS_TXCSUM_CAP_IP4 | NDIS_TXCSUM_CAP_IP4OPT)
    137      1.22    nonaka #define HVN_NDIS_TXCSUM_CAP_TCP4 \
    138      1.22    nonaka 	(NDIS_TXCSUM_CAP_TCP4 | NDIS_TXCSUM_CAP_TCP4OPT)
    139      1.22    nonaka #define HVN_NDIS_TXCSUM_CAP_TCP6 \
    140      1.22    nonaka 	(NDIS_TXCSUM_CAP_TCP6 | NDIS_TXCSUM_CAP_TCP6OPT | \
    141      1.22    nonaka 	    NDIS_TXCSUM_CAP_IP6EXT)
    142      1.22    nonaka #define HVN_NDIS_TXCSUM_CAP_UDP6 \
    143      1.22    nonaka 	(NDIS_TXCSUM_CAP_UDP6 | NDIS_TXCSUM_CAP_IP6EXT)
    144      1.22    nonaka #define HVN_NDIS_LSOV2_CAP_IP6 \
    145      1.22    nonaka 	(NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT)
    146      1.22    nonaka 
    147      1.22    nonaka #define HVN_RNDIS_CMD_NORESP	__BIT(0)
    148      1.22    nonaka 
    149      1.22    nonaka #define HVN_NVS_CMD_NORESP	__BIT(0)
    150      1.22    nonaka 
    151       1.1    nonaka /*
    152       1.1    nonaka  * Tx ring
    153       1.1    nonaka  */
    154      1.22    nonaka #define HVN_TX_DESC			512
    155       1.1    nonaka #define HVN_TX_FRAGS			15		/* 31 is the max */
    156       1.1    nonaka #define HVN_TX_FRAG_SIZE		PAGE_SIZE
    157       1.1    nonaka #define HVN_TX_PKT_SIZE			16384
    158       1.1    nonaka 
    159       1.1    nonaka #define HVN_RNDIS_PKT_LEN					\
    160       1.1    nonaka 	(sizeof(struct rndis_packet_msg) +			\
    161       1.1    nonaka 	 sizeof(struct rndis_pktinfo) + NDIS_VLAN_INFO_SIZE +	\
    162       1.1    nonaka 	 sizeof(struct rndis_pktinfo) + NDIS_TXCSUM_INFO_SIZE)
    163       1.1    nonaka 
    164      1.22    nonaka #define HVN_PKTSIZE_MIN(align)						\
    165      1.22    nonaka 	roundup2(ETHER_MIN_LEN + ETHER_VLAN_ENCAP_LEN - ETHER_CRC_LEN +	\
    166      1.22    nonaka 	HVN_RNDIS_PKT_LEN, (align))
    167      1.22    nonaka #define HVN_PKTSIZE(m, align)						\
    168      1.22    nonaka 	roundup2((m)->m_pkthdr.len + HVN_RNDIS_PKT_LEN, (align))
    169      1.22    nonaka 
    170       1.1    nonaka struct hvn_tx_desc {
    171       1.1    nonaka 	uint32_t			txd_id;
    172       1.1    nonaka 	struct vmbus_gpa		txd_sgl[HVN_TX_FRAGS + 1];
    173       1.1    nonaka 	int				txd_nsge;
    174       1.1    nonaka 	struct mbuf			*txd_buf;
    175       1.1    nonaka 	bus_dmamap_t			txd_dmap;
    176       1.1    nonaka 	struct vmbus_gpa		txd_gpa;
    177       1.1    nonaka 	struct rndis_packet_msg		*txd_req;
    178      1.22    nonaka 	TAILQ_ENTRY(hvn_tx_desc)	txd_entry;
    179      1.22    nonaka 	u_int				txd_refs;
    180      1.22    nonaka 	uint32_t			txd_flags;
    181      1.22    nonaka #define HVN_TXD_FLAG_ONAGG		__BIT(0)
    182      1.22    nonaka #define HVN_TXD_FLAG_DMAMAP		__BIT(1)
    183      1.22    nonaka 	uint32_t			txd_chim_index;
    184      1.22    nonaka 	int				txd_chim_size;
    185      1.22    nonaka 	STAILQ_ENTRY(hvn_tx_desc)	txd_agg_entry;
    186      1.22    nonaka 	STAILQ_HEAD(, hvn_tx_desc)	txd_agg_list;
    187       1.1    nonaka };
    188       1.1    nonaka 
    189      1.22    nonaka struct hvn_softc;
    190      1.22    nonaka struct hvn_rx_ring;
    191      1.22    nonaka 
    192      1.22    nonaka struct hvn_tx_ring {
    193      1.22    nonaka 	struct hvn_softc		*txr_softc;
    194      1.22    nonaka 	struct vmbus_channel		*txr_chan;
    195      1.22    nonaka 	struct hvn_rx_ring		*txr_rxr;
    196      1.22    nonaka 	void				*txr_si;
    197      1.22    nonaka 	char				txr_name[16];
    198      1.22    nonaka 
    199      1.22    nonaka 	int				txr_id;
    200      1.22    nonaka 	int				txr_oactive;
    201      1.22    nonaka 	int				txr_suspended;
    202      1.22    nonaka 	int				txr_csum_assist;
    203      1.22    nonaka 	uint64_t			txr_caps_assist;
    204      1.22    nonaka 	uint32_t			txr_flags;
    205      1.22    nonaka #define HVN_TXR_FLAG_UDP_HASH		__BIT(0)
    206      1.22    nonaka 
    207      1.22    nonaka 	struct evcnt			txr_evpkts;
    208      1.22    nonaka 	struct evcnt			txr_evsends;
    209      1.22    nonaka 	struct evcnt			txr_evnodesc;
    210      1.22    nonaka 	struct evcnt			txr_evdmafailed;
    211      1.22    nonaka 	struct evcnt			txr_evdefrag;
    212      1.22    nonaka 	struct evcnt			txr_evpcqdrop;
    213      1.22    nonaka 	struct evcnt			txr_evtransmitdefer;
    214      1.22    nonaka 	struct evcnt			txr_evflushfailed;
    215      1.22    nonaka 	struct evcnt			txr_evchimneytried;
    216      1.22    nonaka 	struct evcnt			txr_evchimney;
    217      1.22    nonaka 	struct evcnt			txr_evvlanfixup;
    218      1.22    nonaka 	struct evcnt			txr_evvlanhwtagging;
    219      1.22    nonaka 	struct evcnt			txr_evvlantap;
    220      1.22    nonaka 
    221      1.22    nonaka 	kmutex_t			txr_lock;
    222      1.22    nonaka 	pcq_t				*txr_interq;
    223      1.22    nonaka 
    224      1.22    nonaka 	uint32_t			txr_avail;
    225      1.22    nonaka 	TAILQ_HEAD(, hvn_tx_desc)	txr_list;
    226      1.22    nonaka 	struct hvn_tx_desc		txr_desc[HVN_TX_DESC];
    227      1.22    nonaka 	uint8_t				*txr_msgs;
    228      1.22    nonaka 	struct hyperv_dma		txr_dma;
    229      1.22    nonaka 
    230      1.22    nonaka 	int				txr_chim_size;
    231      1.22    nonaka 
    232      1.22    nonaka 	/* Applied packet transmission aggregation limits. */
    233      1.22    nonaka 	int				txr_agg_szmax;
    234      1.22    nonaka 	short				txr_agg_pktmax;
    235      1.22    nonaka 	short				txr_agg_align;
    236      1.22    nonaka 
    237      1.22    nonaka 	/* Packet transmission aggregation states. */
    238      1.22    nonaka 	struct hvn_tx_desc		*txr_agg_txd;
    239      1.22    nonaka 	int				txr_agg_szleft;
    240      1.22    nonaka 	short				txr_agg_pktleft;
    241      1.22    nonaka 	struct rndis_packet_msg		*txr_agg_prevpkt;
    242      1.22    nonaka 
    243      1.22    nonaka 	/* Temporary stats for each sends. */
    244      1.22    nonaka 	int				txr_stat_pkts;
    245      1.22    nonaka 	int				txr_stat_size;
    246      1.22    nonaka 	int				txr_stat_mcasts;
    247      1.22    nonaka 
    248      1.22    nonaka 	int				(*txr_sendpkt)(struct hvn_tx_ring *,
    249      1.22    nonaka 					    struct hvn_tx_desc *);
    250      1.22    nonaka } __aligned(CACHE_LINE_SIZE);
    251      1.22    nonaka 
    252      1.22    nonaka struct hvn_rx_ring {
    253      1.22    nonaka 	struct hvn_softc		*rxr_softc;
    254      1.22    nonaka 	struct vmbus_channel		*rxr_chan;
    255      1.22    nonaka 	struct hvn_tx_ring		*rxr_txr;
    256      1.22    nonaka 	void				*rxr_si;
    257      1.22    nonaka 	bool				rxr_workqueue;
    258      1.22    nonaka 	char				rxr_name[16];
    259      1.22    nonaka 
    260      1.22    nonaka 	struct work			rxr_wk;
    261      1.22    nonaka 	volatile bool			rxr_onlist;
    262      1.22    nonaka 	volatile bool			rxr_onproc;
    263      1.22    nonaka 	kmutex_t			rxr_onwork_lock;
    264      1.22    nonaka 	kcondvar_t			rxr_onwork_cv;
    265      1.22    nonaka 
    266      1.22    nonaka 	uint32_t			rxr_flags;
    267      1.22    nonaka #define HVN_RXR_FLAG_UDP_HASH		__BIT(0)
    268      1.22    nonaka 
    269      1.22    nonaka 	kmutex_t			rxr_lock;
    270      1.22    nonaka 
    271      1.22    nonaka 	struct evcnt			rxr_evpkts;
    272      1.22    nonaka 	struct evcnt			rxr_evcsum_ip;
    273      1.22    nonaka 	struct evcnt			rxr_evcsum_tcp;
    274      1.22    nonaka 	struct evcnt			rxr_evcsum_udp;
    275      1.22    nonaka 	struct evcnt			rxr_evvlanhwtagging;
    276      1.22    nonaka 	struct evcnt			rxr_evintr;
    277      1.22    nonaka 	struct evcnt			rxr_evdefer;
    278      1.22    nonaka 	struct evcnt			rxr_evdeferreq;
    279      1.22    nonaka 	struct evcnt			rxr_evredeferreq;
    280      1.22    nonaka 
    281      1.22    nonaka 	/* NVS */
    282      1.22    nonaka 	uint8_t				*rxr_nvsbuf;
    283      1.22    nonaka } __aligned(CACHE_LINE_SIZE);
    284      1.22    nonaka 
    285       1.1    nonaka struct hvn_softc {
    286       1.1    nonaka 	device_t			sc_dev;
    287       1.1    nonaka 
    288       1.1    nonaka 	struct vmbus_softc		*sc_vmbus;
    289      1.22    nonaka 	struct vmbus_channel		*sc_prichan;
    290       1.1    nonaka 	bus_dma_tag_t			sc_dmat;
    291       1.1    nonaka 
    292       1.1    nonaka 	struct ethercom			sc_ec;
    293       1.1    nonaka 	struct ifmedia			sc_media;
    294       1.1    nonaka 	struct if_percpuq		*sc_ipq;
    295      1.22    nonaka 	struct workqueue		*sc_wq;
    296      1.22    nonaka 	bool				sc_txrx_workqueue;
    297      1.22    nonaka 	kmutex_t			sc_core_lock;
    298      1.22    nonaka 
    299      1.22    nonaka 	kmutex_t			sc_link_lock;
    300      1.22    nonaka 	kcondvar_t			sc_link_cv;
    301      1.22    nonaka 	callout_t			sc_link_tmout;
    302      1.22    nonaka 	lwp_t				*sc_link_lwp;
    303      1.22    nonaka 	uint32_t			sc_link_ev;
    304      1.22    nonaka #define HVN_LINK_EV_STATE_CHANGE	__BIT(0)
    305      1.22    nonaka #define HVN_LINK_EV_NETWORK_CHANGE_TMOUT __BIT(1)
    306      1.22    nonaka #define HVN_LINK_EV_NETWORK_CHANGE	__BIT(2)
    307      1.22    nonaka #define HVN_LINK_EV_RESUME_NETWORK	__BIT(3)
    308      1.22    nonaka #define HVN_LINK_EV_EXIT_THREAD		__BIT(4)
    309       1.1    nonaka 	int				sc_link_state;
    310      1.22    nonaka 	bool				sc_link_onproc;
    311      1.22    nonaka 	bool				sc_link_pending;
    312      1.22    nonaka 	bool				sc_link_suspend;
    313      1.22    nonaka 
    314      1.22    nonaka 	int				sc_tx_process_limit;
    315      1.22    nonaka 	int				sc_rx_process_limit;
    316      1.22    nonaka 	int				sc_tx_intr_process_limit;
    317      1.22    nonaka 	int				sc_rx_intr_process_limit;
    318      1.22    nonaka 
    319      1.22    nonaka 	struct sysctllog		*sc_sysctllog;
    320      1.22    nonaka 
    321      1.22    nonaka 	uint32_t			sc_caps;
    322      1.22    nonaka #define HVN_CAPS_VLAN			__BIT(0)
    323      1.22    nonaka #define HVN_CAPS_MTU			__BIT(1)
    324      1.22    nonaka #define HVN_CAPS_IPCS			__BIT(2)
    325      1.22    nonaka #define HVN_CAPS_TCP4CS			__BIT(3)
    326      1.22    nonaka #define HVN_CAPS_TCP6CS			__BIT(4)
    327      1.22    nonaka #define HVN_CAPS_UDP4CS			__BIT(5)
    328      1.22    nonaka #define HVN_CAPS_UDP6CS			__BIT(6)
    329      1.22    nonaka #define HVN_CAPS_TSO4			__BIT(7)
    330      1.22    nonaka #define HVN_CAPS_TSO6			__BIT(8)
    331      1.22    nonaka #define HVN_CAPS_HASHVAL		__BIT(9)
    332      1.22    nonaka #define HVN_CAPS_UDPHASH		__BIT(10)
    333       1.1    nonaka 
    334       1.1    nonaka 	uint32_t			sc_flags;
    335      1.22    nonaka #define HVN_SCF_ATTACHED		__BIT(0)
    336      1.22    nonaka #define HVN_SCF_RXBUF_CONNECTED		__BIT(1)
    337      1.22    nonaka #define HVN_SCF_CHIM_CONNECTED		__BIT(2)
    338      1.22    nonaka #define HVN_SCF_REVOKED			__BIT(3)
    339      1.22    nonaka #define HVN_SCF_HAS_RSSKEY		__BIT(4)
    340      1.22    nonaka #define HVN_SCF_HAS_RSSIND		__BIT(5)
    341       1.1    nonaka 
    342       1.1    nonaka 	/* NVS protocol */
    343       1.1    nonaka 	int				sc_proto;
    344       1.1    nonaka 	uint32_t			sc_nvstid;
    345       1.1    nonaka 	uint8_t				sc_nvsrsp[HVN_NVS_MSGSIZE];
    346       1.1    nonaka 	int				sc_nvsdone;
    347      1.22    nonaka 	kmutex_t			sc_nvsrsp_lock;
    348      1.22    nonaka 	kcondvar_t			sc_nvsrsp_cv;
    349       1.1    nonaka 
    350       1.1    nonaka 	/* RNDIS protocol */
    351       1.1    nonaka 	int				sc_ndisver;
    352       1.1    nonaka 	uint32_t			sc_rndisrid;
    353      1.22    nonaka 	int				sc_tso_szmax;
    354      1.22    nonaka 	int				sc_tso_sgmin;
    355      1.22    nonaka 	uint32_t			sc_rndis_agg_size;
    356      1.22    nonaka 	uint32_t			sc_rndis_agg_pkts;
    357      1.22    nonaka 	uint32_t			sc_rndis_agg_align;
    358       1.1    nonaka 	struct rndis_queue		sc_cntl_sq; /* submission queue */
    359       1.1    nonaka 	kmutex_t			sc_cntl_sqlck;
    360       1.1    nonaka 	struct rndis_queue		sc_cntl_cq; /* completion queue */
    361       1.1    nonaka 	kmutex_t			sc_cntl_cqlck;
    362       1.1    nonaka 	struct rndis_queue		sc_cntl_fq; /* free queue */
    363       1.1    nonaka 	kmutex_t			sc_cntl_fqlck;
    364      1.22    nonaka 	kcondvar_t			sc_cntl_fqcv;
    365       1.1    nonaka 	struct rndis_cmd		sc_cntl_msgs[HVN_RNDIS_CTLREQS];
    366       1.1    nonaka 	struct hvn_nvs_rndis		sc_data_msg;
    367       1.1    nonaka 
    368      1.22    nonaka 	int				sc_rss_ind_size;
    369      1.22    nonaka 	uint32_t			sc_rss_hash; /* setting, NDIS_HASH_ */
    370      1.22    nonaka 	uint32_t			sc_rss_hcap; /* caps, NDIS_HASH_ */
    371      1.22    nonaka 	struct ndis_rssprm_toeplitz	sc_rss;
    372      1.22    nonaka 
    373       1.1    nonaka 	/* Rx ring */
    374       1.1    nonaka 	uint8_t				*sc_rx_ring;
    375       1.1    nonaka 	int				sc_rx_size;
    376       1.1    nonaka 	uint32_t			sc_rx_hndl;
    377       1.1    nonaka 	struct hyperv_dma		sc_rx_dma;
    378      1.22    nonaka 	struct hvn_rx_ring		*sc_rxr;
    379      1.22    nonaka 	int				sc_nrxr;
    380      1.22    nonaka 	int				sc_nrxr_inuse;
    381       1.1    nonaka 
    382       1.1    nonaka 	/* Tx ring */
    383      1.22    nonaka 	struct hvn_tx_ring		*sc_txr;
    384      1.22    nonaka 	int				sc_ntxr;
    385      1.22    nonaka 	int				sc_ntxr_inuse;
    386      1.22    nonaka 
    387      1.22    nonaka 	/* chimney sending buffers */
    388      1.22    nonaka 	uint8_t				*sc_chim;
    389      1.22    nonaka 	uint32_t			sc_chim_hndl;
    390      1.22    nonaka 	struct hyperv_dma		sc_chim_dma;
    391      1.22    nonaka 	kmutex_t			sc_chim_bmap_lock;
    392      1.22    nonaka 	u_long				*sc_chim_bmap;
    393      1.22    nonaka 	int				sc_chim_bmap_cnt;
    394      1.22    nonaka 	int				sc_chim_cnt;
    395      1.22    nonaka 	int				sc_chim_szmax;
    396      1.22    nonaka 
    397      1.22    nonaka 	/* Packet transmission aggregation user settings. */
    398      1.22    nonaka 	int				sc_agg_size;
    399      1.22    nonaka 	int				sc_agg_pkts;
    400       1.1    nonaka };
    401       1.1    nonaka 
    402       1.1    nonaka #define SC2IFP(_sc_)	(&(_sc_)->sc_ec.ec_if)
    403       1.1    nonaka #define IFP2SC(_ifp_)	((_ifp_)->if_softc)
    404       1.1    nonaka 
    405      1.22    nonaka #ifndef HVN_TX_PROCESS_LIMIT_DEFAULT
    406      1.22    nonaka #define HVN_TX_PROCESS_LIMIT_DEFAULT		128
    407      1.22    nonaka #endif
    408      1.22    nonaka #ifndef HVN_RX_PROCESS_LIMIT_DEFAULT
    409      1.22    nonaka #define HVN_RX_PROCESS_LIMIT_DEFAULT		128
    410      1.22    nonaka #endif
    411      1.22    nonaka #ifndef HVN_TX_INTR_PROCESS_LIMIT_DEFAULT
    412      1.22    nonaka #define HVN_TX_INTR_PROCESS_LIMIT_DEFAULT	256
    413      1.22    nonaka #endif
    414      1.22    nonaka #ifndef HVN_RX_INTR_PROCESS_LIMIT_DEFAULT
    415      1.22    nonaka #define HVN_RX_INTR_PROCESS_LIMIT_DEFAULT	256
    416      1.22    nonaka #endif
    417      1.22    nonaka 
    418      1.22    nonaka /*
    419      1.22    nonaka  * See hvn_set_hlen().
    420      1.22    nonaka  *
    421      1.22    nonaka  * This value is for Azure.  For Hyper-V, set this above
    422      1.22    nonaka  * 65536 to disable UDP datagram checksum fixup.
    423      1.22    nonaka  */
    424      1.22    nonaka #ifndef HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT
    425      1.22    nonaka #define HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT	1420
    426      1.22    nonaka #endif
    427      1.22    nonaka static int hvn_udpcs_fixup_mtu = HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT;
    428      1.22    nonaka 
    429      1.22    nonaka /* Limit chimney send size */
    430      1.22    nonaka static int hvn_tx_chimney_size = 0;
    431      1.22    nonaka 
    432      1.22    nonaka /* # of channels to use; each channel has one RX ring and one TX ring */
    433      1.22    nonaka #ifndef HVN_CHANNEL_COUNT_DEFAULT
    434      1.22    nonaka #define HVN_CHANNEL_COUNT_DEFAULT	0
    435      1.22    nonaka #endif
    436      1.22    nonaka static int hvn_channel_cnt = HVN_CHANNEL_COUNT_DEFAULT;
    437      1.22    nonaka 
    438      1.22    nonaka /* # of transmit rings to use */
    439      1.22    nonaka #ifndef HVN_TX_RING_COUNT_DEFAULT
    440      1.22    nonaka #define HVN_TX_RING_COUNT_DEFAULT	0
    441      1.22    nonaka #endif
    442      1.22    nonaka static int hvn_tx_ring_cnt = HVN_TX_RING_COUNT_DEFAULT;
    443      1.22    nonaka 
    444      1.22    nonaka /* Packet transmission aggregation size limit */
    445      1.22    nonaka static int hvn_tx_agg_size = -1;
    446      1.22    nonaka 
    447      1.22    nonaka /* Packet transmission aggregation count limit */
    448      1.22    nonaka static int hvn_tx_agg_pkts = -1;
    449       1.1    nonaka 
    450       1.1    nonaka static int	hvn_match(device_t, cfdata_t, void *);
    451       1.1    nonaka static void	hvn_attach(device_t, device_t, void *);
    452       1.1    nonaka static int	hvn_detach(device_t, int);
    453       1.1    nonaka 
    454       1.1    nonaka CFATTACH_DECL_NEW(hvn, sizeof(struct hvn_softc),
    455       1.1    nonaka     hvn_match, hvn_attach, hvn_detach, NULL);
    456       1.1    nonaka 
    457       1.1    nonaka static int	hvn_ioctl(struct ifnet *, u_long, void *);
    458       1.1    nonaka static int	hvn_media_change(struct ifnet *);
    459       1.1    nonaka static void	hvn_media_status(struct ifnet *, struct ifmediareq *);
    460      1.22    nonaka static void	hvn_link_task(void *);
    461      1.22    nonaka static void	hvn_link_event(struct hvn_softc *, uint32_t);
    462      1.22    nonaka static void	hvn_link_netchg_tmout_cb(void *);
    463       1.1    nonaka static int	hvn_init(struct ifnet *);
    464      1.22    nonaka static int	hvn_init_locked(struct ifnet *);
    465       1.1    nonaka static void	hvn_stop(struct ifnet *, int);
    466      1.22    nonaka static void	hvn_stop_locked(struct ifnet *);
    467       1.1    nonaka static void	hvn_start(struct ifnet *);
    468      1.22    nonaka static int	hvn_transmit(struct ifnet *, struct mbuf *);
    469      1.22    nonaka static void	hvn_deferred_transmit(void *);
    470      1.22    nonaka static int	hvn_flush_txagg(struct hvn_tx_ring *);
    471      1.22    nonaka static int	hvn_encap(struct hvn_tx_ring *, struct hvn_tx_desc *,
    472      1.22    nonaka 		    struct mbuf *, int);
    473      1.22    nonaka static int	hvn_txpkt(struct hvn_tx_ring *, struct hvn_tx_desc *);
    474      1.22    nonaka static void	hvn_txeof(struct hvn_tx_ring *, uint64_t);
    475      1.22    nonaka static int	hvn_rx_ring_create(struct hvn_softc *, int);
    476       1.1    nonaka static int	hvn_rx_ring_destroy(struct hvn_softc *);
    477      1.22    nonaka static void	hvn_fixup_rx_data(struct hvn_softc *);
    478      1.22    nonaka static int	hvn_tx_ring_create(struct hvn_softc *, int);
    479       1.1    nonaka static void	hvn_tx_ring_destroy(struct hvn_softc *);
    480      1.22    nonaka static void	hvn_set_chim_size(struct hvn_softc *, int);
    481      1.22    nonaka static uint32_t	hvn_chim_alloc(struct hvn_softc *);
    482      1.22    nonaka static void	hvn_chim_free(struct hvn_softc *, uint32_t);
    483      1.22    nonaka static void	hvn_fixup_tx_data(struct hvn_softc *);
    484      1.22    nonaka static struct mbuf *
    485      1.22    nonaka 		hvn_set_hlen(struct mbuf *, int *);
    486      1.22    nonaka static int	hvn_txd_peek(struct hvn_tx_ring *);
    487      1.22    nonaka static struct hvn_tx_desc *
    488      1.22    nonaka 		hvn_txd_get(struct hvn_tx_ring *);
    489      1.22    nonaka static void	hvn_txd_put(struct hvn_tx_ring *, struct hvn_tx_desc *);
    490      1.22    nonaka static void	hvn_txd_gc(struct hvn_tx_ring *, struct hvn_tx_desc *);
    491      1.22    nonaka static void	hvn_txd_hold(struct hvn_tx_desc *);
    492      1.22    nonaka static void	hvn_txd_agg(struct hvn_tx_desc *, struct hvn_tx_desc *);
    493      1.22    nonaka static int	hvn_tx_ring_pending(struct hvn_tx_ring *);
    494      1.22    nonaka static void	hvn_tx_ring_qflush(struct hvn_softc *, struct hvn_tx_ring *);
    495      1.22    nonaka static int	hvn_get_rsscaps(struct hvn_softc *, int *);
    496      1.22    nonaka static int	hvn_set_rss(struct hvn_softc *, uint16_t);
    497      1.22    nonaka static void	hvn_fixup_rss_ind(struct hvn_softc *);
    498      1.22    nonaka static int	hvn_get_hwcaps(struct hvn_softc *, struct ndis_offload *);
    499      1.22    nonaka static int	hvn_set_capabilities(struct hvn_softc *, int);
    500       1.1    nonaka static int	hvn_get_lladdr(struct hvn_softc *, uint8_t *);
    501      1.22    nonaka static void	hvn_update_link_status(struct hvn_softc *);
    502      1.22    nonaka static int	hvn_get_mtu(struct hvn_softc *, uint32_t *);
    503      1.22    nonaka static int	hvn_channel_attach(struct hvn_softc *, struct vmbus_channel *);
    504      1.22    nonaka static void	hvn_channel_detach(struct hvn_softc *, struct vmbus_channel *);
    505      1.22    nonaka static void	hvn_channel_detach_all(struct hvn_softc *);
    506      1.22    nonaka static int	hvn_subchannel_attach(struct hvn_softc *);
    507      1.22    nonaka static int	hvn_synth_alloc_subchannels(struct hvn_softc *, int *);
    508      1.22    nonaka static int	hvn_synth_attachable(const struct hvn_softc *);
    509      1.22    nonaka static int	hvn_synth_attach(struct hvn_softc *, int);
    510      1.22    nonaka static void	hvn_synth_detach(struct hvn_softc *);
    511      1.22    nonaka static void	hvn_set_ring_inuse(struct hvn_softc *, int);
    512      1.22    nonaka static void	hvn_disable_rx(struct hvn_softc *);
    513      1.22    nonaka static void	hvn_drain_rxtx(struct hvn_softc *, int );
    514      1.22    nonaka static void	hvn_suspend_data(struct hvn_softc *);
    515      1.22    nonaka static void	hvn_suspend_mgmt(struct hvn_softc *);
    516      1.22    nonaka static void	hvn_suspend(struct hvn_softc *) __unused;
    517      1.22    nonaka static void	hvn_resume_tx(struct hvn_softc *, int);
    518      1.22    nonaka static void	hvn_resume_data(struct hvn_softc *);
    519      1.22    nonaka static void	hvn_resume_mgmt(struct hvn_softc *);
    520      1.22    nonaka static void	hvn_resume(struct hvn_softc *) __unused;
    521      1.22    nonaka static void	hvn_init_sysctls(struct hvn_softc *);
    522       1.1    nonaka 
    523       1.1    nonaka /* NSVP */
    524      1.22    nonaka static int	hvn_nvs_init(struct hvn_softc *);
    525      1.22    nonaka static void	hvn_nvs_destroy(struct hvn_softc *);
    526      1.22    nonaka static int	hvn_nvs_attach(struct hvn_softc *, int);
    527      1.22    nonaka static int	hvn_nvs_connect_rxbuf(struct hvn_softc *);
    528      1.22    nonaka static int	hvn_nvs_disconnect_rxbuf(struct hvn_softc *);
    529      1.22    nonaka static int	hvn_nvs_connect_chim(struct hvn_softc *);
    530      1.22    nonaka static int	hvn_nvs_disconnect_chim(struct hvn_softc *);
    531      1.22    nonaka static void	hvn_handle_ring_work(struct work *, void *);
    532      1.22    nonaka static void	hvn_nvs_softintr(void *);
    533       1.1    nonaka static void	hvn_nvs_intr(void *);
    534      1.22    nonaka static void	hvn_nvs_intr1(struct hvn_rx_ring *, int, int);
    535      1.22    nonaka static int	hvn_nvs_cmd(struct hvn_softc *, void *, size_t, uint64_t,
    536      1.22    nonaka 		    u_int);
    537      1.22    nonaka static int	hvn_nvs_ack(struct hvn_rx_ring *, uint64_t);
    538       1.1    nonaka static void	hvn_nvs_detach(struct hvn_softc *);
    539      1.22    nonaka static int	hvn_nvs_alloc_subchannels(struct hvn_softc *, int *);
    540       1.1    nonaka 
    541       1.1    nonaka /* RNDIS */
    542      1.22    nonaka static int	hvn_rndis_init(struct hvn_softc *);
    543      1.22    nonaka static void	hvn_rndis_destroy(struct hvn_softc *);
    544      1.22    nonaka static int	hvn_rndis_attach(struct hvn_softc *, int);
    545      1.22    nonaka static int	hvn_rndis_cmd(struct hvn_softc *, struct rndis_cmd *, u_int);
    546      1.22    nonaka static int	hvn_rndis_input(struct hvn_rx_ring *, uint64_t, void *);
    547      1.22    nonaka static int	hvn_rxeof(struct hvn_rx_ring *, uint8_t *, uint32_t);
    548       1.1    nonaka static void	hvn_rndis_complete(struct hvn_softc *, uint8_t *, uint32_t);
    549      1.22    nonaka static int	hvn_rndis_output_sgl(struct hvn_tx_ring *,
    550      1.22    nonaka 		    struct hvn_tx_desc *);
    551      1.22    nonaka static int	hvn_rndis_output_chim(struct hvn_tx_ring *,
    552      1.22    nonaka 		    struct hvn_tx_desc *);
    553       1.1    nonaka static void	hvn_rndis_status(struct hvn_softc *, uint8_t *, uint32_t);
    554       1.1    nonaka static int	hvn_rndis_query(struct hvn_softc *, uint32_t, void *, size_t *);
    555      1.22    nonaka static int	hvn_rndis_query2(struct hvn_softc *, uint32_t, const void *,
    556      1.22    nonaka 		    size_t, void *, size_t *, size_t);
    557       1.1    nonaka static int	hvn_rndis_set(struct hvn_softc *, uint32_t, void *, size_t);
    558       1.1    nonaka static int	hvn_rndis_open(struct hvn_softc *);
    559       1.1    nonaka static int	hvn_rndis_close(struct hvn_softc *);
    560       1.1    nonaka static void	hvn_rndis_detach(struct hvn_softc *);
    561       1.1    nonaka 
    562       1.1    nonaka static int
    563       1.1    nonaka hvn_match(device_t parent, cfdata_t match, void *aux)
    564       1.1    nonaka {
    565       1.1    nonaka 	struct vmbus_attach_args *aa = aux;
    566       1.1    nonaka 
    567       1.1    nonaka 	if (memcmp(aa->aa_type, &hyperv_guid_network, sizeof(*aa->aa_type)))
    568       1.1    nonaka 		return 0;
    569       1.1    nonaka 	return 1;
    570       1.1    nonaka }
    571       1.1    nonaka 
    572       1.1    nonaka static void
    573       1.1    nonaka hvn_attach(device_t parent, device_t self, void *aux)
    574       1.1    nonaka {
    575       1.1    nonaka 	struct hvn_softc *sc = device_private(self);
    576       1.1    nonaka 	struct vmbus_attach_args *aa = aux;
    577       1.1    nonaka 	struct ifnet *ifp = SC2IFP(sc);
    578      1.22    nonaka 	char xnamebuf[32];
    579       1.1    nonaka 	uint8_t enaddr[ETHER_ADDR_LEN];
    580      1.22    nonaka 	uint32_t mtu;
    581      1.22    nonaka 	int tx_ring_cnt, ring_cnt;
    582      1.22    nonaka 	int error;
    583       1.1    nonaka 
    584       1.1    nonaka 	sc->sc_dev = self;
    585       1.1    nonaka 	sc->sc_vmbus = (struct vmbus_softc *)device_private(parent);
    586      1.22    nonaka 	sc->sc_prichan = aa->aa_chan;
    587       1.1    nonaka 	sc->sc_dmat = sc->sc_vmbus->sc_dmat;
    588       1.1    nonaka 
    589       1.1    nonaka 	aprint_naive("\n");
    590       1.1    nonaka 	aprint_normal(": Hyper-V NetVSC\n");
    591       1.1    nonaka 
    592      1.22    nonaka 	sc->sc_txrx_workqueue = true;
    593      1.22    nonaka 	sc->sc_tx_process_limit = HVN_TX_PROCESS_LIMIT_DEFAULT;
    594      1.22    nonaka 	sc->sc_rx_process_limit = HVN_RX_PROCESS_LIMIT_DEFAULT;
    595      1.22    nonaka 	sc->sc_tx_intr_process_limit = HVN_TX_INTR_PROCESS_LIMIT_DEFAULT;
    596      1.22    nonaka 	sc->sc_rx_intr_process_limit = HVN_RX_INTR_PROCESS_LIMIT_DEFAULT;
    597      1.22    nonaka 	sc->sc_agg_size = hvn_tx_agg_size;
    598      1.22    nonaka 	sc->sc_agg_pkts = hvn_tx_agg_pkts;
    599      1.22    nonaka 
    600      1.22    nonaka 	mutex_init(&sc->sc_core_lock, MUTEX_DEFAULT, IPL_SOFTNET);
    601      1.22    nonaka 	mutex_init(&sc->sc_link_lock, MUTEX_DEFAULT, IPL_NET);
    602      1.22    nonaka 	cv_init(&sc->sc_link_cv, "hvnknkcv");
    603      1.22    nonaka 	callout_init(&sc->sc_link_tmout, CALLOUT_MPSAFE);
    604      1.22    nonaka 	callout_setfunc(&sc->sc_link_tmout, hvn_link_netchg_tmout_cb, sc);
    605      1.22    nonaka 	if (kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL,
    606      1.22    nonaka 	    hvn_link_task, sc, &sc->sc_link_lwp, "%slink",
    607      1.22    nonaka 	    device_xname(self))) {
    608      1.22    nonaka 		aprint_error_dev(self, "failed to create link thread\n");
    609       1.1    nonaka 		return;
    610       1.1    nonaka 	}
    611       1.1    nonaka 
    612      1.22    nonaka 	snprintf(xnamebuf, sizeof(xnamebuf), "%srxtx", device_xname(self));
    613      1.22    nonaka 	if (workqueue_create(&sc->sc_wq, xnamebuf, hvn_handle_ring_work,
    614      1.22    nonaka 	    sc, HVN_WORKQUEUE_PRI, IPL_NET, WQ_PERCPU | WQ_MPSAFE)) {
    615      1.22    nonaka 		aprint_error_dev(self, "failed to create workqueue\n");
    616      1.22    nonaka 		sc->sc_wq = NULL;
    617      1.22    nonaka 		goto destroy_link_thread;
    618      1.22    nonaka 	}
    619      1.22    nonaka 
    620      1.22    nonaka 	ring_cnt = hvn_channel_cnt;
    621      1.22    nonaka 	if (ring_cnt <= 0) {
    622      1.22    nonaka 		ring_cnt = ncpu;
    623      1.22    nonaka 		if (ring_cnt > HVN_CHANNEL_MAX_COUNT_DEFAULT)
    624      1.22    nonaka 			ring_cnt = HVN_CHANNEL_MAX_COUNT_DEFAULT;
    625      1.22    nonaka 	} else if (ring_cnt > ncpu)
    626      1.22    nonaka 		ring_cnt = ncpu;
    627      1.22    nonaka 
    628      1.22    nonaka 	tx_ring_cnt = hvn_tx_ring_cnt;
    629      1.22    nonaka 	if (tx_ring_cnt <= 0 || tx_ring_cnt > ring_cnt)
    630      1.22    nonaka 		tx_ring_cnt = ring_cnt;
    631      1.22    nonaka 
    632      1.22    nonaka 	if (hvn_tx_ring_create(sc, tx_ring_cnt)) {
    633      1.22    nonaka 		aprint_error_dev(self, "failed to create Tx ring\n");
    634      1.22    nonaka 		goto destroy_wq;
    635       1.1    nonaka 	}
    636       1.1    nonaka 
    637      1.22    nonaka 	if (hvn_rx_ring_create(sc, ring_cnt)) {
    638      1.22    nonaka 		aprint_error_dev(self, "failed to create Rx ring\n");
    639      1.22    nonaka 		goto destroy_tx_ring;
    640       1.1    nonaka 	}
    641       1.1    nonaka 
    642      1.13    nonaka 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    643       1.1    nonaka 	ifp->if_softc = sc;
    644       1.1    nonaka 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    645      1.22    nonaka 	ifp->if_extflags = IFEF_MPSAFE;
    646       1.1    nonaka 	ifp->if_ioctl = hvn_ioctl;
    647       1.1    nonaka 	ifp->if_start = hvn_start;
    648      1.22    nonaka 	ifp->if_transmit = hvn_transmit;
    649       1.1    nonaka 	ifp->if_init = hvn_init;
    650       1.1    nonaka 	ifp->if_stop = hvn_stop;
    651      1.22    nonaka 	ifp->if_baudrate = IF_Gbps(10);
    652       1.1    nonaka 
    653      1.22    nonaka 	IFQ_SET_MAXLEN(&ifp->if_snd, uimax(HVN_TX_DESC - 1, IFQ_MAXLEN));
    654       1.1    nonaka 	IFQ_SET_READY(&ifp->if_snd);
    655       1.1    nonaka 
    656       1.3   msaitoh 	/* Initialize ifmedia structures. */
    657       1.3   msaitoh 	sc->sc_ec.ec_ifmedia = &sc->sc_media;
    658      1.18    nonaka 	ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK,
    659      1.22    nonaka 	    hvn_media_change, hvn_media_status, &sc->sc_core_lock);
    660      1.22    nonaka 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
    661      1.22    nonaka 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10G_T | IFM_FDX, 0, NULL);
    662      1.22    nonaka 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10G_T, 0, NULL);
    663      1.22    nonaka 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
    664       1.1    nonaka 
    665      1.21  riastrad 	if_initialize(ifp);
    666       1.1    nonaka 	sc->sc_ipq = if_percpuq_create(ifp);
    667       1.1    nonaka 	if_deferred_start_init(ifp, NULL);
    668       1.1    nonaka 
    669      1.22    nonaka 	hvn_nvs_init(sc);
    670      1.22    nonaka 	hvn_rndis_init(sc);
    671      1.22    nonaka 	if (hvn_synth_attach(sc, ETHERMTU)) {
    672      1.22    nonaka 		aprint_error_dev(self, "failed to attach synth\n");
    673      1.22    nonaka 		goto destroy_if_percpuq;
    674       1.1    nonaka 	}
    675       1.1    nonaka 
    676       1.1    nonaka 	aprint_normal_dev(self, "NVS %d.%d NDIS %d.%d\n",
    677       1.1    nonaka 	    sc->sc_proto >> 16, sc->sc_proto & 0xffff,
    678       1.1    nonaka 	    sc->sc_ndisver >> 16 , sc->sc_ndisver & 0xffff);
    679       1.1    nonaka 
    680       1.1    nonaka 	if (hvn_get_lladdr(sc, enaddr)) {
    681       1.1    nonaka 		aprint_error_dev(self,
    682       1.1    nonaka 		    "failed to obtain an ethernet address\n");
    683      1.22    nonaka 		goto detach_synth;
    684       1.1    nonaka 	}
    685       1.1    nonaka 	aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(enaddr));
    686       1.1    nonaka 
    687      1.22    nonaka 	/*
    688      1.22    nonaka 	 * Fixup TX/RX stuffs after synthetic parts are attached.
    689      1.22    nonaka 	 */
    690      1.22    nonaka 	hvn_fixup_tx_data(sc);
    691      1.22    nonaka 	hvn_fixup_rx_data(sc);
    692      1.22    nonaka 
    693      1.22    nonaka 	ifp->if_capabilities |= sc->sc_txr[0].txr_caps_assist &
    694      1.22    nonaka 		(IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
    695      1.22    nonaka 		 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
    696      1.22    nonaka 		 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
    697      1.22    nonaka 		 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
    698      1.22    nonaka 		 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx);
    699      1.22    nonaka 	/* XXX TSOv4, TSOv6 */
    700      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_VLAN) {
    701      1.22    nonaka 		/* XXX not sure about VLAN_MTU. */
    702      1.22    nonaka 		sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
    703      1.22    nonaka 		sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
    704      1.22    nonaka 	}
    705      1.22    nonaka 	sc->sc_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU;
    706      1.22    nonaka 
    707       1.1    nonaka 	ether_ifattach(ifp, enaddr);
    708      1.22    nonaka 
    709      1.22    nonaka 	error = hvn_get_mtu(sc, &mtu);
    710      1.22    nonaka 	if (error)
    711      1.22    nonaka 		mtu = ETHERMTU;
    712      1.22    nonaka 	if (mtu < ETHERMTU) {
    713      1.22    nonaka 		DPRINTF("%s: fixup mtu %u -> %u\n", device_xname(sc->sc_dev),
    714      1.22    nonaka 		    ETHERMTU, mtu);
    715      1.22    nonaka 		ifp->if_mtu = mtu;
    716      1.22    nonaka 	}
    717      1.22    nonaka 
    718       1.1    nonaka 	if_register(ifp);
    719       1.1    nonaka 
    720      1.22    nonaka 	/*
    721      1.22    nonaka 	 * Kick off link status check.
    722      1.22    nonaka 	 */
    723      1.22    nonaka 	hvn_link_event(sc, HVN_LINK_EV_STATE_CHANGE);
    724      1.22    nonaka 
    725      1.22    nonaka 	hvn_init_sysctls(sc);
    726      1.22    nonaka 
    727       1.1    nonaka 	if (pmf_device_register(self, NULL, NULL))
    728       1.1    nonaka 		pmf_class_network_register(self, ifp);
    729       1.1    nonaka 	else
    730       1.1    nonaka 		aprint_error_dev(self, "couldn't establish power handler\n");
    731       1.1    nonaka 
    732       1.1    nonaka 	SET(sc->sc_flags, HVN_SCF_ATTACHED);
    733       1.1    nonaka 	return;
    734       1.1    nonaka 
    735      1.22    nonaka detach_synth:
    736      1.22    nonaka 	hvn_synth_detach(sc);
    737      1.22    nonaka 	hvn_rndis_destroy(sc);
    738      1.22    nonaka 	hvn_nvs_destroy(sc);
    739      1.22    nonaka destroy_if_percpuq:
    740      1.13    nonaka 	if_percpuq_destroy(sc->sc_ipq);
    741      1.22    nonaka 	hvn_rx_ring_destroy(sc);
    742      1.22    nonaka destroy_tx_ring:
    743      1.18    nonaka 	hvn_tx_ring_destroy(sc);
    744      1.22    nonaka destroy_wq:
    745      1.22    nonaka 	workqueue_destroy(sc->sc_wq);
    746      1.22    nonaka 	sc->sc_wq = NULL;
    747      1.22    nonaka destroy_link_thread:
    748      1.22    nonaka 	hvn_link_event(sc, HVN_LINK_EV_EXIT_THREAD);
    749      1.22    nonaka 	kthread_join(sc->sc_link_lwp);
    750      1.22    nonaka 	callout_destroy(&sc->sc_link_tmout);
    751      1.22    nonaka 	cv_destroy(&sc->sc_link_cv);
    752      1.22    nonaka 	mutex_destroy(&sc->sc_link_lock);
    753      1.22    nonaka 	mutex_destroy(&sc->sc_core_lock);
    754       1.1    nonaka }
    755       1.1    nonaka 
    756       1.1    nonaka static int
    757       1.1    nonaka hvn_detach(device_t self, int flags)
    758       1.1    nonaka {
    759       1.1    nonaka 	struct hvn_softc *sc = device_private(self);
    760       1.1    nonaka 	struct ifnet *ifp = SC2IFP(sc);
    761       1.1    nonaka 
    762       1.1    nonaka 	if (!ISSET(sc->sc_flags, HVN_SCF_ATTACHED))
    763       1.1    nonaka 		return 0;
    764       1.1    nonaka 
    765      1.22    nonaka 	if (vmbus_channel_is_revoked(sc->sc_prichan))
    766      1.22    nonaka 		SET(sc->sc_flags, HVN_SCF_REVOKED);
    767       1.1    nonaka 
    768       1.1    nonaka 	pmf_device_deregister(self);
    769       1.1    nonaka 
    770      1.22    nonaka 	mutex_enter(&sc->sc_core_lock);
    771      1.22    nonaka 
    772      1.22    nonaka 	if (ifp->if_flags & IFF_RUNNING)
    773      1.22    nonaka 		hvn_stop_locked(ifp);
    774      1.22    nonaka 	/*
    775      1.22    nonaka 	 * NOTE:
    776      1.27    andvar 	 * hvn_stop() only suspends data, so management
    777      1.22    nonaka 	 * stuffs have to be suspended manually here.
    778      1.22    nonaka 	 */
    779      1.22    nonaka 	hvn_suspend_mgmt(sc);
    780      1.22    nonaka 
    781       1.1    nonaka 	ether_ifdetach(ifp);
    782       1.1    nonaka 	if_detach(ifp);
    783       1.1    nonaka 	if_percpuq_destroy(sc->sc_ipq);
    784       1.1    nonaka 
    785      1.22    nonaka 	hvn_link_event(sc, HVN_LINK_EV_EXIT_THREAD);
    786      1.22    nonaka 	kthread_join(sc->sc_link_lwp);
    787      1.22    nonaka 	callout_halt(&sc->sc_link_tmout, NULL);
    788      1.22    nonaka 
    789      1.22    nonaka 	hvn_synth_detach(sc);
    790      1.22    nonaka 	hvn_rndis_destroy(sc);
    791      1.22    nonaka 	hvn_nvs_destroy(sc);
    792      1.22    nonaka 
    793      1.22    nonaka 	mutex_exit(&sc->sc_core_lock);
    794      1.22    nonaka 
    795       1.1    nonaka 	hvn_rx_ring_destroy(sc);
    796       1.1    nonaka 	hvn_tx_ring_destroy(sc);
    797      1.22    nonaka 
    798      1.22    nonaka 	workqueue_destroy(sc->sc_wq);
    799      1.22    nonaka 	callout_destroy(&sc->sc_link_tmout);
    800      1.22    nonaka 	cv_destroy(&sc->sc_link_cv);
    801      1.22    nonaka 	mutex_destroy(&sc->sc_link_lock);
    802      1.22    nonaka 	mutex_destroy(&sc->sc_core_lock);
    803      1.22    nonaka 
    804      1.22    nonaka 	sysctl_teardown(&sc->sc_sysctllog);
    805       1.1    nonaka 
    806       1.1    nonaka 	return 0;
    807       1.1    nonaka }
    808       1.1    nonaka 
    809       1.1    nonaka static int
    810       1.1    nonaka hvn_ioctl(struct ifnet *ifp, u_long command, void * data)
    811       1.1    nonaka {
    812       1.1    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
    813      1.22    nonaka 	struct ifreq *ifr = (struct ifreq *)data;
    814      1.22    nonaka 	uint32_t mtu;
    815       1.1    nonaka 	int s, error = 0;
    816       1.1    nonaka 
    817      1.22    nonaka 	switch (command) {
    818      1.22    nonaka 	case SIOCSIFMTU:
    819      1.22    nonaka 		if (ifr->ifr_mtu < HVN_MTU_MIN || ifr->ifr_mtu > HVN_MTU_MAX) {
    820      1.22    nonaka 			error = EINVAL;
    821      1.22    nonaka 			break;
    822      1.22    nonaka 		}
    823      1.22    nonaka 
    824      1.22    nonaka 		mutex_enter(&sc->sc_core_lock);
    825      1.22    nonaka 
    826      1.22    nonaka 		if (!(sc->sc_caps & HVN_CAPS_MTU)) {
    827      1.22    nonaka 			/* Can't change MTU */
    828      1.22    nonaka 			mutex_exit(&sc->sc_core_lock);
    829      1.22    nonaka 			error = EOPNOTSUPP;
    830      1.22    nonaka 			break;
    831      1.22    nonaka 		}
    832      1.22    nonaka 
    833      1.22    nonaka 		if (ifp->if_mtu == ifr->ifr_mtu) {
    834      1.22    nonaka 			mutex_exit(&sc->sc_core_lock);
    835      1.22    nonaka 			break;
    836      1.22    nonaka 		}
    837      1.22    nonaka 
    838      1.22    nonaka 		/*
    839      1.22    nonaka 		 * Suspend this interface before the synthetic parts
    840      1.22    nonaka 		 * are ripped.
    841      1.22    nonaka 		 */
    842      1.22    nonaka 		hvn_suspend(sc);
    843      1.22    nonaka 
    844      1.22    nonaka 		/*
    845      1.22    nonaka 		 * Detach the synthetics parts, i.e. NVS and RNDIS.
    846      1.22    nonaka 		 */
    847      1.22    nonaka 		hvn_synth_detach(sc);
    848      1.22    nonaka 
    849      1.22    nonaka 		/*
    850      1.22    nonaka 		 * Reattach the synthetic parts, i.e. NVS and RNDIS,
    851      1.22    nonaka 		 * with the new MTU setting.
    852      1.22    nonaka 		 */
    853      1.22    nonaka 		error = hvn_synth_attach(sc, ifr->ifr_mtu);
    854      1.22    nonaka 		if (error) {
    855      1.22    nonaka 			mutex_exit(&sc->sc_core_lock);
    856      1.22    nonaka 			break;
    857      1.22    nonaka 		}
    858       1.1    nonaka 
    859      1.22    nonaka 		error = hvn_get_mtu(sc, &mtu);
    860      1.22    nonaka 		if (error)
    861      1.22    nonaka 			mtu = ifr->ifr_mtu;
    862      1.22    nonaka 		DPRINTF("%s: RNDIS mtu=%d\n", device_xname(sc->sc_dev), mtu);
    863      1.22    nonaka 
    864      1.22    nonaka 		/*
    865      1.22    nonaka 		 * Commit the requested MTU, after the synthetic parts
    866      1.22    nonaka 		 * have been successfully attached.
    867      1.22    nonaka 		 */
    868      1.22    nonaka 		if (mtu >= ifr->ifr_mtu) {
    869      1.22    nonaka 			mtu = ifr->ifr_mtu;
    870      1.22    nonaka 		} else {
    871      1.22    nonaka 			DPRINTF("%s: fixup mtu %d -> %u\n",
    872      1.22    nonaka 			    device_xname(sc->sc_dev), ifr->ifr_mtu, mtu);
    873      1.22    nonaka 		}
    874      1.22    nonaka 		ifp->if_mtu = mtu;
    875      1.22    nonaka 
    876      1.22    nonaka 		/*
    877      1.22    nonaka 		 * Synthetic parts' reattach may change the chimney
    878      1.22    nonaka 		 * sending size; update it.
    879      1.22    nonaka 		 */
    880      1.22    nonaka 		if (sc->sc_txr[0].txr_chim_size > sc->sc_chim_szmax)
    881      1.22    nonaka 			hvn_set_chim_size(sc, sc->sc_chim_szmax);
    882      1.22    nonaka 
    883      1.22    nonaka 		/*
    884      1.22    nonaka 		 * All done!  Resume the interface now.
    885      1.22    nonaka 		 */
    886      1.22    nonaka 		hvn_resume(sc);
    887      1.22    nonaka 
    888      1.22    nonaka 		mutex_exit(&sc->sc_core_lock);
    889      1.22    nonaka 		break;
    890      1.22    nonaka 	default:
    891      1.22    nonaka 		s = splnet();
    892      1.22    nonaka 		if (command == SIOCGIFMEDIA || command == SIOCSIFMEDIA)
    893      1.22    nonaka 			error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
    894      1.22    nonaka 		else
    895      1.22    nonaka 			error = ether_ioctl(ifp, command, data);
    896      1.22    nonaka 		splx(s);
    897      1.22    nonaka 		if (error == ENETRESET) {
    898      1.22    nonaka 			mutex_enter(&sc->sc_core_lock);
    899      1.22    nonaka 			if (ifp->if_flags & IFF_RUNNING)
    900      1.22    nonaka 				hvn_init_locked(ifp);
    901      1.22    nonaka 			mutex_exit(&sc->sc_core_lock);
    902      1.22    nonaka 			error = 0;
    903      1.22    nonaka 		}
    904      1.22    nonaka 		break;
    905       1.1    nonaka 	}
    906       1.1    nonaka 
    907       1.1    nonaka 	return error;
    908       1.1    nonaka }
    909       1.1    nonaka 
    910       1.1    nonaka static int
    911       1.1    nonaka hvn_media_change(struct ifnet *ifp)
    912       1.1    nonaka {
    913      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
    914      1.22    nonaka 	struct ifmedia *ifm = &sc->sc_media;
    915       1.1    nonaka 
    916      1.22    nonaka 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
    917      1.22    nonaka 		return EINVAL;
    918      1.22    nonaka 
    919      1.22    nonaka 	switch (IFM_SUBTYPE(ifm->ifm_media)) {
    920      1.22    nonaka 	case IFM_AUTO:
    921      1.22    nonaka 		break;
    922      1.22    nonaka 	default:
    923      1.22    nonaka 		device_printf(sc->sc_dev, "Only auto media type\n");
    924      1.22    nonaka 		return EINVAL;
    925      1.22    nonaka 	}
    926       1.1    nonaka 	return 0;
    927       1.1    nonaka }
    928       1.1    nonaka 
    929       1.1    nonaka static void
    930       1.1    nonaka hvn_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
    931       1.1    nonaka {
    932       1.1    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
    933       1.1    nonaka 
    934      1.22    nonaka 	ifmr->ifm_status = IFM_AVALID;
    935      1.22    nonaka 	ifmr->ifm_active = IFM_ETHER;
    936      1.22    nonaka 
    937      1.22    nonaka 	if (sc->sc_link_state != LINK_STATE_UP) {
    938      1.22    nonaka 		ifmr->ifm_active |= IFM_NONE;
    939      1.22    nonaka 		return;
    940      1.22    nonaka 	}
    941      1.22    nonaka 
    942      1.22    nonaka 	ifmr->ifm_status |= IFM_ACTIVE;
    943      1.22    nonaka 	ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
    944      1.22    nonaka }
    945      1.22    nonaka 
    946      1.22    nonaka static void
    947      1.22    nonaka hvn_link_task(void *arg)
    948      1.22    nonaka {
    949      1.22    nonaka 	struct hvn_softc *sc = arg;
    950      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
    951      1.22    nonaka 	uint32_t event;
    952      1.22    nonaka 	int old_link_state;
    953      1.22    nonaka 
    954      1.22    nonaka 	mutex_enter(&sc->sc_link_lock);
    955      1.22    nonaka 	sc->sc_link_onproc = false;
    956      1.22    nonaka 	for (;;) {
    957      1.22    nonaka 		if (sc->sc_link_ev == 0) {
    958      1.22    nonaka 			cv_wait(&sc->sc_link_cv, &sc->sc_link_lock);
    959      1.22    nonaka 			continue;
    960      1.22    nonaka 		}
    961      1.22    nonaka 
    962      1.22    nonaka 		sc->sc_link_onproc = true;
    963      1.22    nonaka 		event = sc->sc_link_ev;
    964      1.22    nonaka 		sc->sc_link_ev = 0;
    965      1.22    nonaka 		mutex_exit(&sc->sc_link_lock);
    966      1.22    nonaka 
    967      1.22    nonaka 		if (event & HVN_LINK_EV_EXIT_THREAD)
    968      1.22    nonaka 			break;
    969      1.22    nonaka 
    970      1.22    nonaka 		if (sc->sc_link_suspend)
    971      1.22    nonaka 			goto next;
    972      1.22    nonaka 
    973      1.22    nonaka 		if (event & HVN_LINK_EV_RESUME_NETWORK) {
    974      1.22    nonaka 			if (sc->sc_link_pending)
    975      1.22    nonaka 				event |= HVN_LINK_EV_NETWORK_CHANGE;
    976      1.22    nonaka 			else
    977      1.22    nonaka 				event |= HVN_LINK_EV_STATE_CHANGE;
    978      1.22    nonaka 		}
    979      1.22    nonaka 
    980      1.22    nonaka 		if (event & HVN_LINK_EV_NETWORK_CHANGE) {
    981      1.22    nonaka 			/* Prevent any link status checks from running. */
    982      1.22    nonaka 			sc->sc_link_pending = true;
    983      1.22    nonaka 
    984      1.22    nonaka 			/*
    985      1.22    nonaka 			 * Fake up a [link down --> link up] state change;
    986      1.22    nonaka 			 * 5 seconds delay is used, which closely simulates
    987      1.22    nonaka 			 * miibus reaction upon link down event.
    988      1.22    nonaka 			 */
    989      1.22    nonaka 			old_link_state = sc->sc_link_state;
    990      1.22    nonaka 			sc->sc_link_state = LINK_STATE_DOWN;
    991      1.22    nonaka 			if (old_link_state != sc->sc_link_state) {
    992      1.22    nonaka 				if_link_state_change(ifp, LINK_STATE_DOWN);
    993      1.22    nonaka 			}
    994      1.22    nonaka #if defined(HVN_LINK_STATE_CHANGE_DELAY) && HVN_LINK_STATE_CHANGE_DELAY > 0
    995      1.22    nonaka 			callout_schedule(&sc->sc_link_tmout,
    996      1.22    nonaka 			    mstohz(HVN_LINK_STATE_CHANGE_DELAY));
    997      1.22    nonaka #else
    998      1.22    nonaka 			hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE_TMOUT);
    999      1.22    nonaka #endif
   1000      1.22    nonaka 		} else if (event & HVN_LINK_EV_NETWORK_CHANGE_TMOUT) {
   1001      1.22    nonaka 			/* Re-allow link status checks. */
   1002      1.22    nonaka 			sc->sc_link_pending = false;
   1003      1.22    nonaka 			hvn_update_link_status(sc);
   1004      1.22    nonaka 		} else if (event & HVN_LINK_EV_STATE_CHANGE) {
   1005      1.22    nonaka 			if (!sc->sc_link_pending)
   1006      1.22    nonaka 				hvn_update_link_status(sc);
   1007      1.22    nonaka 		}
   1008      1.22    nonaka  next:
   1009      1.22    nonaka 		mutex_enter(&sc->sc_link_lock);
   1010      1.22    nonaka 		sc->sc_link_onproc = false;
   1011      1.22    nonaka 	}
   1012      1.22    nonaka 
   1013      1.22    nonaka 	mutex_enter(&sc->sc_link_lock);
   1014      1.22    nonaka 	sc->sc_link_onproc = false;
   1015      1.22    nonaka 	mutex_exit(&sc->sc_link_lock);
   1016      1.22    nonaka 
   1017      1.22    nonaka 	kthread_exit(0);
   1018      1.22    nonaka }
   1019      1.22    nonaka 
   1020      1.22    nonaka static void
   1021      1.22    nonaka hvn_link_event(struct hvn_softc *sc, uint32_t ev)
   1022      1.22    nonaka {
   1023      1.22    nonaka 
   1024      1.22    nonaka 	mutex_enter(&sc->sc_link_lock);
   1025      1.22    nonaka 	SET(sc->sc_link_ev, ev);
   1026      1.22    nonaka 	cv_signal(&sc->sc_link_cv);
   1027      1.22    nonaka 	mutex_exit(&sc->sc_link_lock);
   1028      1.22    nonaka }
   1029      1.22    nonaka 
   1030      1.22    nonaka static void
   1031      1.22    nonaka hvn_link_netchg_tmout_cb(void *arg)
   1032      1.22    nonaka {
   1033      1.22    nonaka 	struct hvn_softc *sc = arg;
   1034       1.1    nonaka 
   1035      1.22    nonaka 	hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE_TMOUT);
   1036       1.1    nonaka }
   1037       1.1    nonaka 
   1038       1.1    nonaka static int
   1039      1.22    nonaka hvn_init(struct ifnet *ifp)
   1040       1.1    nonaka {
   1041      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1042      1.22    nonaka 	int error;
   1043       1.1    nonaka 
   1044      1.22    nonaka 	mutex_enter(&sc->sc_core_lock);
   1045      1.22    nonaka 	error = hvn_init_locked(ifp);
   1046      1.22    nonaka 	mutex_exit(&sc->sc_core_lock);
   1047       1.1    nonaka 
   1048      1.22    nonaka 	return error;
   1049       1.1    nonaka }
   1050       1.1    nonaka 
   1051       1.1    nonaka static int
   1052      1.22    nonaka hvn_init_locked(struct ifnet *ifp)
   1053       1.1    nonaka {
   1054       1.1    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1055       1.1    nonaka 	int error;
   1056       1.1    nonaka 
   1057      1.22    nonaka 	KASSERT(mutex_owned(&sc->sc_core_lock));
   1058      1.22    nonaka 
   1059      1.22    nonaka 	hvn_stop_locked(ifp);
   1060       1.1    nonaka 
   1061      1.22    nonaka 	error = hvn_rndis_open(sc);
   1062       1.1    nonaka 	if (error)
   1063       1.1    nonaka 		return error;
   1064       1.1    nonaka 
   1065      1.22    nonaka 	/* Clear TX 'suspended' bit. */
   1066      1.22    nonaka 	hvn_resume_tx(sc, sc->sc_ntxr_inuse);
   1067      1.22    nonaka 
   1068      1.22    nonaka 	/* Everything is ready; unleash! */
   1069      1.22    nonaka 	ifp->if_flags |= IFF_RUNNING;
   1070      1.22    nonaka 
   1071      1.22    nonaka 	return 0;
   1072       1.1    nonaka }
   1073       1.1    nonaka 
   1074       1.1    nonaka static void
   1075       1.1    nonaka hvn_stop(struct ifnet *ifp, int disable)
   1076       1.1    nonaka {
   1077       1.1    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1078       1.1    nonaka 
   1079      1.22    nonaka 	mutex_enter(&sc->sc_core_lock);
   1080      1.22    nonaka 	hvn_stop_locked(ifp);
   1081      1.22    nonaka 	mutex_exit(&sc->sc_core_lock);
   1082      1.22    nonaka }
   1083      1.22    nonaka 
   1084      1.22    nonaka static void
   1085      1.22    nonaka hvn_stop_locked(struct ifnet *ifp)
   1086      1.22    nonaka {
   1087      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1088      1.22    nonaka 	int i;
   1089      1.22    nonaka 
   1090      1.22    nonaka 	KASSERT(mutex_owned(&sc->sc_core_lock));
   1091      1.22    nonaka 
   1092      1.22    nonaka 	/* Clear RUNNING bit ASAP. */
   1093      1.22    nonaka 	ifp->if_flags &= ~IFF_RUNNING;
   1094       1.1    nonaka 
   1095      1.22    nonaka 	/* Suspend data transfers. */
   1096      1.22    nonaka 	hvn_suspend_data(sc);
   1097      1.22    nonaka 
   1098      1.24   thorpej 	/* Clear OACTIVE state. */
   1099      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr_inuse; i++)
   1100      1.22    nonaka 		sc->sc_txr[i].txr_oactive = 0;
   1101       1.1    nonaka }
   1102       1.1    nonaka 
   1103       1.1    nonaka static void
   1104      1.22    nonaka hvn_transmit_common(struct ifnet *ifp, struct hvn_tx_ring *txr,
   1105      1.22    nonaka     bool is_transmit)
   1106       1.1    nonaka {
   1107       1.1    nonaka 	struct hvn_tx_desc *txd;
   1108       1.1    nonaka 	struct mbuf *m;
   1109      1.22    nonaka 	int l2hlen = ETHER_HDR_LEN;
   1110       1.1    nonaka 
   1111      1.22    nonaka 	KASSERT(mutex_owned(&txr->txr_lock));
   1112      1.22    nonaka 
   1113      1.22    nonaka 	if (!(ifp->if_flags & IFF_RUNNING))
   1114      1.22    nonaka 		return;
   1115      1.22    nonaka 	if (txr->txr_oactive)
   1116      1.22    nonaka 		return;
   1117      1.22    nonaka 	if (txr->txr_suspended)
   1118       1.1    nonaka 		return;
   1119       1.1    nonaka 
   1120       1.1    nonaka 	for (;;) {
   1121      1.22    nonaka 		if (!hvn_txd_peek(txr)) {
   1122       1.1    nonaka 			/* transient */
   1123      1.22    nonaka 			txr->txr_oactive = 1;
   1124      1.22    nonaka 			txr->txr_evnodesc.ev_count++;
   1125       1.1    nonaka 			break;
   1126       1.1    nonaka 		}
   1127       1.1    nonaka 
   1128      1.22    nonaka 		if (is_transmit)
   1129      1.22    nonaka 			m = pcq_get(txr->txr_interq);
   1130      1.22    nonaka 		else
   1131      1.22    nonaka 			IFQ_DEQUEUE(&ifp->if_snd, m);
   1132       1.1    nonaka 		if (m == NULL)
   1133       1.1    nonaka 			break;
   1134       1.1    nonaka 
   1135      1.22    nonaka #if defined(INET) || defined(INET6)
   1136      1.22    nonaka 		if (m->m_pkthdr.csum_flags &
   1137      1.22    nonaka 		    (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TCPv6|M_CSUM_UDPv6)) {
   1138      1.22    nonaka 			m = hvn_set_hlen(m, &l2hlen);
   1139      1.22    nonaka 			if (__predict_false(m == NULL)) {
   1140      1.22    nonaka 				if_statinc(ifp, if_oerrors);
   1141      1.22    nonaka 				continue;
   1142      1.22    nonaka 			}
   1143      1.22    nonaka 		}
   1144      1.22    nonaka #endif
   1145      1.22    nonaka 
   1146      1.22    nonaka 		txd = hvn_txd_get(txr);
   1147      1.22    nonaka 		if (hvn_encap(txr, txd, m, l2hlen)) {
   1148       1.1    nonaka 			/* the chain is too large */
   1149      1.16   thorpej 			if_statinc(ifp, if_oerrors);
   1150      1.22    nonaka 			hvn_txd_put(txr, txd);
   1151       1.1    nonaka 			m_freem(m);
   1152       1.1    nonaka 			continue;
   1153       1.1    nonaka 		}
   1154       1.1    nonaka 
   1155      1.22    nonaka 		if (txr->txr_agg_pktleft == 0) {
   1156      1.22    nonaka 			if (txr->txr_agg_txd != NULL) {
   1157      1.22    nonaka 				hvn_flush_txagg(txr);
   1158      1.22    nonaka 			} else {
   1159      1.22    nonaka 				if (hvn_txpkt(txr, txd)) {
   1160      1.22    nonaka 					/* txd is freed, but m is not. */
   1161      1.22    nonaka 					m_freem(m);
   1162      1.22    nonaka 					if_statinc(ifp, if_oerrors);
   1163      1.22    nonaka 				}
   1164      1.22    nonaka 			}
   1165      1.22    nonaka 		}
   1166      1.22    nonaka 	}
   1167      1.22    nonaka 
   1168      1.22    nonaka 	/* Flush pending aggerated transmission. */
   1169      1.22    nonaka 	if (txr->txr_agg_txd != NULL)
   1170      1.22    nonaka 		hvn_flush_txagg(txr);
   1171      1.22    nonaka }
   1172      1.22    nonaka 
   1173      1.22    nonaka static void
   1174      1.22    nonaka hvn_start(struct ifnet *ifp)
   1175      1.22    nonaka {
   1176      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1177      1.22    nonaka 	struct hvn_tx_ring *txr = &sc->sc_txr[0];
   1178      1.22    nonaka 
   1179      1.22    nonaka 	mutex_enter(&txr->txr_lock);
   1180      1.22    nonaka 	hvn_transmit_common(ifp, txr, false);
   1181      1.22    nonaka 	mutex_exit(&txr->txr_lock);
   1182      1.22    nonaka }
   1183      1.22    nonaka 
   1184      1.22    nonaka static int
   1185      1.22    nonaka hvn_select_txqueue(struct ifnet *ifp, struct mbuf *m __unused)
   1186      1.22    nonaka {
   1187      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1188      1.22    nonaka 	u_int cpu;
   1189      1.22    nonaka 
   1190      1.22    nonaka 	cpu = cpu_index(curcpu());
   1191      1.22    nonaka 
   1192      1.22    nonaka 	return cpu % sc->sc_ntxr_inuse;
   1193      1.22    nonaka }
   1194      1.22    nonaka 
   1195      1.22    nonaka static int
   1196      1.22    nonaka hvn_transmit(struct ifnet *ifp, struct mbuf *m)
   1197      1.22    nonaka {
   1198      1.22    nonaka 	struct hvn_softc *sc = IFP2SC(ifp);
   1199      1.22    nonaka 	struct hvn_tx_ring *txr;
   1200      1.22    nonaka 	int qid;
   1201      1.22    nonaka 
   1202      1.22    nonaka 	qid = hvn_select_txqueue(ifp, m);
   1203      1.22    nonaka 	txr = &sc->sc_txr[qid];
   1204      1.22    nonaka 
   1205      1.22    nonaka 	if (__predict_false(!pcq_put(txr->txr_interq, m))) {
   1206      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   1207      1.22    nonaka 		txr->txr_evpcqdrop.ev_count++;
   1208      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   1209      1.22    nonaka 		m_freem(m);
   1210      1.22    nonaka 		return ENOBUFS;
   1211      1.22    nonaka 	}
   1212      1.22    nonaka 
   1213      1.22    nonaka 	kpreempt_disable();
   1214      1.22    nonaka 	softint_schedule(txr->txr_si);
   1215      1.22    nonaka 	kpreempt_enable();
   1216      1.22    nonaka 	return 0;
   1217      1.22    nonaka }
   1218       1.1    nonaka 
   1219      1.22    nonaka static void
   1220      1.22    nonaka hvn_deferred_transmit(void *arg)
   1221      1.22    nonaka {
   1222      1.22    nonaka 	struct hvn_tx_ring *txr = arg;
   1223      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1224      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   1225       1.1    nonaka 
   1226      1.22    nonaka 	mutex_enter(&txr->txr_lock);
   1227      1.22    nonaka 	txr->txr_evtransmitdefer.ev_count++;
   1228      1.22    nonaka 	hvn_transmit_common(ifp, txr, true);
   1229      1.22    nonaka 	mutex_exit(&txr->txr_lock);
   1230       1.1    nonaka }
   1231       1.1    nonaka 
   1232       1.1    nonaka static inline char *
   1233       1.1    nonaka hvn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize,
   1234       1.1    nonaka     size_t datalen, uint32_t type)
   1235       1.1    nonaka {
   1236       1.1    nonaka 	struct rndis_pktinfo *pi;
   1237       1.1    nonaka 	size_t pi_size = sizeof(*pi) + datalen;
   1238       1.1    nonaka 	char *cp;
   1239       1.1    nonaka 
   1240       1.1    nonaka 	KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <=
   1241       1.1    nonaka 	    pktsize);
   1242       1.1    nonaka 
   1243       1.1    nonaka 	cp = (char *)pkt + pkt->rm_pktinfooffset + pkt->rm_pktinfolen;
   1244       1.1    nonaka 	pi = (struct rndis_pktinfo *)cp;
   1245       1.1    nonaka 	pi->rm_size = pi_size;
   1246       1.1    nonaka 	pi->rm_type = type;
   1247       1.1    nonaka 	pi->rm_pktinfooffset = sizeof(*pi);
   1248       1.1    nonaka 	pkt->rm_pktinfolen += pi_size;
   1249       1.1    nonaka 	pkt->rm_dataoffset += pi_size;
   1250       1.1    nonaka 	pkt->rm_len += pi_size;
   1251       1.1    nonaka 
   1252       1.1    nonaka 	return (char *)pi->rm_data;
   1253       1.1    nonaka }
   1254       1.1    nonaka 
   1255      1.22    nonaka static struct mbuf *
   1256      1.22    nonaka hvn_pullup_hdr(struct mbuf *m, int len)
   1257       1.1    nonaka {
   1258      1.22    nonaka 	struct mbuf *mn;
   1259       1.1    nonaka 
   1260      1.22    nonaka 	if (__predict_false(m->m_len < len)) {
   1261      1.22    nonaka 		mn = m_pullup(m, len);
   1262      1.22    nonaka 		if (mn == NULL)
   1263      1.22    nonaka 			return NULL;
   1264      1.22    nonaka 		m = mn;
   1265      1.22    nonaka 	}
   1266      1.22    nonaka 	return m;
   1267      1.22    nonaka }
   1268       1.1    nonaka 
   1269      1.22    nonaka /*
   1270      1.22    nonaka  * NOTE: If this function failed, the m would be freed.
   1271      1.22    nonaka  */
   1272      1.22    nonaka static struct mbuf *
   1273      1.22    nonaka hvn_set_hlen(struct mbuf *m, int *l2hlenp)
   1274      1.22    nonaka {
   1275      1.22    nonaka 	const struct ether_header *eh;
   1276      1.22    nonaka 	int l2hlen, off;
   1277       1.1    nonaka 
   1278      1.22    nonaka 	m = hvn_pullup_hdr(m, sizeof(*eh));
   1279      1.22    nonaka 	if (m == NULL)
   1280      1.22    nonaka 		return NULL;
   1281       1.1    nonaka 
   1282      1.22    nonaka 	eh = mtod(m, const struct ether_header *);
   1283      1.22    nonaka 	if (eh->ether_type == ntohs(ETHERTYPE_VLAN))
   1284      1.22    nonaka 		l2hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
   1285      1.22    nonaka 	else
   1286      1.22    nonaka 		l2hlen = ETHER_HDR_LEN;
   1287       1.1    nonaka 
   1288      1.22    nonaka #if defined(INET)
   1289      1.22    nonaka 	if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
   1290      1.22    nonaka 		const struct ip *ip;
   1291       1.1    nonaka 
   1292      1.22    nonaka 		off = l2hlen + sizeof(*ip);
   1293      1.22    nonaka 		m = hvn_pullup_hdr(m, off);
   1294      1.22    nonaka 		if (m == NULL)
   1295      1.22    nonaka 			return NULL;
   1296       1.1    nonaka 
   1297      1.22    nonaka 		ip = (struct ip *)((mtod(m, uint8_t *)) + off);
   1298      1.22    nonaka 
   1299      1.22    nonaka 		/*
   1300      1.22    nonaka 		 * UDP checksum offload does not work in Azure, if the
   1301      1.22    nonaka 		 * following conditions meet:
   1302      1.22    nonaka 		 * - sizeof(IP hdr + UDP hdr + payload) > 1420.
   1303      1.22    nonaka 		 * - IP_DF is not set in the IP hdr.
   1304      1.22    nonaka 		 *
   1305      1.22    nonaka 		 * Fallback to software checksum for these UDP datagrams.
   1306      1.22    nonaka 		 */
   1307      1.22    nonaka 		if ((m->m_pkthdr.csum_flags & M_CSUM_UDPv4) &&
   1308      1.22    nonaka 		    m->m_pkthdr.len > hvn_udpcs_fixup_mtu + l2hlen &&
   1309      1.22    nonaka 		    !(ntohs(ip->ip_off) & IP_DF)) {
   1310      1.22    nonaka 			uint16_t *csump;
   1311      1.22    nonaka 
   1312      1.22    nonaka 			off = l2hlen +
   1313      1.22    nonaka 			    M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
   1314      1.22    nonaka 			m = hvn_pullup_hdr(m, off + sizeof(struct udphdr));
   1315      1.22    nonaka 			if (m == NULL)
   1316      1.22    nonaka 				return NULL;
   1317      1.22    nonaka 
   1318      1.22    nonaka 			csump = (uint16_t *)(mtod(m, uint8_t *) + off +
   1319      1.22    nonaka 			    M_CSUM_DATA_IPv4_OFFSET(m->m_pkthdr.csum_data));
   1320      1.22    nonaka 			*csump = cpu_in_cksum(m, m->m_pkthdr.len - off, off, 0);
   1321      1.22    nonaka 			m->m_pkthdr.csum_flags &= ~M_CSUM_UDPv4;
   1322      1.22    nonaka 		}
   1323      1.22    nonaka 	}
   1324      1.22    nonaka #endif	/* INET */
   1325      1.22    nonaka #if defined(INET) && defined(INET6)
   1326      1.22    nonaka 	else
   1327      1.22    nonaka #endif	/* INET && INET6 */
   1328      1.22    nonaka #if defined(INET6)
   1329      1.22    nonaka 	{
   1330      1.22    nonaka 		const struct ip6_hdr *ip6;
   1331      1.22    nonaka 
   1332      1.22    nonaka 		off = l2hlen + sizeof(*ip6);
   1333      1.22    nonaka 		m = hvn_pullup_hdr(m, off);
   1334      1.22    nonaka 		if (m == NULL)
   1335      1.22    nonaka 			return NULL;
   1336      1.22    nonaka 
   1337      1.22    nonaka 		ip6 = (struct ip6_hdr *)((mtod(m, uint8_t *)) + l2hlen);
   1338      1.22    nonaka 		if (ip6->ip6_nxt != IPPROTO_TCP &&
   1339      1.22    nonaka 		    ip6->ip6_nxt != IPPROTO_UDP) {
   1340      1.22    nonaka 			m_freem(m);
   1341      1.22    nonaka 			return NULL;
   1342      1.22    nonaka 		}
   1343      1.22    nonaka 	}
   1344      1.22    nonaka #endif	/* INET6 */
   1345      1.22    nonaka 
   1346      1.22    nonaka 	*l2hlenp = l2hlen;
   1347      1.22    nonaka 
   1348      1.22    nonaka 	return m;
   1349      1.22    nonaka }
   1350      1.22    nonaka 
   1351      1.22    nonaka static int
   1352      1.22    nonaka hvn_flush_txagg(struct hvn_tx_ring *txr)
   1353      1.22    nonaka {
   1354      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1355      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   1356      1.22    nonaka 	struct hvn_tx_desc *txd;
   1357      1.22    nonaka 	struct mbuf *m;
   1358      1.22    nonaka 	int error, pkts;
   1359      1.22    nonaka 
   1360      1.22    nonaka 	txd = txr->txr_agg_txd;
   1361      1.22    nonaka 	KASSERTMSG(txd != NULL, "no aggregate txdesc");
   1362      1.22    nonaka 
   1363      1.22    nonaka 	/*
   1364      1.22    nonaka 	 * Since hvn_txpkt() will reset this temporary stat, save
   1365      1.22    nonaka 	 * it now, so that oerrors can be updated properly, if
   1366      1.22    nonaka 	 * hvn_txpkt() ever fails.
   1367      1.22    nonaka 	 */
   1368      1.22    nonaka 	pkts = txr->txr_stat_pkts;
   1369      1.22    nonaka 
   1370      1.22    nonaka 	/*
   1371      1.22    nonaka 	 * Since txd's mbuf will _not_ be freed upon hvn_txpkt()
   1372      1.22    nonaka 	 * failure, save it for later freeing, if hvn_txpkt() ever
   1373      1.22    nonaka 	 * fails.
   1374      1.22    nonaka 	 */
   1375      1.22    nonaka 	m = txd->txd_buf;
   1376      1.22    nonaka 	error = hvn_txpkt(txr, txd);
   1377      1.22    nonaka 	if (__predict_false(error)) {
   1378      1.22    nonaka 		/* txd is freed, but m is not. */
   1379      1.22    nonaka 		m_freem(m);
   1380      1.22    nonaka 		txr->txr_evflushfailed.ev_count++;
   1381      1.22    nonaka 		if_statadd(ifp, if_oerrors, pkts);
   1382      1.22    nonaka 	}
   1383      1.22    nonaka 
   1384      1.22    nonaka 	/* Reset all aggregation states. */
   1385      1.22    nonaka 	txr->txr_agg_txd = NULL;
   1386      1.22    nonaka 	txr->txr_agg_szleft = 0;
   1387      1.22    nonaka 	txr->txr_agg_pktleft = 0;
   1388      1.22    nonaka 	txr->txr_agg_prevpkt = NULL;
   1389      1.22    nonaka 
   1390      1.22    nonaka 	return error;
   1391      1.22    nonaka }
   1392      1.22    nonaka 
   1393      1.22    nonaka static void *
   1394      1.22    nonaka hvn_try_txagg(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd, int pktsz)
   1395      1.22    nonaka {
   1396      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1397      1.22    nonaka 	struct hvn_tx_desc *agg_txd;
   1398      1.22    nonaka 	struct rndis_packet_msg *pkt;
   1399      1.22    nonaka 	void *chim;
   1400      1.22    nonaka 	int olen;
   1401      1.22    nonaka 
   1402      1.22    nonaka 	if (txr->txr_agg_txd != NULL) {
   1403      1.22    nonaka 		if (txr->txr_agg_pktleft > 0 && txr->txr_agg_szleft > pktsz) {
   1404      1.22    nonaka 			agg_txd = txr->txr_agg_txd;
   1405      1.22    nonaka 			pkt = txr->txr_agg_prevpkt;
   1406      1.22    nonaka 
   1407      1.22    nonaka 			/*
   1408      1.22    nonaka 			 * Update the previous RNDIS packet's total length,
   1409      1.22    nonaka 			 * it can be increased due to the mandatory alignment
   1410      1.22    nonaka 			 * padding for this RNDIS packet.  And update the
   1411      1.22    nonaka 			 * aggregating txdesc's chimney sending buffer size
   1412      1.22    nonaka 			 * accordingly.
   1413      1.22    nonaka 			 *
   1414      1.22    nonaka 			 * XXX
   1415      1.22    nonaka 			 * Zero-out the padding, as required by the RNDIS spec.
   1416      1.22    nonaka 			 */
   1417      1.22    nonaka 			olen = pkt->rm_len;
   1418      1.22    nonaka 			pkt->rm_len = roundup2(olen, txr->txr_agg_align);
   1419      1.22    nonaka 			agg_txd->txd_chim_size += pkt->rm_len - olen;
   1420      1.22    nonaka 
   1421      1.22    nonaka 			/* Link this txdesc to the parent. */
   1422      1.22    nonaka 			hvn_txd_agg(agg_txd, txd);
   1423      1.22    nonaka 
   1424      1.22    nonaka 			chim = (uint8_t *)pkt + pkt->rm_len;
   1425      1.22    nonaka 			/* Save the current packet for later fixup. */
   1426      1.22    nonaka 			txr->txr_agg_prevpkt = chim;
   1427      1.22    nonaka 
   1428      1.22    nonaka 			txr->txr_agg_pktleft--;
   1429      1.22    nonaka 			txr->txr_agg_szleft -= pktsz;
   1430      1.22    nonaka 			if (txr->txr_agg_szleft <=
   1431      1.22    nonaka 			    HVN_PKTSIZE_MIN(txr->txr_agg_align)) {
   1432      1.22    nonaka 				/*
   1433      1.22    nonaka 				 * Probably can't aggregate more packets,
   1434      1.22    nonaka 				 * flush this aggregating txdesc proactively.
   1435      1.22    nonaka 				 */
   1436      1.22    nonaka 				txr->txr_agg_pktleft = 0;
   1437      1.22    nonaka 			}
   1438      1.22    nonaka 
   1439      1.22    nonaka 			/* Done! */
   1440      1.22    nonaka 			return chim;
   1441      1.22    nonaka 		}
   1442      1.22    nonaka 		hvn_flush_txagg(txr);
   1443      1.22    nonaka 	}
   1444      1.22    nonaka 
   1445      1.22    nonaka 	txr->txr_evchimneytried.ev_count++;
   1446      1.22    nonaka 	txd->txd_chim_index = hvn_chim_alloc(sc);
   1447      1.22    nonaka 	if (txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID)
   1448      1.22    nonaka 		return NULL;
   1449      1.22    nonaka 	txr->txr_evchimney.ev_count++;
   1450      1.22    nonaka 
   1451      1.22    nonaka 	chim = sc->sc_chim + (txd->txd_chim_index * sc->sc_chim_szmax);
   1452      1.22    nonaka 
   1453      1.22    nonaka 	if (txr->txr_agg_pktmax > 1 &&
   1454      1.22    nonaka 	    txr->txr_agg_szmax > pktsz + HVN_PKTSIZE_MIN(txr->txr_agg_align)) {
   1455      1.22    nonaka 		txr->txr_agg_txd = txd;
   1456      1.22    nonaka 		txr->txr_agg_pktleft = txr->txr_agg_pktmax - 1;
   1457      1.22    nonaka 		txr->txr_agg_szleft = txr->txr_agg_szmax - pktsz;
   1458      1.22    nonaka 		txr->txr_agg_prevpkt = chim;
   1459      1.22    nonaka 	}
   1460      1.22    nonaka 
   1461      1.22    nonaka 	return chim;
   1462      1.22    nonaka }
   1463      1.22    nonaka 
   1464      1.22    nonaka static int
   1465      1.22    nonaka hvn_encap(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd, struct mbuf *m,
   1466      1.22    nonaka     int l2hlen)
   1467      1.22    nonaka {
   1468      1.22    nonaka 	/* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */
   1469      1.22    nonaka 	static const char zero_pad[ETHER_MIN_LEN];
   1470      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1471      1.22    nonaka 	struct rndis_packet_msg *pkt;
   1472      1.22    nonaka 	bus_dma_segment_t *seg;
   1473      1.22    nonaka 	void *chim = NULL;
   1474      1.22    nonaka 	size_t pktlen, pktsize;
   1475      1.22    nonaka 	int l3hlen;
   1476      1.22    nonaka 	int i, rv;
   1477      1.22    nonaka 
   1478      1.22    nonaka 	if (ISSET(sc->sc_caps, HVN_CAPS_VLAN) && !vlan_has_tag(m)) {
   1479      1.22    nonaka 		struct ether_vlan_header *evl;
   1480      1.22    nonaka 
   1481      1.22    nonaka 		m = hvn_pullup_hdr(m, sizeof(*evl));
   1482      1.22    nonaka 		if (m == NULL) {
   1483      1.22    nonaka 			DPRINTF("%s: failed to pullup mbuf\n",
   1484      1.22    nonaka 			    device_xname(sc->sc_dev));
   1485      1.22    nonaka 			return -1;
   1486      1.22    nonaka 		}
   1487      1.22    nonaka 
   1488      1.22    nonaka 		evl = mtod(m, struct ether_vlan_header *);
   1489      1.22    nonaka 		if (evl->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
   1490      1.22    nonaka 			struct ether_header *eh;
   1491      1.22    nonaka 			uint16_t proto = evl->evl_proto;
   1492      1.22    nonaka 
   1493      1.22    nonaka 			vlan_set_tag(m, ntohs(evl->evl_tag));
   1494      1.22    nonaka 
   1495      1.22    nonaka 			/*
   1496      1.22    nonaka 			 * Trim VLAN tag from header.
   1497      1.22    nonaka 			 */
   1498      1.22    nonaka 			memmove((uint8_t *)evl + ETHER_VLAN_ENCAP_LEN,
   1499      1.22    nonaka 			    evl, ETHER_HDR_LEN);
   1500      1.22    nonaka 			m_adj(m, ETHER_VLAN_ENCAP_LEN);
   1501      1.22    nonaka 
   1502      1.22    nonaka 			eh = mtod(m, struct ether_header *);
   1503      1.22    nonaka 			eh->ether_type = proto;
   1504      1.22    nonaka 
   1505      1.22    nonaka 			/*
   1506      1.22    nonaka 			 * Re-padding.  See sys/net/if_vlan.c:vlan_start().
   1507      1.22    nonaka 			 */
   1508      1.22    nonaka 			if (m->m_pkthdr.len < (ETHER_MIN_LEN - ETHER_CRC_LEN +
   1509      1.22    nonaka 			    ETHER_VLAN_ENCAP_LEN)) {
   1510      1.22    nonaka 				m_copyback(m, m->m_pkthdr.len,
   1511      1.22    nonaka 				    (ETHER_MIN_LEN - ETHER_CRC_LEN +
   1512      1.22    nonaka 				     ETHER_VLAN_ENCAP_LEN) -
   1513      1.22    nonaka 				    m->m_pkthdr.len, zero_pad);
   1514      1.22    nonaka 			}
   1515      1.22    nonaka 
   1516      1.22    nonaka 			txr->txr_evvlanfixup.ev_count++;
   1517      1.22    nonaka 		}
   1518      1.22    nonaka 	}
   1519      1.22    nonaka 
   1520      1.22    nonaka 	pkt = txd->txd_req;
   1521      1.22    nonaka 	pktsize = HVN_PKTSIZE(m, txr->txr_agg_align);
   1522      1.22    nonaka 	if (pktsize < txr->txr_chim_size) {
   1523      1.22    nonaka 		chim = hvn_try_txagg(txr, txd, pktsize);
   1524      1.22    nonaka 		if (chim != NULL)
   1525      1.22    nonaka 			pkt = chim;
   1526      1.22    nonaka 	} else {
   1527      1.22    nonaka 		if (txr->txr_agg_txd != NULL)
   1528      1.22    nonaka 			hvn_flush_txagg(txr);
   1529      1.22    nonaka 	}
   1530      1.22    nonaka 
   1531      1.22    nonaka 	memset(pkt, 0, HVN_RNDIS_PKT_LEN);
   1532      1.22    nonaka 	pkt->rm_type = REMOTE_NDIS_PACKET_MSG;
   1533      1.22    nonaka 	pkt->rm_len = sizeof(*pkt) + m->m_pkthdr.len;
   1534      1.22    nonaka 	pkt->rm_dataoffset = RNDIS_DATA_OFFSET;
   1535      1.22    nonaka 	pkt->rm_datalen = m->m_pkthdr.len;
   1536      1.22    nonaka 	pkt->rm_pktinfooffset = sizeof(*pkt); /* adjusted below */
   1537      1.22    nonaka 	pkt->rm_pktinfolen = 0;
   1538      1.22    nonaka 
   1539      1.22    nonaka 	if (txr->txr_flags & HVN_TXR_FLAG_UDP_HASH) {
   1540      1.22    nonaka 		char *cp;
   1541      1.22    nonaka 
   1542      1.22    nonaka 		/*
   1543      1.22    nonaka 		 * Set the hash value for this packet, so that the host could
   1544      1.22    nonaka 		 * dispatch the TX done event for this packet back to this TX
   1545      1.22    nonaka 		 * ring's channel.
   1546      1.22    nonaka 		 */
   1547      1.22    nonaka 		cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN,
   1548      1.22    nonaka 		    HVN_NDIS_HASH_VALUE_SIZE, HVN_NDIS_PKTINFO_TYPE_HASHVAL);
   1549      1.22    nonaka 		memcpy(cp, &txr->txr_id, HVN_NDIS_HASH_VALUE_SIZE);
   1550      1.22    nonaka 	}
   1551      1.22    nonaka 
   1552      1.22    nonaka 	if (vlan_has_tag(m)) {
   1553      1.22    nonaka 		uint32_t vlan;
   1554      1.22    nonaka 		char *cp;
   1555      1.22    nonaka 		uint16_t tag;
   1556      1.22    nonaka 
   1557      1.22    nonaka 		tag = vlan_get_tag(m);
   1558      1.22    nonaka 		vlan = NDIS_VLAN_INFO_MAKE(EVL_VLANOFTAG(tag),
   1559      1.22    nonaka 		    EVL_PRIOFTAG(tag), EVL_CFIOFTAG(tag));
   1560      1.22    nonaka 		cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN,
   1561      1.22    nonaka 		    NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN);
   1562      1.22    nonaka 		memcpy(cp, &vlan, NDIS_VLAN_INFO_SIZE);
   1563      1.22    nonaka 		txr->txr_evvlanhwtagging.ev_count++;
   1564      1.22    nonaka 	}
   1565      1.22    nonaka 
   1566      1.22    nonaka 	if (m->m_pkthdr.csum_flags & txr->txr_csum_assist) {
   1567      1.22    nonaka 		uint32_t csum;
   1568      1.22    nonaka 		char *cp;
   1569      1.22    nonaka 
   1570      1.22    nonaka 		if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) {
   1571      1.22    nonaka 			csum = NDIS_TXCSUM_INFO_IPV6;
   1572      1.22    nonaka 			l3hlen = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data);
   1573      1.22    nonaka 			if (m->m_pkthdr.csum_flags & M_CSUM_TCPv6)
   1574      1.22    nonaka 				csum |= NDIS_TXCSUM_INFO_MKTCPCS(l2hlen +
   1575      1.22    nonaka 				    l3hlen);
   1576      1.22    nonaka 			if (m->m_pkthdr.csum_flags & M_CSUM_UDPv6)
   1577      1.22    nonaka 				csum |= NDIS_TXCSUM_INFO_MKUDPCS(l2hlen +
   1578      1.22    nonaka 				    l3hlen);
   1579      1.22    nonaka 		} else {
   1580      1.22    nonaka 			csum = NDIS_TXCSUM_INFO_IPV4;
   1581      1.22    nonaka 			l3hlen = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
   1582      1.22    nonaka 			if (m->m_pkthdr.csum_flags & M_CSUM_IPv4)
   1583      1.22    nonaka 				csum |= NDIS_TXCSUM_INFO_IPCS;
   1584      1.22    nonaka 			if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4)
   1585      1.22    nonaka 				csum |= NDIS_TXCSUM_INFO_MKTCPCS(l2hlen +
   1586      1.22    nonaka 				    l3hlen);
   1587      1.22    nonaka 			if (m->m_pkthdr.csum_flags & M_CSUM_UDPv4)
   1588      1.22    nonaka 				csum |= NDIS_TXCSUM_INFO_MKUDPCS(l2hlen +
   1589      1.22    nonaka 				    l3hlen);
   1590      1.22    nonaka 		}
   1591       1.1    nonaka 		cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN,
   1592       1.1    nonaka 		    NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM);
   1593       1.1    nonaka 		memcpy(cp, &csum, NDIS_TXCSUM_INFO_SIZE);
   1594       1.1    nonaka 	}
   1595       1.1    nonaka 
   1596       1.1    nonaka 	pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen;
   1597       1.1    nonaka 	pkt->rm_pktinfooffset -= RNDIS_HEADER_OFFSET;
   1598       1.1    nonaka 
   1599      1.22    nonaka 	/*
   1600      1.22    nonaka 	 * Fast path: Chimney sending.
   1601      1.22    nonaka 	 */
   1602      1.22    nonaka 	if (chim != NULL) {
   1603      1.22    nonaka 		struct hvn_tx_desc *tgt_txd;
   1604      1.22    nonaka 
   1605      1.22    nonaka 		tgt_txd = (txr->txr_agg_txd != NULL) ? txr->txr_agg_txd : txd;
   1606      1.22    nonaka 
   1607      1.22    nonaka 		KASSERTMSG(pkt == chim,
   1608      1.22    nonaka 		    "RNDIS pkt not in chimney sending buffer");
   1609      1.22    nonaka 		KASSERTMSG(tgt_txd->txd_chim_index != HVN_NVS_CHIM_IDX_INVALID,
   1610      1.22    nonaka 		    "chimney sending buffer is not used");
   1611      1.22    nonaka 
   1612      1.22    nonaka 		tgt_txd->txd_chim_size += pkt->rm_len;
   1613      1.22    nonaka 		m_copydata(m, 0, m->m_pkthdr.len, (uint8_t *)chim + pktlen);
   1614      1.22    nonaka 
   1615      1.22    nonaka 		txr->txr_sendpkt = hvn_rndis_output_chim;
   1616      1.22    nonaka 		goto done;
   1617      1.22    nonaka 	}
   1618      1.22    nonaka 
   1619      1.22    nonaka 	KASSERTMSG(txr->txr_agg_txd == NULL, "aggregating sglist txdesc");
   1620      1.22    nonaka 	KASSERTMSG(txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID,
   1621      1.22    nonaka 	    "chimney buffer is used");
   1622      1.22    nonaka 	KASSERTMSG(pkt == txd->txd_req, "RNDIS pkt not in txdesc");
   1623      1.22    nonaka 
   1624      1.22    nonaka 	rv = bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmap, m, BUS_DMA_READ |
   1625      1.22    nonaka 	    BUS_DMA_NOWAIT);
   1626      1.22    nonaka 	switch (rv) {
   1627      1.22    nonaka 	case 0:
   1628      1.22    nonaka 		break;
   1629      1.22    nonaka 	case EFBIG:
   1630      1.22    nonaka 		if (m_defrag(m, M_NOWAIT) != NULL) {
   1631      1.22    nonaka 			txr->txr_evdefrag.ev_count++;
   1632      1.22    nonaka 			if (bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmap, m,
   1633      1.22    nonaka 			    BUS_DMA_READ | BUS_DMA_NOWAIT) == 0)
   1634      1.22    nonaka 				break;
   1635      1.22    nonaka 		}
   1636      1.22    nonaka 		/* FALLTHROUGH */
   1637      1.22    nonaka 	default:
   1638      1.22    nonaka 		DPRINTF("%s: failed to load mbuf\n", device_xname(sc->sc_dev));
   1639      1.22    nonaka 		txr->txr_evdmafailed.ev_count++;
   1640      1.22    nonaka 		return -1;
   1641      1.22    nonaka 	}
   1642      1.22    nonaka 	bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap,
   1643      1.22    nonaka 	    0, txd->txd_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
   1644      1.22    nonaka 	SET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP);
   1645      1.22    nonaka 
   1646       1.1    nonaka 	/* Attach an RNDIS message to the first slot */
   1647       1.1    nonaka 	txd->txd_sgl[0].gpa_page = txd->txd_gpa.gpa_page;
   1648       1.1    nonaka 	txd->txd_sgl[0].gpa_ofs = txd->txd_gpa.gpa_ofs;
   1649       1.1    nonaka 	txd->txd_sgl[0].gpa_len = pktlen;
   1650       1.1    nonaka 	txd->txd_nsge = txd->txd_dmap->dm_nsegs + 1;
   1651       1.1    nonaka 
   1652       1.1    nonaka 	for (i = 0; i < txd->txd_dmap->dm_nsegs; i++) {
   1653       1.1    nonaka 		seg = &txd->txd_dmap->dm_segs[i];
   1654       1.1    nonaka 		txd->txd_sgl[1 + i].gpa_page = atop(seg->ds_addr);
   1655       1.1    nonaka 		txd->txd_sgl[1 + i].gpa_ofs = seg->ds_addr & PAGE_MASK;
   1656       1.1    nonaka 		txd->txd_sgl[1 + i].gpa_len = seg->ds_len;
   1657       1.1    nonaka 	}
   1658       1.1    nonaka 
   1659      1.22    nonaka 	txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID;
   1660      1.22    nonaka 	txd->txd_chim_size = 0;
   1661      1.22    nonaka 	txr->txr_sendpkt = hvn_rndis_output_sgl;
   1662      1.22    nonaka done:
   1663      1.22    nonaka 	txd->txd_buf = m;
   1664       1.1    nonaka 
   1665      1.22    nonaka 	/* Update temporary stats for later use. */
   1666      1.22    nonaka 	txr->txr_stat_pkts++;
   1667      1.22    nonaka 	txr->txr_stat_size += m->m_pkthdr.len;
   1668      1.22    nonaka 	if (m->m_flags & M_MCAST)
   1669      1.22    nonaka 		txr->txr_stat_mcasts++;
   1670       1.1    nonaka 
   1671       1.1    nonaka 	return 0;
   1672       1.1    nonaka }
   1673       1.1    nonaka 
   1674       1.1    nonaka static void
   1675      1.22    nonaka hvn_bpf_mtap(struct hvn_tx_ring *txr, struct mbuf *m, u_int direction)
   1676      1.22    nonaka {
   1677      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1678      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   1679      1.22    nonaka 	struct ether_header *eh;
   1680      1.22    nonaka 	struct ether_vlan_header evl;
   1681      1.22    nonaka 
   1682      1.22    nonaka 	if (!vlan_has_tag(m)) {
   1683      1.22    nonaka 		bpf_mtap(ifp, m, direction);
   1684      1.22    nonaka 		return;
   1685      1.22    nonaka 	}
   1686      1.22    nonaka 
   1687      1.22    nonaka 	if (ifp->if_bpf == NULL)
   1688      1.22    nonaka 		return;
   1689      1.22    nonaka 
   1690      1.22    nonaka 	txr->txr_evvlantap.ev_count++;
   1691      1.22    nonaka 
   1692      1.22    nonaka 	/*
   1693      1.22    nonaka 	 * Restore a VLAN tag for bpf.
   1694      1.22    nonaka 	 *
   1695      1.22    nonaka 	 * Do not modify contents of the original mbuf,
   1696      1.22    nonaka 	 * because Tx processing on the mbuf is still in progress.
   1697      1.22    nonaka 	 */
   1698      1.22    nonaka 
   1699      1.22    nonaka 	eh = mtod(m, struct ether_header *);
   1700  1.27.2.1  perseant 	memcpy(&evl, eh, ETHER_ADDR_LEN * 2);
   1701      1.22    nonaka 	evl.evl_encap_proto = htons(ETHERTYPE_VLAN);
   1702      1.22    nonaka 	evl.evl_tag = htons(vlan_get_tag(m));
   1703      1.22    nonaka 	evl.evl_proto = eh->ether_type;
   1704      1.22    nonaka 
   1705      1.22    nonaka 	/* Do not tap ether header of the original mbuf. */
   1706      1.22    nonaka 	m_adj(m, sizeof(*eh));
   1707      1.22    nonaka 
   1708      1.22    nonaka 	bpf_mtap2(ifp->if_bpf, &evl, sizeof(evl), m, direction);
   1709      1.22    nonaka 
   1710      1.22    nonaka 	/* Cannot restore ether header of the original mbuf,
   1711      1.22    nonaka 	 * but do not worry about it because just free it. */
   1712      1.22    nonaka }
   1713      1.22    nonaka 
   1714      1.22    nonaka static int
   1715      1.22    nonaka hvn_txpkt(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd)
   1716       1.1    nonaka {
   1717      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1718       1.1    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   1719      1.22    nonaka 	const struct hvn_tx_desc *tmp_txd;
   1720      1.22    nonaka 	int error;
   1721      1.22    nonaka 
   1722      1.22    nonaka 	/*
   1723      1.22    nonaka 	 * Make sure that this txd and any aggregated txds are not
   1724      1.22    nonaka 	 * freed before bpf_mtap.
   1725      1.22    nonaka 	 */
   1726      1.22    nonaka 	hvn_txd_hold(txd);
   1727      1.22    nonaka 
   1728      1.22    nonaka 	error = (*txr->txr_sendpkt)(txr, txd);
   1729      1.22    nonaka 	if (error == 0) {
   1730      1.22    nonaka 		hvn_bpf_mtap(txr, txd->txd_buf, BPF_D_OUT);
   1731      1.22    nonaka 		STAILQ_FOREACH(tmp_txd, &txd->txd_agg_list, txd_agg_entry)
   1732      1.22    nonaka 			hvn_bpf_mtap(txr, tmp_txd->txd_buf, BPF_D_OUT);
   1733      1.22    nonaka 
   1734      1.22    nonaka 		if_statadd(ifp, if_opackets, txr->txr_stat_pkts);
   1735      1.22    nonaka 		if_statadd(ifp, if_obytes, txr->txr_stat_size);
   1736      1.22    nonaka 		if (txr->txr_stat_mcasts != 0)
   1737      1.22    nonaka 			if_statadd(ifp, if_omcasts, txr->txr_stat_mcasts);
   1738      1.22    nonaka 		txr->txr_evpkts.ev_count += txr->txr_stat_pkts;
   1739      1.22    nonaka 		txr->txr_evsends.ev_count++;
   1740      1.22    nonaka 	}
   1741      1.22    nonaka 
   1742      1.22    nonaka 	hvn_txd_put(txr, txd);
   1743      1.22    nonaka 
   1744      1.22    nonaka 	if (__predict_false(error)) {
   1745      1.22    nonaka 		/*
   1746      1.22    nonaka 		 * Caller will perform further processing on the
   1747      1.22    nonaka 		 * associated mbuf, so don't free it in hvn_txd_put();
   1748      1.22    nonaka 		 * only unload it from the DMA map in hvn_txd_put(),
   1749      1.22    nonaka 		 * if it was loaded.
   1750      1.22    nonaka 		 */
   1751      1.22    nonaka 		txd->txd_buf = NULL;
   1752      1.22    nonaka 		hvn_txd_put(txr, txd);
   1753      1.22    nonaka 	}
   1754      1.22    nonaka 
   1755      1.22    nonaka 	/* Reset temporary stats, after this sending is done. */
   1756      1.22    nonaka 	txr->txr_stat_pkts = 0;
   1757      1.22    nonaka 	txr->txr_stat_size = 0;
   1758      1.22    nonaka 	txr->txr_stat_mcasts = 0;
   1759      1.22    nonaka 
   1760      1.22    nonaka 	return error;
   1761      1.22    nonaka }
   1762      1.22    nonaka 
   1763      1.22    nonaka static void
   1764      1.22    nonaka hvn_txeof(struct hvn_tx_ring *txr, uint64_t tid)
   1765      1.22    nonaka {
   1766      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   1767      1.22    nonaka 	struct hvn_tx_desc *txd;
   1768      1.22    nonaka 	uint32_t id = tid >> 32;
   1769      1.22    nonaka 
   1770      1.22    nonaka 	if ((tid & 0xffffffffU) != 0)
   1771      1.22    nonaka 		return;
   1772      1.22    nonaka 
   1773      1.22    nonaka 	id -= HVN_NVS_CHIM_SIG;
   1774      1.22    nonaka 	if (id >= HVN_TX_DESC) {
   1775      1.22    nonaka 		device_printf(sc->sc_dev, "tx packet index too large: %u", id);
   1776      1.22    nonaka 		return;
   1777      1.22    nonaka 	}
   1778      1.22    nonaka 
   1779      1.22    nonaka 	txd = &txr->txr_desc[id];
   1780      1.22    nonaka 
   1781      1.22    nonaka 	if (txd->txd_buf == NULL)
   1782      1.22    nonaka 		device_printf(sc->sc_dev, "no mbuf @%u\n", id);
   1783      1.22    nonaka 
   1784      1.22    nonaka 	hvn_txd_put(txr, txd);
   1785      1.22    nonaka }
   1786      1.22    nonaka 
   1787      1.22    nonaka static int
   1788      1.22    nonaka hvn_rx_ring_create(struct hvn_softc *sc, int ring_cnt)
   1789      1.22    nonaka {
   1790      1.22    nonaka 	struct hvn_rx_ring *rxr;
   1791      1.22    nonaka 	int i;
   1792      1.22    nonaka 
   1793      1.22    nonaka 	if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_2)
   1794      1.22    nonaka 		sc->sc_rx_size = 15 * 1024 * 1024;	/* 15MB */
   1795      1.22    nonaka 	else
   1796      1.22    nonaka 		sc->sc_rx_size = 16 * 1024 * 1024; 	/* 16MB */
   1797      1.22    nonaka 	sc->sc_rx_ring = hyperv_dma_alloc(sc->sc_dmat, &sc->sc_rx_dma,
   1798      1.22    nonaka 	    sc->sc_rx_size, PAGE_SIZE, PAGE_SIZE, sc->sc_rx_size / PAGE_SIZE);
   1799      1.22    nonaka 	if (sc->sc_rx_ring == NULL) {
   1800      1.22    nonaka 		DPRINTF("%s: failed to allocate Rx ring buffer\n",
   1801      1.22    nonaka 		    device_xname(sc->sc_dev));
   1802      1.22    nonaka 		return -1;
   1803      1.22    nonaka 	}
   1804      1.22    nonaka 
   1805      1.22    nonaka 	sc->sc_rxr = kmem_zalloc(sizeof(*rxr) * ring_cnt, KM_SLEEP);
   1806      1.22    nonaka 	sc->sc_nrxr_inuse = sc->sc_nrxr = ring_cnt;
   1807      1.22    nonaka 
   1808      1.22    nonaka 	for (i = 0; i < sc->sc_nrxr; i++) {
   1809      1.22    nonaka 		rxr = &sc->sc_rxr[i];
   1810      1.22    nonaka 		rxr->rxr_softc = sc;
   1811      1.22    nonaka 		if (i < sc->sc_ntxr) {
   1812      1.22    nonaka 			rxr->rxr_txr = &sc->sc_txr[i];
   1813      1.22    nonaka 			rxr->rxr_txr->txr_rxr = rxr;
   1814      1.22    nonaka 		}
   1815      1.22    nonaka 
   1816      1.22    nonaka 		mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET);
   1817      1.22    nonaka 		mutex_init(&rxr->rxr_onwork_lock, MUTEX_DEFAULT, IPL_NET);
   1818      1.22    nonaka 		cv_init(&rxr->rxr_onwork_cv, "waitonwk");
   1819      1.22    nonaka 
   1820      1.22    nonaka 		snprintf(rxr->rxr_name, sizeof(rxr->rxr_name),
   1821      1.22    nonaka 		    "%s-rx%d", device_xname(sc->sc_dev), i);
   1822      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evpkts, EVCNT_TYPE_MISC,
   1823      1.22    nonaka 		    NULL, rxr->rxr_name, "packets received");
   1824      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evcsum_ip, EVCNT_TYPE_MISC,
   1825      1.22    nonaka 		    NULL, rxr->rxr_name, "IP checksum");
   1826      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evcsum_tcp, EVCNT_TYPE_MISC,
   1827      1.22    nonaka 		    NULL, rxr->rxr_name, "TCP checksum");
   1828      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evcsum_udp, EVCNT_TYPE_MISC,
   1829      1.22    nonaka 		    NULL, rxr->rxr_name, "UDP checksum");
   1830      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evvlanhwtagging, EVCNT_TYPE_MISC,
   1831      1.22    nonaka 		    NULL, rxr->rxr_name, "VLAN H/W tagging");
   1832      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evintr, EVCNT_TYPE_INTR,
   1833      1.22    nonaka 		    NULL, rxr->rxr_name, "interrupt on ring");
   1834      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evdefer, EVCNT_TYPE_MISC,
   1835      1.22    nonaka 		    NULL, rxr->rxr_name, "handled queue in workqueue");
   1836      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evdeferreq, EVCNT_TYPE_MISC,
   1837      1.22    nonaka 		    NULL, rxr->rxr_name, "requested defer on ring");
   1838      1.22    nonaka 		evcnt_attach_dynamic(&rxr->rxr_evredeferreq, EVCNT_TYPE_MISC,
   1839      1.22    nonaka 		    NULL, rxr->rxr_name, "requested defer in workqueue");
   1840      1.22    nonaka 
   1841      1.22    nonaka 		rxr->rxr_nvsbuf = kmem_zalloc(HVN_NVS_BUFSIZE, KM_SLEEP);
   1842      1.22    nonaka 		if (rxr->rxr_nvsbuf == NULL) {
   1843      1.22    nonaka 			DPRINTF("%s: failed to allocate channel data buffer\n",
   1844      1.22    nonaka 			    device_xname(sc->sc_dev));
   1845      1.22    nonaka 			goto errout;
   1846      1.22    nonaka 		}
   1847      1.22    nonaka 
   1848      1.22    nonaka 		rxr->rxr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
   1849      1.22    nonaka 		    hvn_nvs_softintr, rxr);
   1850      1.22    nonaka 		if (rxr->rxr_si == NULL) {
   1851      1.22    nonaka 			DPRINTF("%s: failed to establish rx softint\n",
   1852      1.22    nonaka 			    device_xname(sc->sc_dev));
   1853      1.22    nonaka 			goto errout;
   1854      1.22    nonaka 		}
   1855      1.22    nonaka 	}
   1856      1.22    nonaka 
   1857      1.22    nonaka 	return 0;
   1858      1.22    nonaka 
   1859      1.22    nonaka  errout:
   1860      1.22    nonaka 	hvn_rx_ring_destroy(sc);
   1861      1.22    nonaka 	return -1;
   1862      1.22    nonaka }
   1863       1.1    nonaka 
   1864      1.22    nonaka static int
   1865      1.22    nonaka hvn_rx_ring_destroy(struct hvn_softc *sc)
   1866      1.22    nonaka {
   1867      1.22    nonaka 	struct hvn_rx_ring *rxr;
   1868      1.22    nonaka 	int i;
   1869      1.22    nonaka 
   1870      1.22    nonaka 	if (sc->sc_rxr != NULL) {
   1871      1.22    nonaka 		for (i = 0; i < sc->sc_nrxr; i++) {
   1872      1.22    nonaka 			rxr = &sc->sc_rxr[i];
   1873      1.22    nonaka 
   1874      1.22    nonaka 			if (rxr->rxr_si != NULL) {
   1875      1.22    nonaka 				softint_disestablish(rxr->rxr_si);
   1876      1.22    nonaka 				rxr->rxr_si = NULL;
   1877      1.22    nonaka 			}
   1878      1.22    nonaka 
   1879      1.22    nonaka 			if (rxr->rxr_nvsbuf != NULL) {
   1880      1.22    nonaka 				kmem_free(rxr->rxr_nvsbuf, HVN_NVS_BUFSIZE);
   1881      1.22    nonaka 				rxr->rxr_nvsbuf = NULL;
   1882      1.22    nonaka 			}
   1883      1.22    nonaka 
   1884      1.22    nonaka 			evcnt_detach(&rxr->rxr_evpkts);
   1885      1.22    nonaka 			evcnt_detach(&rxr->rxr_evcsum_ip);
   1886      1.22    nonaka 			evcnt_detach(&rxr->rxr_evcsum_tcp);
   1887      1.22    nonaka 			evcnt_detach(&rxr->rxr_evcsum_udp);
   1888      1.22    nonaka 			evcnt_detach(&rxr->rxr_evvlanhwtagging);
   1889      1.22    nonaka 			evcnt_detach(&rxr->rxr_evintr);
   1890      1.22    nonaka 			evcnt_detach(&rxr->rxr_evdefer);
   1891      1.22    nonaka 			evcnt_detach(&rxr->rxr_evdeferreq);
   1892      1.22    nonaka 			evcnt_detach(&rxr->rxr_evredeferreq);
   1893      1.22    nonaka 
   1894      1.22    nonaka 			cv_destroy(&rxr->rxr_onwork_cv);
   1895      1.22    nonaka 			mutex_destroy(&rxr->rxr_onwork_lock);
   1896      1.22    nonaka 			mutex_destroy(&rxr->rxr_lock);
   1897      1.22    nonaka 		}
   1898      1.22    nonaka 		kmem_free(sc->sc_rxr, sizeof(*rxr) * sc->sc_nrxr);
   1899      1.22    nonaka 		sc->sc_rxr = NULL;
   1900      1.22    nonaka 		sc->sc_nrxr = 0;
   1901      1.22    nonaka 	}
   1902      1.22    nonaka 	if (sc->sc_rx_ring != NULL) {
   1903      1.22    nonaka 		hyperv_dma_free(sc->sc_dmat, &sc->sc_rx_dma);
   1904      1.22    nonaka 		sc->sc_rx_ring = NULL;
   1905      1.22    nonaka 	}
   1906      1.22    nonaka 
   1907      1.22    nonaka 	return 0;
   1908      1.22    nonaka }
   1909      1.22    nonaka 
   1910      1.22    nonaka static void
   1911      1.22    nonaka hvn_fixup_rx_data(struct hvn_softc *sc)
   1912      1.22    nonaka {
   1913      1.22    nonaka 	struct hvn_rx_ring *rxr;
   1914      1.22    nonaka 	int i;
   1915      1.22    nonaka 
   1916      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_UDPHASH) {
   1917      1.22    nonaka 		for (i = 0; i < sc->sc_nrxr; i++) {
   1918      1.22    nonaka 			rxr = &sc->sc_rxr[i];
   1919      1.22    nonaka 			rxr->rxr_flags |= HVN_RXR_FLAG_UDP_HASH;
   1920      1.22    nonaka 		}
   1921      1.22    nonaka 	}
   1922      1.22    nonaka }
   1923      1.22    nonaka 
   1924      1.22    nonaka static int
   1925      1.22    nonaka hvn_tx_ring_create(struct hvn_softc *sc, int ring_cnt)
   1926      1.22    nonaka {
   1927      1.22    nonaka 	struct hvn_tx_ring *txr;
   1928      1.22    nonaka 	struct hvn_tx_desc *txd;
   1929      1.22    nonaka 	bus_dma_segment_t *seg;
   1930      1.22    nonaka 	size_t msgsize;
   1931      1.22    nonaka 	int i, j;
   1932      1.22    nonaka 	paddr_t pa;
   1933      1.22    nonaka 
   1934      1.22    nonaka 	/*
   1935      1.22    nonaka 	 * Create TXBUF for chimney sending.
   1936      1.22    nonaka 	 *
   1937      1.22    nonaka 	 * NOTE: It is shared by all channels.
   1938      1.22    nonaka 	 */
   1939      1.22    nonaka 	sc->sc_chim = hyperv_dma_alloc(sc->sc_dmat, &sc->sc_chim_dma,
   1940      1.22    nonaka 	    HVN_CHIM_SIZE, PAGE_SIZE, 0, 1);
   1941      1.22    nonaka 	if (sc->sc_chim == NULL) {
   1942      1.22    nonaka 		DPRINTF("%s: failed to allocate chimney sending memory",
   1943      1.22    nonaka 		    device_xname(sc->sc_dev));
   1944      1.22    nonaka 		goto errout;
   1945      1.22    nonaka 	}
   1946      1.22    nonaka 
   1947      1.22    nonaka 	sc->sc_txr = kmem_zalloc(sizeof(*txr) * ring_cnt, KM_SLEEP);
   1948      1.22    nonaka 	sc->sc_ntxr_inuse = sc->sc_ntxr = ring_cnt;
   1949      1.22    nonaka 
   1950      1.22    nonaka 	msgsize = roundup(HVN_RNDIS_PKT_LEN, 128);
   1951      1.22    nonaka 
   1952      1.22    nonaka 	for (j = 0; j < ring_cnt; j++) {
   1953      1.22    nonaka 		txr = &sc->sc_txr[j];
   1954      1.22    nonaka 		txr->txr_softc = sc;
   1955      1.22    nonaka 		txr->txr_id = j;
   1956      1.22    nonaka 
   1957      1.22    nonaka 		mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET);
   1958      1.22    nonaka 		txr->txr_interq = pcq_create(HVN_TX_DESC, KM_SLEEP);
   1959      1.22    nonaka 
   1960      1.22    nonaka 		snprintf(txr->txr_name, sizeof(txr->txr_name),
   1961      1.22    nonaka 		    "%s-tx%d", device_xname(sc->sc_dev), j);
   1962      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evpkts, EVCNT_TYPE_MISC,
   1963      1.22    nonaka 		    NULL, txr->txr_name, "packets transmit");
   1964      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evsends, EVCNT_TYPE_MISC,
   1965      1.22    nonaka 		    NULL, txr->txr_name, "sends");
   1966      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evnodesc, EVCNT_TYPE_MISC,
   1967      1.22    nonaka 		    NULL, txr->txr_name, "descriptor shortage");
   1968      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evdmafailed, EVCNT_TYPE_MISC,
   1969      1.22    nonaka 		    NULL, txr->txr_name, "DMA failure");
   1970      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evdefrag, EVCNT_TYPE_MISC,
   1971      1.22    nonaka 		    NULL, txr->txr_name, "mbuf defraged");
   1972      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evpcqdrop, EVCNT_TYPE_MISC,
   1973      1.22    nonaka 		    NULL, txr->txr_name, "dropped in pcq");
   1974      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evtransmitdefer, EVCNT_TYPE_MISC,
   1975      1.22    nonaka 		    NULL, txr->txr_name, "deferred transmit");
   1976      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evflushfailed, EVCNT_TYPE_MISC,
   1977      1.22    nonaka 		    NULL, txr->txr_name, "aggregation flush failure");
   1978      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evchimneytried, EVCNT_TYPE_MISC,
   1979      1.22    nonaka 		    NULL, txr->txr_name, "chimney send tried");
   1980      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evchimney, EVCNT_TYPE_MISC,
   1981      1.22    nonaka 		    NULL, txr->txr_name, "chimney send");
   1982      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evvlanfixup, EVCNT_TYPE_MISC,
   1983      1.22    nonaka 		    NULL, txr->txr_name, "VLAN fixup");
   1984      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evvlanhwtagging, EVCNT_TYPE_MISC,
   1985      1.22    nonaka 		    NULL, txr->txr_name, "VLAN H/W tagging");
   1986      1.22    nonaka 		evcnt_attach_dynamic(&txr->txr_evvlantap, EVCNT_TYPE_MISC,
   1987      1.22    nonaka 		    NULL, txr->txr_name, "VLAN bpf_mtap fixup");
   1988      1.22    nonaka 
   1989      1.22    nonaka 		txr->txr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
   1990      1.22    nonaka 		    hvn_deferred_transmit, txr);
   1991      1.22    nonaka 		if (txr->txr_si == NULL) {
   1992      1.22    nonaka 			aprint_error_dev(sc->sc_dev,
   1993      1.22    nonaka 			    "failed to establish softint for tx ring\n");
   1994      1.22    nonaka 			goto errout;
   1995      1.22    nonaka 		}
   1996      1.22    nonaka 
   1997      1.22    nonaka 		/* Allocate memory to store RNDIS messages */
   1998      1.22    nonaka 		txr->txr_msgs = hyperv_dma_alloc(sc->sc_dmat, &txr->txr_dma,
   1999      1.22    nonaka 		    msgsize * HVN_TX_DESC, PAGE_SIZE, 0, 1);
   2000      1.22    nonaka 		if (txr->txr_msgs == NULL) {
   2001      1.22    nonaka 			DPRINTF("%s: failed to allocate memory for RDNIS "
   2002      1.22    nonaka 			    "messages\n", device_xname(sc->sc_dev));
   2003      1.22    nonaka 			goto errout;
   2004      1.22    nonaka 		}
   2005      1.22    nonaka 
   2006      1.22    nonaka 		TAILQ_INIT(&txr->txr_list);
   2007      1.22    nonaka 		for (i = 0; i < HVN_TX_DESC; i++) {
   2008      1.22    nonaka 			txd = &txr->txr_desc[i];
   2009      1.22    nonaka 			txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID;
   2010      1.22    nonaka 			txd->txd_chim_size = 0;
   2011      1.22    nonaka 			STAILQ_INIT(&txd->txd_agg_list);
   2012      1.22    nonaka 			if (bus_dmamap_create(sc->sc_dmat, HVN_TX_PKT_SIZE,
   2013      1.22    nonaka 			    HVN_TX_FRAGS, HVN_TX_FRAG_SIZE, PAGE_SIZE,
   2014      1.22    nonaka 			    BUS_DMA_WAITOK, &txd->txd_dmap)) {
   2015      1.22    nonaka 				DPRINTF("%s: failed to create map for TX "
   2016      1.22    nonaka 				    "descriptors\n", device_xname(sc->sc_dev));
   2017      1.22    nonaka 				goto errout;
   2018      1.22    nonaka 			}
   2019      1.22    nonaka 			seg = &txr->txr_dma.map->dm_segs[0];
   2020      1.22    nonaka 			pa = seg->ds_addr + (msgsize * i);
   2021      1.22    nonaka 			txd->txd_gpa.gpa_page = atop(pa);
   2022      1.22    nonaka 			txd->txd_gpa.gpa_ofs = pa & PAGE_MASK;
   2023      1.22    nonaka 			txd->txd_gpa.gpa_len = msgsize;
   2024      1.22    nonaka 			txd->txd_req = (void *)(txr->txr_msgs + (msgsize * i));
   2025      1.22    nonaka 			txd->txd_id = i + HVN_NVS_CHIM_SIG;
   2026      1.22    nonaka 			TAILQ_INSERT_TAIL(&txr->txr_list, txd, txd_entry);
   2027      1.22    nonaka 		}
   2028      1.22    nonaka 		txr->txr_avail = HVN_TX_DESC;
   2029      1.22    nonaka 	}
   2030      1.22    nonaka 
   2031      1.22    nonaka 	return 0;
   2032      1.22    nonaka 
   2033      1.22    nonaka  errout:
   2034      1.22    nonaka 	hvn_tx_ring_destroy(sc);
   2035      1.22    nonaka 	return -1;
   2036       1.1    nonaka }
   2037       1.1    nonaka 
   2038       1.1    nonaka static void
   2039      1.22    nonaka hvn_tx_ring_destroy(struct hvn_softc *sc)
   2040       1.1    nonaka {
   2041      1.22    nonaka 	struct hvn_tx_ring *txr;
   2042       1.1    nonaka 	struct hvn_tx_desc *txd;
   2043      1.22    nonaka 	int i, j;
   2044      1.22    nonaka 
   2045      1.22    nonaka 	if (sc->sc_txr != NULL) {
   2046      1.22    nonaka 		for (j = 0; j < sc->sc_ntxr; j++) {
   2047      1.22    nonaka 			txr = &sc->sc_txr[j];
   2048      1.22    nonaka 
   2049      1.22    nonaka 			mutex_enter(&txr->txr_lock);
   2050      1.22    nonaka 			for (i = 0; i < HVN_TX_DESC; i++) {
   2051      1.22    nonaka 				txd = &txr->txr_desc[i];
   2052      1.22    nonaka 				hvn_txd_gc(txr, txd);
   2053      1.22    nonaka 			}
   2054      1.22    nonaka 			mutex_exit(&txr->txr_lock);
   2055      1.22    nonaka 			for (i = 0; i < HVN_TX_DESC; i++) {
   2056      1.22    nonaka 				txd = &txr->txr_desc[i];
   2057      1.22    nonaka 				if (txd->txd_dmap != NULL) {
   2058      1.22    nonaka 					bus_dmamap_destroy(sc->sc_dmat,
   2059      1.22    nonaka 					    txd->txd_dmap);
   2060      1.22    nonaka 					txd->txd_dmap = NULL;
   2061      1.22    nonaka 				}
   2062      1.22    nonaka 			}
   2063      1.22    nonaka 			if (txr->txr_msgs != NULL) {
   2064      1.22    nonaka 				hyperv_dma_free(sc->sc_dmat, &txr->txr_dma);
   2065      1.22    nonaka 				txr->txr_msgs = NULL;
   2066      1.22    nonaka 			}
   2067      1.22    nonaka 			if (txr->txr_si != NULL) {
   2068      1.22    nonaka 				softint_disestablish(txr->txr_si);
   2069      1.22    nonaka 				txr->txr_si = NULL;
   2070      1.22    nonaka 			}
   2071      1.22    nonaka 			if (txr->txr_interq != NULL) {
   2072      1.22    nonaka 				hvn_tx_ring_qflush(sc, txr);
   2073      1.22    nonaka 				pcq_destroy(txr->txr_interq);
   2074      1.22    nonaka 				txr->txr_interq = NULL;
   2075      1.22    nonaka 			}
   2076      1.22    nonaka 
   2077      1.22    nonaka 			evcnt_detach(&txr->txr_evpkts);
   2078      1.22    nonaka 			evcnt_detach(&txr->txr_evsends);
   2079      1.22    nonaka 			evcnt_detach(&txr->txr_evnodesc);
   2080      1.22    nonaka 			evcnt_detach(&txr->txr_evdmafailed);
   2081      1.22    nonaka 			evcnt_detach(&txr->txr_evdefrag);
   2082      1.22    nonaka 			evcnt_detach(&txr->txr_evpcqdrop);
   2083      1.22    nonaka 			evcnt_detach(&txr->txr_evtransmitdefer);
   2084      1.22    nonaka 			evcnt_detach(&txr->txr_evflushfailed);
   2085      1.22    nonaka 			evcnt_detach(&txr->txr_evchimneytried);
   2086      1.22    nonaka 			evcnt_detach(&txr->txr_evchimney);
   2087      1.22    nonaka 			evcnt_detach(&txr->txr_evvlanfixup);
   2088      1.22    nonaka 			evcnt_detach(&txr->txr_evvlanhwtagging);
   2089      1.22    nonaka 			evcnt_detach(&txr->txr_evvlantap);
   2090      1.22    nonaka 
   2091      1.22    nonaka 			mutex_destroy(&txr->txr_lock);
   2092      1.22    nonaka 		}
   2093      1.22    nonaka 
   2094      1.22    nonaka 		kmem_free(sc->sc_txr, sizeof(*txr) * sc->sc_ntxr);
   2095      1.22    nonaka 		sc->sc_txr = NULL;
   2096      1.22    nonaka 	}
   2097      1.22    nonaka 
   2098      1.22    nonaka 	if (sc->sc_chim != NULL) {
   2099      1.22    nonaka 		hyperv_dma_free(sc->sc_dmat, &sc->sc_chim_dma);
   2100      1.22    nonaka 		sc->sc_chim = NULL;
   2101      1.22    nonaka 	}
   2102      1.22    nonaka }
   2103      1.22    nonaka 
   2104      1.22    nonaka static void
   2105      1.22    nonaka hvn_set_chim_size(struct hvn_softc *sc, int chim_size)
   2106      1.22    nonaka {
   2107      1.22    nonaka 	struct hvn_tx_ring *txr;
   2108      1.22    nonaka 	int i;
   2109      1.22    nonaka 
   2110      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr_inuse; i++) {
   2111      1.22    nonaka 		txr = &sc->sc_txr[i];
   2112      1.22    nonaka 		txr->txr_chim_size = chim_size;
   2113      1.22    nonaka 	}
   2114      1.22    nonaka }
   2115      1.22    nonaka 
   2116      1.22    nonaka #if LONG_BIT == 64
   2117      1.22    nonaka #define ffsl(v)	ffs64(v)
   2118      1.22    nonaka #elif LONG_BIT == 32
   2119      1.22    nonaka #define ffsl(v)	ffs32(v)
   2120      1.22    nonaka #else
   2121      1.22    nonaka #error unsupport LONG_BIT
   2122      1.22    nonaka #endif  /* LONG_BIT */
   2123      1.22    nonaka 
   2124      1.22    nonaka static uint32_t
   2125      1.22    nonaka hvn_chim_alloc(struct hvn_softc *sc)
   2126      1.22    nonaka {
   2127      1.22    nonaka 	uint32_t chim_idx = HVN_NVS_CHIM_IDX_INVALID;
   2128      1.22    nonaka 	int i, idx;
   2129      1.22    nonaka 
   2130      1.22    nonaka 	mutex_spin_enter(&sc->sc_chim_bmap_lock);
   2131      1.22    nonaka 	for (i = 0; i < sc->sc_chim_bmap_cnt; i++) {
   2132      1.22    nonaka 		idx = ffsl(~sc->sc_chim_bmap[i]);
   2133      1.22    nonaka 		if (idx == 0)
   2134      1.22    nonaka 			continue;
   2135      1.22    nonaka 
   2136      1.22    nonaka 		--idx;	/* ffsl is 1-based */
   2137      1.22    nonaka 		SET(sc->sc_chim_bmap[i], __BIT(idx));
   2138      1.22    nonaka 
   2139      1.22    nonaka 		chim_idx = i * LONG_BIT + idx;
   2140      1.22    nonaka 		break;
   2141      1.22    nonaka 	}
   2142      1.22    nonaka 	mutex_spin_exit(&sc->sc_chim_bmap_lock);
   2143      1.22    nonaka 
   2144      1.22    nonaka 	return chim_idx;
   2145      1.22    nonaka }
   2146      1.22    nonaka 
   2147      1.22    nonaka static void
   2148      1.22    nonaka hvn_chim_free(struct hvn_softc *sc, uint32_t chim_idx)
   2149      1.22    nonaka {
   2150      1.22    nonaka 	u_long mask;
   2151      1.22    nonaka 	uint32_t idx;
   2152      1.22    nonaka 
   2153      1.22    nonaka 	idx = chim_idx / LONG_BIT;
   2154      1.22    nonaka 	mask = __BIT(chim_idx % LONG_BIT);
   2155      1.22    nonaka 
   2156      1.22    nonaka 	mutex_spin_enter(&sc->sc_chim_bmap_lock);
   2157      1.22    nonaka 	CLR(sc->sc_chim_bmap[idx], mask);
   2158      1.22    nonaka 	mutex_spin_exit(&sc->sc_chim_bmap_lock);
   2159      1.22    nonaka }
   2160      1.22    nonaka 
   2161      1.22    nonaka static void
   2162      1.22    nonaka hvn_fixup_tx_data(struct hvn_softc *sc)
   2163      1.22    nonaka {
   2164      1.22    nonaka 	struct hvn_tx_ring *txr;
   2165      1.22    nonaka 	uint64_t caps_assist;
   2166      1.22    nonaka 	int csum_assist;
   2167      1.22    nonaka 	int i;
   2168      1.22    nonaka 
   2169      1.22    nonaka 	hvn_set_chim_size(sc, sc->sc_chim_szmax);
   2170      1.22    nonaka 	if (hvn_tx_chimney_size > 0 && hvn_tx_chimney_size < sc->sc_chim_szmax)
   2171      1.22    nonaka 		hvn_set_chim_size(sc, hvn_tx_chimney_size);
   2172      1.22    nonaka 
   2173      1.22    nonaka 	caps_assist = 0;
   2174      1.22    nonaka 	csum_assist = 0;
   2175      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_IPCS) {
   2176      1.22    nonaka 		caps_assist |= IFCAP_CSUM_IPv4_Tx;
   2177      1.22    nonaka 		caps_assist |= IFCAP_CSUM_IPv4_Rx;
   2178      1.22    nonaka 		csum_assist |= M_CSUM_IPv4;
   2179      1.22    nonaka 	}
   2180      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_TCP4CS) {
   2181      1.22    nonaka 		caps_assist |= IFCAP_CSUM_TCPv4_Tx;
   2182      1.22    nonaka 		caps_assist |= IFCAP_CSUM_TCPv4_Rx;
   2183      1.22    nonaka 		csum_assist |= M_CSUM_TCPv4;
   2184      1.22    nonaka 	}
   2185      1.22    nonaka 	if (sc->sc_caps &  HVN_CAPS_TCP6CS) {
   2186      1.22    nonaka 		caps_assist |= IFCAP_CSUM_TCPv6_Tx;
   2187      1.22    nonaka 		csum_assist |= M_CSUM_TCPv6;
   2188      1.22    nonaka 	}
   2189      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_UDP4CS) {
   2190      1.22    nonaka 		caps_assist |= IFCAP_CSUM_UDPv4_Tx;
   2191      1.22    nonaka 		caps_assist |= IFCAP_CSUM_UDPv4_Rx;
   2192      1.22    nonaka 		csum_assist |= M_CSUM_UDPv4;
   2193      1.22    nonaka 	}
   2194      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_UDP6CS) {
   2195      1.22    nonaka 		caps_assist |= IFCAP_CSUM_UDPv6_Tx;
   2196      1.22    nonaka 		csum_assist |= M_CSUM_UDPv6;
   2197      1.22    nonaka 	}
   2198      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr; i++) {
   2199      1.22    nonaka 		txr = &sc->sc_txr[i];
   2200      1.22    nonaka 		txr->txr_caps_assist = caps_assist;
   2201      1.22    nonaka 		txr->txr_csum_assist = csum_assist;
   2202      1.22    nonaka 	}
   2203      1.22    nonaka 
   2204      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_UDPHASH) {
   2205      1.22    nonaka 		for (i = 0; i < sc->sc_ntxr; i++) {
   2206      1.22    nonaka 			txr = &sc->sc_txr[i];
   2207      1.22    nonaka 			txr->txr_flags |= HVN_TXR_FLAG_UDP_HASH;
   2208      1.22    nonaka 		}
   2209      1.22    nonaka 	}
   2210      1.22    nonaka }
   2211      1.22    nonaka 
   2212      1.22    nonaka static int
   2213      1.22    nonaka hvn_txd_peek(struct hvn_tx_ring *txr)
   2214      1.22    nonaka {
   2215      1.22    nonaka 
   2216      1.22    nonaka 	KASSERT(mutex_owned(&txr->txr_lock));
   2217      1.22    nonaka 
   2218      1.22    nonaka 	return txr->txr_avail;
   2219      1.22    nonaka }
   2220      1.22    nonaka 
   2221      1.22    nonaka static struct hvn_tx_desc *
   2222      1.22    nonaka hvn_txd_get(struct hvn_tx_ring *txr)
   2223      1.22    nonaka {
   2224      1.22    nonaka 	struct hvn_tx_desc *txd;
   2225      1.22    nonaka 
   2226      1.22    nonaka 	KASSERT(mutex_owned(&txr->txr_lock));
   2227      1.22    nonaka 
   2228      1.22    nonaka 	txd = TAILQ_FIRST(&txr->txr_list);
   2229      1.22    nonaka 	KASSERT(txd != NULL);
   2230      1.22    nonaka 	TAILQ_REMOVE(&txr->txr_list, txd, txd_entry);
   2231      1.22    nonaka 	txr->txr_avail--;
   2232      1.22    nonaka 
   2233      1.22    nonaka 	txd->txd_refs = 1;
   2234      1.22    nonaka 
   2235      1.22    nonaka 	return txd;
   2236      1.22    nonaka }
   2237      1.22    nonaka 
   2238      1.22    nonaka static void
   2239      1.22    nonaka hvn_txd_put(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd)
   2240      1.22    nonaka {
   2241      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   2242      1.22    nonaka 	struct hvn_tx_desc *tmp_txd;
   2243      1.22    nonaka 
   2244      1.22    nonaka 	KASSERT(mutex_owned(&txr->txr_lock));
   2245      1.22    nonaka 	KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG),
   2246      1.22    nonaka 	    "put an onagg txd %#x", txd->txd_flags);
   2247      1.22    nonaka 
   2248      1.22    nonaka 	KASSERTMSG(txd->txd_refs > 0, "invalid txd refs %d", txd->txd_refs);
   2249      1.22    nonaka 	if (atomic_dec_uint_nv(&txd->txd_refs) != 0)
   2250      1.22    nonaka 		return;
   2251      1.22    nonaka 
   2252      1.22    nonaka 	if (!STAILQ_EMPTY(&txd->txd_agg_list)) {
   2253      1.22    nonaka 		while ((tmp_txd = STAILQ_FIRST(&txd->txd_agg_list)) != NULL) {
   2254      1.22    nonaka 			KASSERTMSG(STAILQ_EMPTY(&tmp_txd->txd_agg_list),
   2255      1.22    nonaka 			    "resursive aggregation on aggregated txdesc");
   2256      1.22    nonaka 			KASSERTMSG(
   2257      1.22    nonaka 			    ISSET(tmp_txd->txd_flags, HVN_TXD_FLAG_ONAGG),
   2258      1.22    nonaka 			    "not aggregated txdesc");
   2259      1.22    nonaka 			KASSERTMSG(
   2260      1.22    nonaka 			    tmp_txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID,
   2261      1.22    nonaka 			    "aggregated txdesc consumes chimney sending "
   2262      1.22    nonaka 			    "buffer: idx %u", tmp_txd->txd_chim_index);
   2263      1.22    nonaka 			KASSERTMSG(tmp_txd->txd_chim_size == 0,
   2264      1.22    nonaka 			    "aggregated txdesc has non-zero chimney sending "
   2265      1.22    nonaka 			    "size: sz %u", tmp_txd->txd_chim_size);
   2266      1.22    nonaka 
   2267      1.22    nonaka 			STAILQ_REMOVE_HEAD(&txd->txd_agg_list, txd_agg_entry);
   2268      1.22    nonaka 			CLR(tmp_txd->txd_flags, HVN_TXD_FLAG_ONAGG);
   2269      1.22    nonaka 			hvn_txd_put(txr, tmp_txd);
   2270      1.22    nonaka 		}
   2271      1.22    nonaka 	}
   2272      1.22    nonaka 
   2273      1.22    nonaka 	if (txd->txd_chim_index != HVN_NVS_CHIM_IDX_INVALID) {
   2274      1.22    nonaka 		KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP),
   2275      1.22    nonaka 		    "chim txd uses dmamap");
   2276      1.22    nonaka 		hvn_chim_free(sc, txd->txd_chim_index);
   2277      1.22    nonaka 		txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID;
   2278      1.22    nonaka 		txd->txd_chim_size = 0;
   2279      1.22    nonaka 	} else if (ISSET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP)) {
   2280      1.22    nonaka 		bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap,
   2281      1.22    nonaka 		    0, txd->txd_dmap->dm_mapsize,
   2282      1.22    nonaka 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   2283      1.22    nonaka 		bus_dmamap_unload(sc->sc_dmat, txd->txd_dmap);
   2284      1.22    nonaka 		CLR(txd->txd_flags, HVN_TXD_FLAG_DMAMAP);
   2285      1.22    nonaka 	}
   2286      1.22    nonaka 
   2287  1.27.2.1  perseant 	m_freem(txd->txd_buf);
   2288  1.27.2.1  perseant 	txd->txd_buf = NULL;
   2289      1.22    nonaka 
   2290      1.22    nonaka 	TAILQ_INSERT_TAIL(&txr->txr_list, txd, txd_entry);
   2291      1.22    nonaka 	txr->txr_avail++;
   2292      1.22    nonaka 	txr->txr_oactive = 0;
   2293      1.22    nonaka }
   2294      1.22    nonaka 
   2295      1.22    nonaka static void
   2296      1.22    nonaka hvn_txd_gc(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd)
   2297      1.22    nonaka {
   2298      1.22    nonaka 
   2299      1.22    nonaka 	KASSERTMSG(txd->txd_refs == 0 || txd->txd_refs == 1,
   2300      1.22    nonaka 	    "invalid txd refs %d", txd->txd_refs);
   2301      1.22    nonaka 
   2302      1.22    nonaka 	/* Aggregated txds will be freed by their aggregating txd. */
   2303      1.22    nonaka 	if (txd->txd_refs > 0 && !ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG))
   2304      1.22    nonaka 		hvn_txd_put(txr, txd);
   2305      1.22    nonaka }
   2306      1.22    nonaka 
   2307      1.22    nonaka static void
   2308      1.22    nonaka hvn_txd_hold(struct hvn_tx_desc *txd)
   2309      1.22    nonaka {
   2310      1.22    nonaka 
   2311      1.22    nonaka 	/* 0->1 transition will never work */
   2312      1.22    nonaka 	KASSERTMSG(txd->txd_refs > 0, "invalid txd refs %d", txd->txd_refs);
   2313      1.22    nonaka 
   2314      1.22    nonaka 	atomic_inc_uint(&txd->txd_refs);
   2315      1.22    nonaka }
   2316      1.22    nonaka 
   2317      1.22    nonaka static void
   2318      1.22    nonaka hvn_txd_agg(struct hvn_tx_desc *agg_txd, struct hvn_tx_desc *txd)
   2319      1.22    nonaka {
   2320      1.22    nonaka 
   2321      1.22    nonaka 	KASSERTMSG(!ISSET(agg_txd->txd_flags, HVN_TXD_FLAG_ONAGG),
   2322      1.22    nonaka 	    "recursive aggregation on aggregating txdesc");
   2323      1.22    nonaka 	KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG),
   2324      1.22    nonaka 	    "already aggregated");
   2325      1.22    nonaka 	KASSERTMSG(STAILQ_EMPTY(&txd->txd_agg_list),
   2326      1.22    nonaka 	    "recursive aggregation on to-be-aggregated txdesc");
   2327      1.22    nonaka 
   2328      1.22    nonaka 	SET(txd->txd_flags, HVN_TXD_FLAG_ONAGG);
   2329      1.22    nonaka 	STAILQ_INSERT_TAIL(&agg_txd->txd_agg_list, txd, txd_agg_entry);
   2330      1.22    nonaka }
   2331      1.22    nonaka 
   2332      1.22    nonaka static int
   2333      1.22    nonaka hvn_tx_ring_pending(struct hvn_tx_ring *txr)
   2334      1.22    nonaka {
   2335      1.22    nonaka 	int pending = 0;
   2336      1.22    nonaka 
   2337      1.22    nonaka 	mutex_enter(&txr->txr_lock);
   2338      1.22    nonaka 	if (hvn_txd_peek(txr) != HVN_TX_DESC)
   2339      1.22    nonaka 		pending = 1;
   2340      1.22    nonaka 	mutex_exit(&txr->txr_lock);
   2341      1.22    nonaka 
   2342      1.22    nonaka 	return pending;
   2343      1.22    nonaka }
   2344      1.22    nonaka 
   2345      1.22    nonaka static void
   2346      1.22    nonaka hvn_tx_ring_qflush(struct hvn_softc *sc, struct hvn_tx_ring *txr)
   2347      1.22    nonaka {
   2348       1.1    nonaka 	struct mbuf *m;
   2349       1.1    nonaka 
   2350      1.22    nonaka 	while ((m = pcq_get(txr->txr_interq)) != NULL)
   2351      1.22    nonaka 		m_freem(m);
   2352      1.22    nonaka }
   2353      1.22    nonaka 
   2354      1.22    nonaka static int
   2355      1.22    nonaka hvn_get_lladdr(struct hvn_softc *sc, uint8_t *enaddr)
   2356      1.22    nonaka {
   2357      1.22    nonaka 	size_t addrlen = ETHER_ADDR_LEN;
   2358      1.22    nonaka 	int rv;
   2359      1.22    nonaka 
   2360      1.22    nonaka 	rv = hvn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, enaddr, &addrlen);
   2361      1.22    nonaka 	if (rv == 0 && addrlen != ETHER_ADDR_LEN)
   2362      1.22    nonaka 		rv = -1;
   2363      1.22    nonaka 	return rv;
   2364      1.22    nonaka }
   2365      1.22    nonaka 
   2366      1.22    nonaka static void
   2367      1.22    nonaka hvn_update_link_status(struct hvn_softc *sc)
   2368      1.22    nonaka {
   2369      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   2370      1.22    nonaka 	uint32_t state, old_link_state;
   2371      1.22    nonaka 	size_t len = sizeof(state);
   2372      1.22    nonaka 	int rv;
   2373      1.22    nonaka 
   2374      1.22    nonaka 	rv = hvn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS, &state, &len);
   2375      1.22    nonaka 	if (rv != 0 || len != sizeof(state))
   2376      1.22    nonaka 		return;
   2377      1.22    nonaka 
   2378      1.22    nonaka 	old_link_state = sc->sc_link_state;
   2379      1.22    nonaka 	sc->sc_link_state = (state == NDIS_MEDIA_STATE_CONNECTED) ?
   2380      1.22    nonaka 	    LINK_STATE_UP : LINK_STATE_DOWN;
   2381      1.22    nonaka 	if (old_link_state != sc->sc_link_state) {
   2382      1.22    nonaka 		if_link_state_change(ifp, sc->sc_link_state);
   2383      1.22    nonaka 	}
   2384      1.22    nonaka }
   2385      1.22    nonaka 
   2386      1.22    nonaka static int
   2387      1.22    nonaka hvn_get_mtu(struct hvn_softc *sc, uint32_t *mtu)
   2388      1.22    nonaka {
   2389      1.22    nonaka 	size_t mtusz = sizeof(*mtu);
   2390      1.22    nonaka 	int rv;
   2391      1.22    nonaka 
   2392      1.22    nonaka 	rv = hvn_rndis_query(sc, OID_GEN_MAXIMUM_FRAME_SIZE, mtu, &mtusz);
   2393      1.22    nonaka 	if (rv == 0 && mtusz != sizeof(*mtu))
   2394      1.22    nonaka 		rv = -1;
   2395      1.22    nonaka 	return rv;
   2396      1.22    nonaka }
   2397      1.22    nonaka 
   2398      1.22    nonaka static int
   2399      1.22    nonaka hvn_channel_attach(struct hvn_softc *sc, struct vmbus_channel *chan)
   2400      1.22    nonaka {
   2401      1.22    nonaka 	struct hvn_rx_ring *rxr;
   2402      1.22    nonaka 	struct hvn_tx_ring *txr;
   2403      1.22    nonaka 	int idx;
   2404      1.22    nonaka 
   2405      1.22    nonaka 	idx = chan->ch_subidx;
   2406      1.22    nonaka 	if (idx < 0 || idx >= sc->sc_nrxr_inuse) {
   2407      1.22    nonaka 		DPRINTF("%s: invalid sub-channel %u\n",
   2408      1.22    nonaka 		    device_xname(sc->sc_dev), idx);
   2409      1.22    nonaka 		return -1;
   2410      1.22    nonaka 	}
   2411      1.22    nonaka 
   2412      1.22    nonaka 	rxr = &sc->sc_rxr[idx];
   2413      1.22    nonaka 	rxr->rxr_chan = chan;
   2414      1.22    nonaka 
   2415      1.22    nonaka 	if (idx < sc->sc_ntxr_inuse) {
   2416      1.22    nonaka 		txr = &sc->sc_txr[idx];
   2417      1.22    nonaka 		txr->txr_chan = chan;
   2418      1.22    nonaka 	}
   2419      1.22    nonaka 
   2420      1.22    nonaka 	/* Bind this channel to a proper CPU. */
   2421      1.22    nonaka 	vmbus_channel_cpu_set(chan, HVN_RING_IDX2CPU(sc, idx));
   2422      1.22    nonaka 
   2423      1.22    nonaka 	chan->ch_flags &= ~CHF_BATCHED;
   2424      1.22    nonaka 
   2425      1.22    nonaka 	/* Associate our interrupt handler with the channel */
   2426      1.22    nonaka 	if (vmbus_channel_open(chan,
   2427      1.22    nonaka 	    HVN_RING_BUFSIZE - sizeof(struct vmbus_bufring), NULL, 0,
   2428      1.22    nonaka 	    hvn_nvs_intr, rxr)) {
   2429      1.22    nonaka 		DPRINTF("%s: failed to open channel\n",
   2430      1.22    nonaka 		    device_xname(sc->sc_dev));
   2431      1.22    nonaka 		return -1;
   2432      1.22    nonaka 	}
   2433      1.22    nonaka 
   2434      1.22    nonaka 	return 0;
   2435      1.22    nonaka }
   2436      1.22    nonaka 
   2437      1.22    nonaka static void
   2438      1.22    nonaka hvn_channel_detach(struct hvn_softc *sc, struct vmbus_channel *chan)
   2439      1.22    nonaka {
   2440      1.22    nonaka 
   2441      1.22    nonaka 	vmbus_channel_close_direct(chan);
   2442      1.22    nonaka }
   2443      1.22    nonaka 
   2444      1.22    nonaka static void
   2445      1.22    nonaka hvn_channel_detach_all(struct hvn_softc *sc)
   2446      1.22    nonaka {
   2447      1.22    nonaka 	struct vmbus_channel **subchans;
   2448      1.22    nonaka 	int i, subchan_cnt = sc->sc_nrxr_inuse - 1;
   2449      1.22    nonaka 
   2450      1.22    nonaka 	if (subchan_cnt > 0) {
   2451      1.22    nonaka 		/* Detach the sub-channels. */
   2452      1.22    nonaka 		subchans = vmbus_subchannel_get(sc->sc_prichan, subchan_cnt);
   2453      1.22    nonaka 		for (i = 0; i < subchan_cnt; i++)
   2454      1.22    nonaka 			hvn_channel_detach(sc, subchans[i]);
   2455      1.22    nonaka 		vmbus_subchannel_rel(subchans, subchan_cnt);
   2456      1.22    nonaka 	}
   2457      1.22    nonaka 
   2458      1.22    nonaka 	/*
   2459      1.22    nonaka 	 * Detach the primary channel, _after_ all sub-channels
   2460      1.22    nonaka 	 * are detached.
   2461      1.22    nonaka 	 */
   2462      1.22    nonaka 	hvn_channel_detach(sc, sc->sc_prichan);
   2463      1.22    nonaka 
   2464      1.22    nonaka 	/* Wait for sub-channels to be destroyed, if any. */
   2465      1.22    nonaka 	vmbus_subchannel_drain(sc->sc_prichan);
   2466      1.22    nonaka }
   2467      1.22    nonaka 
   2468      1.22    nonaka static int
   2469      1.22    nonaka hvn_subchannel_attach(struct hvn_softc *sc)
   2470      1.22    nonaka {
   2471      1.22    nonaka 	struct vmbus_channel **subchans;
   2472      1.22    nonaka 	int subchan_cnt = sc->sc_nrxr_inuse - 1;
   2473      1.22    nonaka 	int i, error = 0;
   2474      1.22    nonaka 
   2475      1.22    nonaka 	KASSERTMSG(subchan_cnt > 0, "no sub-channels");
   2476      1.22    nonaka 
   2477      1.22    nonaka 	/* Attach the sub-channels. */
   2478      1.22    nonaka 	subchans = vmbus_subchannel_get(sc->sc_prichan, subchan_cnt);
   2479      1.22    nonaka 	for (i = 0; i < subchan_cnt; ++i) {
   2480      1.22    nonaka 		int error1;
   2481      1.22    nonaka 
   2482      1.22    nonaka 		error1 = hvn_channel_attach(sc, subchans[i]);
   2483      1.22    nonaka 		if (error1) {
   2484      1.22    nonaka 			error = error1;
   2485      1.22    nonaka 			/* Move on; all channels will be detached later. */
   2486      1.22    nonaka 		}
   2487      1.22    nonaka 	}
   2488      1.22    nonaka 	vmbus_subchannel_rel(subchans, subchan_cnt);
   2489      1.22    nonaka 
   2490      1.22    nonaka 	if (error) {
   2491      1.22    nonaka 		aprint_error_dev(sc->sc_dev,
   2492      1.22    nonaka 		    "sub-channels attach failed: %d\n", error);
   2493      1.22    nonaka 		return error;
   2494      1.22    nonaka 	}
   2495      1.22    nonaka 
   2496      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "%d sub-channels attached\n",
   2497      1.22    nonaka 	    subchan_cnt);
   2498      1.22    nonaka 	return 0;
   2499      1.22    nonaka }
   2500      1.22    nonaka 
   2501      1.22    nonaka static int
   2502      1.22    nonaka hvn_synth_alloc_subchannels(struct hvn_softc *sc, int *nsubch)
   2503      1.22    nonaka {
   2504      1.22    nonaka 	struct vmbus_channel **subchans;
   2505      1.22    nonaka 	int error, nchan, rxr_cnt;
   2506      1.22    nonaka 
   2507      1.22    nonaka 	nchan = *nsubch + 1;
   2508      1.22    nonaka 	if (nchan < 2) {
   2509      1.22    nonaka 		/* Multiple RX/TX rings are not requested. */
   2510      1.22    nonaka 		*nsubch = 0;
   2511      1.22    nonaka 		return 0;
   2512      1.22    nonaka 	}
   2513      1.22    nonaka 
   2514      1.22    nonaka 	/*
   2515      1.22    nonaka 	 * Query RSS capabilities, e.g. # of RX rings, and # of indirect
   2516      1.22    nonaka 	 * table entries.
   2517      1.22    nonaka 	 */
   2518      1.22    nonaka 	if (hvn_get_rsscaps(sc, &rxr_cnt)) {
   2519      1.22    nonaka 		/* No RSS. */
   2520      1.22    nonaka 		*nsubch = 0;
   2521      1.22    nonaka 		return 0;
   2522      1.22    nonaka 	}
   2523      1.22    nonaka 
   2524      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "RX rings offered %u, requested %d\n",
   2525      1.22    nonaka 	    rxr_cnt, nchan);
   2526      1.22    nonaka 
   2527      1.22    nonaka 	if (nchan > rxr_cnt)
   2528      1.22    nonaka 		nchan = rxr_cnt;
   2529      1.22    nonaka 	if (nchan == 1) {
   2530      1.22    nonaka 		aprint_debug_dev(sc->sc_dev,
   2531      1.22    nonaka 		    "only 1 channel is supported, no vRSS\n");
   2532      1.22    nonaka 		*nsubch = 0;
   2533      1.22    nonaka 		return 0;
   2534      1.22    nonaka 	}
   2535      1.22    nonaka 
   2536      1.22    nonaka 	*nsubch = nchan - 1;
   2537      1.22    nonaka 	error = hvn_nvs_alloc_subchannels(sc, nsubch);
   2538      1.22    nonaka 	if (error || *nsubch == 0) {
   2539      1.22    nonaka 		/* Failed to allocate sub-channels. */
   2540      1.22    nonaka 		*nsubch = 0;
   2541      1.22    nonaka 		return 0;
   2542      1.22    nonaka 	}
   2543      1.22    nonaka 
   2544      1.22    nonaka 	/*
   2545      1.22    nonaka 	 * Wait for all sub-channels to become ready before moving on.
   2546      1.22    nonaka 	 */
   2547      1.22    nonaka 	subchans = vmbus_subchannel_get(sc->sc_prichan, *nsubch);
   2548      1.22    nonaka 	vmbus_subchannel_rel(subchans, *nsubch);
   2549      1.22    nonaka 	return 0;
   2550      1.22    nonaka }
   2551      1.22    nonaka 
   2552      1.22    nonaka static int
   2553      1.22    nonaka hvn_synth_attachable(const struct hvn_softc *sc)
   2554      1.22    nonaka {
   2555      1.22    nonaka #if 0
   2556      1.22    nonaka 	const struct hvn_rx_ring *rxr;
   2557      1.22    nonaka 	int i;
   2558      1.22    nonaka 
   2559      1.22    nonaka 	for (i = 0; i < sc->sc_nrxr; i++) {
   2560      1.22    nonaka 		rxr = &sc->sc_rxr[i];
   2561      1.22    nonaka 		if (rxr->rxr_flags)
   2562      1.22    nonaka 			return 0;
   2563      1.22    nonaka 	}
   2564      1.22    nonaka #endif
   2565      1.22    nonaka 	return 1;
   2566      1.22    nonaka }
   2567      1.22    nonaka 
   2568      1.22    nonaka /*
   2569      1.22    nonaka  * Make sure that the RX filter is zero after the successful
   2570      1.22    nonaka  * RNDIS initialization.
   2571      1.22    nonaka  *
   2572      1.22    nonaka  * NOTE:
   2573      1.22    nonaka  * Under certain conditions on certain versions of Hyper-V,
   2574      1.22    nonaka  * the RNDIS rxfilter is _not_ zero on the hypervisor side
   2575      1.22    nonaka  * after the successful RNDIS initialization, which breaks
   2576      1.22    nonaka  * the assumption of any following code (well, it breaks the
   2577      1.22    nonaka  * RNDIS API contract actually).  Clear the RNDIS rxfilter
   2578      1.22    nonaka  * explicitly, drain packets sneaking through, and drain the
   2579      1.22    nonaka  * interrupt taskqueues scheduled due to the stealth packets.
   2580      1.22    nonaka  */
   2581      1.22    nonaka static void
   2582      1.22    nonaka hvn_init_fixat(struct hvn_softc *sc, int nchan)
   2583      1.22    nonaka {
   2584      1.22    nonaka 
   2585      1.22    nonaka 	hvn_disable_rx(sc);
   2586      1.22    nonaka 	hvn_drain_rxtx(sc, nchan);
   2587      1.22    nonaka }
   2588      1.22    nonaka 
   2589      1.22    nonaka static void
   2590      1.22    nonaka hvn_set_txagg(struct hvn_softc *sc)
   2591      1.22    nonaka {
   2592      1.22    nonaka 	struct hvn_tx_ring *txr;
   2593      1.22    nonaka 	uint32_t size, pkts;
   2594      1.22    nonaka 	int i;
   2595      1.22    nonaka 
   2596      1.22    nonaka 	/*
   2597      1.22    nonaka 	 * Setup aggregation size.
   2598      1.22    nonaka 	 */
   2599      1.22    nonaka 	if (sc->sc_agg_size < 0)
   2600      1.22    nonaka 		size = UINT32_MAX;
   2601      1.22    nonaka 	else
   2602      1.22    nonaka 		size = sc->sc_agg_size;
   2603      1.22    nonaka 
   2604      1.22    nonaka 	if (size > sc->sc_rndis_agg_size)
   2605      1.22    nonaka 		size = sc->sc_rndis_agg_size;
   2606      1.22    nonaka 
   2607      1.22    nonaka 	/* NOTE: We only aggregate packets using chimney sending buffers. */
   2608      1.22    nonaka 	if (size > (uint32_t)sc->sc_chim_szmax)
   2609      1.22    nonaka 		size = sc->sc_chim_szmax;
   2610      1.22    nonaka 
   2611      1.22    nonaka 	if (size <= 2 * HVN_PKTSIZE_MIN(sc->sc_rndis_agg_align)) {
   2612      1.22    nonaka 		/* Disable */
   2613      1.22    nonaka 		size = 0;
   2614      1.22    nonaka 		pkts = 0;
   2615      1.22    nonaka 		goto done;
   2616      1.22    nonaka 	}
   2617      1.22    nonaka 
   2618      1.22    nonaka 	/* NOTE: Type of the per TX ring setting is 'int'. */
   2619      1.22    nonaka 	if (size > INT_MAX)
   2620      1.22    nonaka 		size = INT_MAX;
   2621      1.22    nonaka 
   2622      1.22    nonaka 	/*
   2623      1.22    nonaka 	 * Setup aggregation packet count.
   2624      1.22    nonaka 	 */
   2625      1.22    nonaka 	if (sc->sc_agg_pkts < 0)
   2626      1.22    nonaka 		pkts = UINT32_MAX;
   2627      1.22    nonaka 	else
   2628      1.22    nonaka 		pkts = sc->sc_agg_pkts;
   2629      1.22    nonaka 
   2630      1.22    nonaka 	if (pkts > sc->sc_rndis_agg_pkts)
   2631      1.22    nonaka 		pkts = sc->sc_rndis_agg_pkts;
   2632      1.22    nonaka 
   2633      1.22    nonaka 	if (pkts <= 1) {
   2634      1.22    nonaka 		/* Disable */
   2635      1.22    nonaka 		size = 0;
   2636      1.22    nonaka 		pkts = 0;
   2637      1.22    nonaka 		goto done;
   2638      1.22    nonaka 	}
   2639      1.22    nonaka 
   2640      1.22    nonaka 	/* NOTE: Type of the per TX ring setting is 'short'. */
   2641      1.22    nonaka 	if (pkts > SHRT_MAX)
   2642      1.22    nonaka 		pkts = SHRT_MAX;
   2643      1.22    nonaka 
   2644      1.22    nonaka done:
   2645      1.22    nonaka 	/* NOTE: Type of the per TX ring setting is 'short'. */
   2646      1.22    nonaka 	if (sc->sc_rndis_agg_align > SHRT_MAX) {
   2647      1.22    nonaka 		/* Disable */
   2648      1.22    nonaka 		size = 0;
   2649      1.22    nonaka 		pkts = 0;
   2650      1.22    nonaka 	}
   2651      1.22    nonaka 
   2652      1.22    nonaka 	aprint_verbose_dev(sc->sc_dev,
   2653      1.22    nonaka 	    "TX aggregate size %u, pkts %u, align %u\n",
   2654      1.22    nonaka 	    size, pkts, sc->sc_rndis_agg_align);
   2655      1.22    nonaka 
   2656      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr_inuse; ++i) {
   2657      1.22    nonaka 		txr = &sc->sc_txr[i];
   2658      1.22    nonaka 
   2659      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   2660      1.22    nonaka 		txr->txr_agg_szmax = size;
   2661      1.22    nonaka 		txr->txr_agg_pktmax = pkts;
   2662      1.22    nonaka 		txr->txr_agg_align = sc->sc_rndis_agg_align;
   2663      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   2664      1.22    nonaka 	}
   2665      1.22    nonaka }
   2666      1.22    nonaka 
   2667      1.22    nonaka static int
   2668      1.22    nonaka hvn_synth_attach(struct hvn_softc *sc, int mtu)
   2669      1.22    nonaka {
   2670      1.22    nonaka 	uint8_t rss_key[RSS_KEYSIZE];
   2671      1.22    nonaka 	uint32_t old_caps;
   2672      1.22    nonaka 	int nchan = 1, nsubch;
   2673      1.22    nonaka 	int i, error;
   2674      1.22    nonaka 
   2675      1.22    nonaka 	if (!hvn_synth_attachable(sc))
   2676      1.22    nonaka 		return ENXIO;
   2677      1.22    nonaka 
   2678      1.22    nonaka 	/* Save capabilities for later verification. */
   2679      1.22    nonaka 	old_caps = sc->sc_caps;
   2680      1.22    nonaka 	sc->sc_caps = 0;
   2681      1.22    nonaka 
   2682      1.22    nonaka 	/* Clear RSS stuffs. */
   2683      1.22    nonaka 	sc->sc_rss_ind_size = 0;
   2684      1.22    nonaka 	sc->sc_rss_hash = 0;
   2685      1.22    nonaka 	sc->sc_rss_hcap = 0;
   2686      1.22    nonaka 
   2687      1.22    nonaka 	/*
   2688      1.22    nonaka 	 * Attach the primary channel _before_ attaching NVS and RNDIS.
   2689      1.22    nonaka 	 */
   2690      1.22    nonaka 	error = hvn_channel_attach(sc, sc->sc_prichan);
   2691      1.22    nonaka 	if (error) {
   2692      1.22    nonaka 		aprint_error_dev(sc->sc_dev,
   2693      1.22    nonaka 		    "failed to attach primary channel\n");
   2694      1.22    nonaka 		goto failed;
   2695      1.22    nonaka 	}
   2696      1.22    nonaka 
   2697      1.22    nonaka 	/*
   2698      1.22    nonaka 	 * Attach NVS.
   2699      1.22    nonaka 	 */
   2700      1.22    nonaka 	error = hvn_nvs_attach(sc, mtu);
   2701      1.22    nonaka 	if (error) {
   2702      1.22    nonaka 		aprint_error_dev(sc->sc_dev, "failed to init NVSP\n");
   2703      1.22    nonaka 		goto detach_channel;
   2704      1.22    nonaka 	}
   2705      1.22    nonaka 
   2706      1.22    nonaka 	/*
   2707      1.22    nonaka 	 * Attach RNDIS _after_ NVS is attached.
   2708      1.22    nonaka 	 */
   2709      1.22    nonaka 	error = hvn_rndis_attach(sc, mtu);
   2710      1.22    nonaka 	if (error) {
   2711      1.22    nonaka 		aprint_error_dev(sc->sc_dev, "failed to init RNDIS\n");
   2712      1.22    nonaka 		goto detach_nvs;
   2713      1.22    nonaka 	}
   2714      1.22    nonaka 
   2715      1.22    nonaka 	error = hvn_set_capabilities(sc, mtu);
   2716      1.22    nonaka 	if (error) {
   2717      1.22    nonaka 		aprint_error_dev(sc->sc_dev, "failed to setup offloading\n");
   2718      1.22    nonaka 		goto detach_rndis;
   2719      1.22    nonaka 	}
   2720      1.22    nonaka 
   2721      1.22    nonaka 	if ((sc->sc_flags & HVN_SCF_ATTACHED) && old_caps != sc->sc_caps) {
   2722      1.22    nonaka 		device_printf(sc->sc_dev, "caps mismatch "
   2723      1.22    nonaka 		    "old 0x%08x, new 0x%08x\n", old_caps, sc->sc_caps);
   2724      1.22    nonaka 		error = ENXIO;
   2725      1.22    nonaka 		goto detach_rndis;
   2726      1.22    nonaka 	}
   2727      1.22    nonaka 
   2728      1.22    nonaka 	/*
   2729      1.22    nonaka 	 * Allocate sub-channels for multi-TX/RX rings.
   2730      1.22    nonaka 	 *
   2731      1.22    nonaka 	 * NOTE:
   2732      1.22    nonaka 	 * The # of RX rings that can be used is equivalent to the # of
   2733      1.22    nonaka 	 * channels to be requested.
   2734      1.22    nonaka 	 */
   2735      1.22    nonaka 	nsubch = sc->sc_nrxr - 1;
   2736      1.22    nonaka 	error = hvn_synth_alloc_subchannels(sc, &nsubch);
   2737      1.22    nonaka 	if (error) {
   2738      1.22    nonaka 		aprint_error_dev(sc->sc_dev,
   2739      1.22    nonaka 		    "failed to allocate sub channels\n");
   2740      1.22    nonaka 		goto detach_synth;
   2741      1.22    nonaka 	}
   2742      1.22    nonaka 
   2743      1.22    nonaka 	/*
   2744      1.22    nonaka 	 * Set the # of TX/RX rings that could be used according to
   2745      1.22    nonaka 	 * the # of channels that NVS offered.
   2746      1.22    nonaka 	 */
   2747      1.22    nonaka 	nchan = nsubch + 1;
   2748      1.22    nonaka 	hvn_set_ring_inuse(sc, nchan);
   2749      1.22    nonaka 
   2750      1.22    nonaka 	if (nchan > 1) {
   2751      1.22    nonaka 		/*
   2752      1.22    nonaka 		 * Attach the sub-channels.
   2753      1.22    nonaka 		 *
   2754      1.22    nonaka 		 * NOTE: hvn_set_ring_inuse() _must_ have been called.
   2755      1.22    nonaka 		 */
   2756      1.22    nonaka 		error = hvn_subchannel_attach(sc);
   2757      1.22    nonaka 		if (error) {
   2758      1.22    nonaka 			aprint_error_dev(sc->sc_dev,
   2759      1.22    nonaka 			    "failed to attach sub channels\n");
   2760      1.22    nonaka 			goto detach_synth;
   2761      1.22    nonaka 		}
   2762      1.22    nonaka 
   2763      1.22    nonaka 		/*
   2764      1.22    nonaka 		 * Configure RSS key and indirect table _after_ all sub-channels
   2765      1.22    nonaka 		 * are attached.
   2766      1.22    nonaka 		 */
   2767      1.22    nonaka 		if (!(sc->sc_flags & HVN_SCF_HAS_RSSKEY)) {
   2768      1.22    nonaka 			/* Set the default RSS key. */
   2769      1.22    nonaka 			CTASSERT(sizeof(sc->sc_rss.rss_key) == sizeof(rss_key));
   2770      1.22    nonaka 			rss_getkey(rss_key);
   2771      1.22    nonaka 			memcpy(&sc->sc_rss.rss_key, rss_key,
   2772      1.22    nonaka 			    sizeof(sc->sc_rss.rss_key));
   2773      1.22    nonaka 			sc->sc_flags |= HVN_SCF_HAS_RSSKEY;
   2774      1.22    nonaka 		}
   2775      1.22    nonaka 
   2776      1.22    nonaka 		if (!(sc->sc_flags & HVN_SCF_HAS_RSSIND)) {
   2777      1.22    nonaka 			/* Setup RSS indirect table in round-robin fashion. */
   2778      1.22    nonaka 			for (i = 0; i < NDIS_HASH_INDCNT; i++) {
   2779      1.22    nonaka 				sc->sc_rss.rss_ind[i] = i % nchan;
   2780      1.22    nonaka 			}
   2781      1.22    nonaka 			sc->sc_flags |= HVN_SCF_HAS_RSSIND;
   2782      1.22    nonaka 		} else {
   2783      1.22    nonaka 			/*
   2784      1.22    nonaka 			 * # of usable channels may be changed, so we have to
   2785      1.22    nonaka 			 * make sure that all entries in RSS indirect table
   2786      1.22    nonaka 			 * are valid.
   2787      1.22    nonaka 			 *
   2788      1.22    nonaka 			 * NOTE: hvn_set_ring_inuse() _must_ have been called.
   2789      1.22    nonaka 			 */
   2790      1.22    nonaka 			hvn_fixup_rss_ind(sc);
   2791      1.22    nonaka 		}
   2792      1.22    nonaka 
   2793      1.22    nonaka 		sc->sc_rss_hash = sc->sc_rss_hcap;
   2794      1.22    nonaka 		error = hvn_set_rss(sc, NDIS_RSS_FLAG_NONE);
   2795      1.22    nonaka 		if (error) {
   2796      1.22    nonaka 			aprint_error_dev(sc->sc_dev, "failed to setup RSS\n");
   2797      1.22    nonaka 			goto detach_synth;
   2798      1.22    nonaka 		}
   2799      1.22    nonaka 	}
   2800      1.22    nonaka 
   2801      1.22    nonaka 	/*
   2802      1.22    nonaka 	 * Fixup transmission aggregation setup.
   2803      1.22    nonaka 	 */
   2804      1.22    nonaka 	hvn_set_txagg(sc);
   2805      1.22    nonaka 	hvn_init_fixat(sc, nchan);
   2806      1.22    nonaka 	return 0;
   2807      1.22    nonaka 
   2808      1.22    nonaka detach_synth:
   2809      1.22    nonaka 	hvn_init_fixat(sc, nchan);
   2810      1.22    nonaka 	hvn_synth_detach(sc);
   2811      1.22    nonaka 	return error;
   2812      1.22    nonaka 
   2813      1.22    nonaka detach_rndis:
   2814      1.22    nonaka 	hvn_init_fixat(sc, nchan);
   2815      1.22    nonaka 	hvn_rndis_detach(sc);
   2816      1.22    nonaka detach_nvs:
   2817      1.22    nonaka 	hvn_nvs_detach(sc);
   2818      1.22    nonaka detach_channel:
   2819      1.22    nonaka 	hvn_channel_detach(sc, sc->sc_prichan);
   2820      1.22    nonaka failed:
   2821      1.22    nonaka 	/* Restore old capabilities. */
   2822      1.22    nonaka 	sc->sc_caps = old_caps;
   2823      1.22    nonaka 	return error;
   2824      1.22    nonaka }
   2825      1.22    nonaka 
   2826      1.22    nonaka static void
   2827      1.22    nonaka hvn_synth_detach(struct hvn_softc *sc)
   2828      1.22    nonaka {
   2829      1.22    nonaka 
   2830      1.22    nonaka 	/* Detach the RNDIS first. */
   2831      1.22    nonaka 	hvn_rndis_detach(sc);
   2832      1.22    nonaka 
   2833      1.22    nonaka 	/* Detach NVS. */
   2834      1.22    nonaka 	hvn_nvs_detach(sc);
   2835      1.22    nonaka 
   2836      1.22    nonaka 	/* Detach all of the channels. */
   2837      1.22    nonaka 	hvn_channel_detach_all(sc);
   2838      1.22    nonaka 
   2839      1.22    nonaka 	if (sc->sc_prichan->ch_sc->sc_proto >= VMBUS_VERSION_WIN10 &&
   2840      1.22    nonaka 	    sc->sc_rx_hndl) {
   2841      1.22    nonaka 		/*
   2842      1.22    nonaka 		 * Host is post-Win2016, disconnect RXBUF from primary channel
   2843      1.22    nonaka 		 * here.
   2844      1.22    nonaka 		 */
   2845      1.22    nonaka 		vmbus_handle_free(sc->sc_prichan, sc->sc_rx_hndl);
   2846      1.22    nonaka 		sc->sc_rx_hndl = 0;
   2847      1.22    nonaka 	}
   2848      1.22    nonaka 
   2849      1.22    nonaka 	if (sc->sc_prichan->ch_sc->sc_proto >= VMBUS_VERSION_WIN10 &&
   2850      1.22    nonaka 	    sc->sc_chim_hndl) {
   2851      1.22    nonaka 		/*
   2852      1.22    nonaka 		 * Host is post-Win2016, disconnect chimney sending buffer
   2853      1.22    nonaka 		 * from primary channel here.
   2854      1.22    nonaka 		 */
   2855      1.22    nonaka 		vmbus_handle_free(sc->sc_prichan, sc->sc_chim_hndl);
   2856      1.22    nonaka 		sc->sc_chim_hndl = 0;
   2857      1.22    nonaka 	}
   2858      1.22    nonaka }
   2859      1.22    nonaka 
   2860      1.22    nonaka static void
   2861      1.22    nonaka hvn_set_ring_inuse(struct hvn_softc *sc, int ring_cnt)
   2862      1.22    nonaka {
   2863      1.22    nonaka 
   2864      1.22    nonaka 	if (sc->sc_ntxr > ring_cnt)
   2865      1.22    nonaka 		sc->sc_ntxr_inuse = ring_cnt;
   2866      1.22    nonaka 	else
   2867      1.22    nonaka 		sc->sc_ntxr_inuse = sc->sc_ntxr;
   2868      1.22    nonaka 	sc->sc_nrxr_inuse = ring_cnt;
   2869      1.22    nonaka }
   2870      1.22    nonaka 
   2871      1.22    nonaka static void
   2872      1.22    nonaka hvn_channel_drain(struct hvn_softc *sc, struct vmbus_channel *chan)
   2873      1.22    nonaka {
   2874      1.22    nonaka 	struct hvn_rx_ring *rxr;
   2875      1.22    nonaka 	int i, s;
   2876      1.22    nonaka 
   2877      1.22    nonaka 	for (rxr = NULL, i = 0; i < sc->sc_nrxr_inuse; i++) {
   2878      1.22    nonaka 		rxr = &sc->sc_rxr[i];
   2879      1.22    nonaka 		if (rxr->rxr_chan == chan)
   2880      1.22    nonaka 			break;
   2881      1.22    nonaka 	}
   2882      1.22    nonaka 	KASSERT(i < sc->sc_nrxr_inuse);
   2883      1.22    nonaka 
   2884      1.22    nonaka 	/*
   2885      1.22    nonaka 	 * NOTE:
   2886      1.22    nonaka 	 * The TX bufring will not be drained by the hypervisor,
   2887      1.22    nonaka 	 * if the primary channel is revoked.
   2888      1.22    nonaka 	 */
   2889      1.22    nonaka 	while (!vmbus_channel_rx_empty(chan) ||
   2890      1.22    nonaka 	    (!vmbus_channel_is_revoked(sc->sc_prichan) &&
   2891      1.22    nonaka 	     !vmbus_channel_tx_empty(chan))) {
   2892      1.22    nonaka 		DELAY(20);
   2893      1.22    nonaka 		s = splnet();
   2894      1.22    nonaka 		hvn_nvs_intr1(rxr, sc->sc_tx_process_limit,
   2895      1.22    nonaka 		    sc->sc_rx_process_limit);
   2896      1.22    nonaka 		splx(s);
   2897      1.22    nonaka 	}
   2898      1.22    nonaka 
   2899      1.22    nonaka 	mutex_enter(&rxr->rxr_onwork_lock);
   2900      1.22    nonaka 	while (rxr->rxr_onlist || rxr->rxr_onproc)
   2901      1.22    nonaka 		cv_wait(&rxr->rxr_onwork_cv, &rxr->rxr_onwork_lock);
   2902      1.22    nonaka 	mutex_exit(&rxr->rxr_onwork_lock);
   2903      1.22    nonaka }
   2904      1.22    nonaka 
   2905      1.22    nonaka static void
   2906      1.22    nonaka hvn_disable_rx(struct hvn_softc *sc)
   2907      1.22    nonaka {
   2908      1.22    nonaka 
   2909      1.22    nonaka 	/*
   2910      1.22    nonaka 	 * Disable RX by clearing RX filter forcefully.
   2911      1.22    nonaka 	 */
   2912      1.22    nonaka 	(void)hvn_rndis_close(sc);	/* ignore error */
   2913      1.22    nonaka 
   2914      1.22    nonaka 	/*
   2915      1.22    nonaka 	 * Give RNDIS enough time to flush all pending data packets.
   2916      1.22    nonaka 	 */
   2917      1.22    nonaka 	DELAY(200);
   2918      1.22    nonaka }
   2919      1.22    nonaka 
   2920      1.22    nonaka static void
   2921      1.22    nonaka hvn_drain_rxtx(struct hvn_softc *sc, int nchan)
   2922      1.22    nonaka {
   2923      1.22    nonaka 	struct vmbus_channel **subchans = NULL;
   2924      1.22    nonaka 	int i, nsubch;
   2925      1.22    nonaka 
   2926      1.22    nonaka 	/*
   2927      1.22    nonaka 	 * Drain RX/TX bufrings and interrupts.
   2928      1.22    nonaka 	 */
   2929      1.22    nonaka 	nsubch = nchan - 1;
   2930      1.22    nonaka 	if (nsubch > 0)
   2931      1.22    nonaka 		subchans = vmbus_subchannel_get(sc->sc_prichan, nsubch);
   2932      1.22    nonaka 
   2933      1.22    nonaka 	if (subchans != NULL) {
   2934      1.22    nonaka 		for (i = 0; i < nsubch; ++i)
   2935      1.22    nonaka 			hvn_channel_drain(sc, subchans[i]);
   2936      1.22    nonaka 	}
   2937      1.22    nonaka 	hvn_channel_drain(sc, sc->sc_prichan);
   2938      1.22    nonaka 
   2939      1.22    nonaka 	if (subchans != NULL)
   2940      1.22    nonaka 		vmbus_subchannel_rel(subchans, nsubch);
   2941      1.22    nonaka }
   2942      1.22    nonaka 
   2943      1.22    nonaka static void
   2944      1.22    nonaka hvn_suspend_data(struct hvn_softc *sc)
   2945      1.22    nonaka {
   2946      1.22    nonaka 	struct hvn_tx_ring *txr;
   2947      1.22    nonaka 	int i, s;
   2948      1.22    nonaka 
   2949      1.22    nonaka 	/*
   2950      1.22    nonaka 	 * Suspend TX.
   2951      1.22    nonaka 	 */
   2952      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr_inuse; i++) {
   2953      1.22    nonaka 		txr = &sc->sc_txr[i];
   2954      1.22    nonaka 
   2955      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   2956      1.22    nonaka 		txr->txr_suspended = 1;
   2957      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   2958      1.22    nonaka 		/* No one is able send more packets now. */
   2959      1.22    nonaka 
   2960      1.22    nonaka 		/*
   2961      1.22    nonaka 		 * Wait for all pending sends to finish.
   2962      1.22    nonaka 		 *
   2963      1.22    nonaka 		 * NOTE:
   2964      1.22    nonaka 		 * We will _not_ receive all pending send-done, if the
   2965      1.22    nonaka 		 * primary channel is revoked.
   2966      1.22    nonaka 		 */
   2967      1.22    nonaka 		while (hvn_tx_ring_pending(txr) &&
   2968      1.22    nonaka 		    !vmbus_channel_is_revoked(sc->sc_prichan)) {
   2969      1.22    nonaka 			DELAY(20);
   2970      1.22    nonaka 			s = splnet();
   2971      1.22    nonaka 			hvn_nvs_intr1(txr->txr_rxr, sc->sc_tx_process_limit,
   2972      1.22    nonaka 			    sc->sc_rx_process_limit);
   2973      1.22    nonaka 			splx(s);
   2974      1.22    nonaka 		}
   2975      1.22    nonaka 	}
   2976      1.22    nonaka 
   2977      1.22    nonaka 	/*
   2978      1.22    nonaka 	 * Disable RX.
   2979      1.22    nonaka 	 */
   2980      1.22    nonaka 	hvn_disable_rx(sc);
   2981      1.22    nonaka 
   2982      1.22    nonaka 	/*
   2983      1.22    nonaka 	 * Drain RX/TX.
   2984      1.22    nonaka 	 */
   2985      1.22    nonaka 	hvn_drain_rxtx(sc, sc->sc_nrxr_inuse);
   2986      1.22    nonaka }
   2987      1.22    nonaka 
   2988      1.22    nonaka static void
   2989      1.22    nonaka hvn_suspend_mgmt(struct hvn_softc *sc)
   2990      1.22    nonaka {
   2991      1.22    nonaka 
   2992      1.22    nonaka 	sc->sc_link_suspend = true;
   2993      1.22    nonaka 	callout_halt(&sc->sc_link_tmout, NULL);
   2994      1.22    nonaka 
   2995      1.22    nonaka 	/* Drain link state task */
   2996      1.22    nonaka 	mutex_enter(&sc->sc_link_lock);
   2997      1.22    nonaka 	for (;;) {
   2998      1.22    nonaka 		if (!sc->sc_link_onproc)
   2999      1.22    nonaka 			break;
   3000      1.22    nonaka 		mutex_exit(&sc->sc_link_lock);
   3001      1.22    nonaka 		DELAY(20);
   3002      1.22    nonaka 		mutex_enter(&sc->sc_link_lock);
   3003      1.22    nonaka 	}
   3004      1.22    nonaka 	mutex_exit(&sc->sc_link_lock);
   3005      1.22    nonaka }
   3006      1.22    nonaka 
   3007      1.22    nonaka static void
   3008      1.22    nonaka hvn_suspend(struct hvn_softc *sc)
   3009      1.22    nonaka {
   3010      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   3011      1.22    nonaka 
   3012      1.22    nonaka 	if (ifp->if_flags & IFF_RUNNING)
   3013      1.22    nonaka 		hvn_suspend_data(sc);
   3014      1.22    nonaka 	hvn_suspend_mgmt(sc);
   3015      1.22    nonaka }
   3016      1.22    nonaka 
   3017      1.22    nonaka static void
   3018      1.22    nonaka hvn_resume_tx(struct hvn_softc *sc, int ring_cnt)
   3019      1.22    nonaka {
   3020      1.22    nonaka 	struct hvn_tx_ring *txr;
   3021      1.22    nonaka 	int i;
   3022      1.22    nonaka 
   3023      1.22    nonaka 	for (i = 0; i < ring_cnt; i++) {
   3024      1.22    nonaka 		txr = &sc->sc_txr[i];
   3025      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   3026      1.22    nonaka 		txr->txr_suspended = 0;
   3027      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   3028      1.22    nonaka 	}
   3029      1.22    nonaka }
   3030      1.22    nonaka 
   3031      1.22    nonaka static void
   3032      1.22    nonaka hvn_resume_data(struct hvn_softc *sc)
   3033      1.22    nonaka {
   3034      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   3035      1.22    nonaka 	struct hvn_tx_ring *txr;
   3036      1.22    nonaka 	int i;
   3037      1.22    nonaka 
   3038      1.22    nonaka 	/*
   3039      1.22    nonaka 	 * Re-enable RX.
   3040      1.22    nonaka 	 */
   3041      1.22    nonaka 	hvn_rndis_open(sc);
   3042      1.22    nonaka 
   3043      1.22    nonaka 	/*
   3044      1.22    nonaka 	 * Make sure to clear suspend status on "all" TX rings,
   3045      1.22    nonaka 	 * since sc_ntxr_inuse can be changed after hvn_suspend_data().
   3046      1.22    nonaka 	 */
   3047      1.22    nonaka 	hvn_resume_tx(sc, sc->sc_ntxr);
   3048      1.22    nonaka 
   3049      1.22    nonaka 	/*
   3050      1.22    nonaka 	 * Flush unused mbuf, since sc_ntxr_inuse may be reduced.
   3051      1.22    nonaka 	 */
   3052      1.22    nonaka 	for (i = sc->sc_ntxr_inuse; i < sc->sc_ntxr; i++)
   3053      1.22    nonaka 		hvn_tx_ring_qflush(sc, &sc->sc_txr[i]);
   3054      1.22    nonaka 
   3055      1.22    nonaka 	/*
   3056      1.22    nonaka 	 * Kick start TX.
   3057      1.22    nonaka 	 */
   3058      1.22    nonaka 	for (i = 0; i < sc->sc_ntxr_inuse; i++) {
   3059      1.22    nonaka 		txr = &sc->sc_txr[i];
   3060      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   3061      1.22    nonaka 		txr->txr_oactive = 0;
   3062      1.22    nonaka 
   3063      1.22    nonaka 		/* ALTQ */
   3064      1.22    nonaka 		if (txr->txr_id == 0)
   3065      1.22    nonaka 			if_schedule_deferred_start(ifp);
   3066      1.22    nonaka 		softint_schedule(txr->txr_si);
   3067      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   3068      1.22    nonaka 	}
   3069      1.22    nonaka }
   3070      1.22    nonaka 
   3071      1.22    nonaka static void
   3072      1.22    nonaka hvn_resume_mgmt(struct hvn_softc *sc)
   3073      1.22    nonaka {
   3074      1.22    nonaka 
   3075      1.22    nonaka 	sc->sc_link_suspend = false;
   3076      1.22    nonaka 	hvn_link_event(sc, HVN_LINK_EV_RESUME_NETWORK);
   3077      1.22    nonaka }
   3078      1.22    nonaka 
   3079      1.22    nonaka static void
   3080      1.22    nonaka hvn_resume(struct hvn_softc *sc)
   3081      1.22    nonaka {
   3082      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   3083      1.22    nonaka 
   3084      1.22    nonaka 	if (ifp->if_flags & IFF_RUNNING)
   3085      1.22    nonaka 		hvn_resume_data(sc);
   3086      1.22    nonaka 	hvn_resume_mgmt(sc);
   3087      1.22    nonaka }
   3088      1.22    nonaka 
   3089      1.22    nonaka static int
   3090      1.22    nonaka hvn_nvs_init(struct hvn_softc *sc)
   3091      1.22    nonaka {
   3092      1.22    nonaka 
   3093      1.22    nonaka 	mutex_init(&sc->sc_nvsrsp_lock, MUTEX_DEFAULT, IPL_NET);
   3094      1.22    nonaka 	cv_init(&sc->sc_nvsrsp_cv, "nvsrspcv");
   3095      1.22    nonaka 
   3096      1.22    nonaka 	return 0;
   3097      1.22    nonaka }
   3098      1.22    nonaka 
   3099      1.22    nonaka static void
   3100      1.22    nonaka hvn_nvs_destroy(struct hvn_softc *sc)
   3101      1.22    nonaka {
   3102      1.22    nonaka 
   3103      1.22    nonaka 	mutex_destroy(&sc->sc_nvsrsp_lock);
   3104      1.22    nonaka 	cv_destroy(&sc->sc_nvsrsp_cv);
   3105      1.22    nonaka }
   3106      1.22    nonaka 
   3107      1.22    nonaka static int
   3108      1.22    nonaka hvn_nvs_doinit(struct hvn_softc *sc, uint32_t proto)
   3109      1.22    nonaka {
   3110      1.22    nonaka 	struct hvn_nvs_init cmd;
   3111      1.22    nonaka 	struct hvn_nvs_init_resp *rsp;
   3112      1.22    nonaka 	uint64_t tid;
   3113      1.22    nonaka 	int error;
   3114      1.22    nonaka 
   3115      1.22    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3116      1.22    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_INIT;
   3117      1.22    nonaka 	cmd.nvs_ver_min = cmd.nvs_ver_max = proto;
   3118      1.22    nonaka 
   3119      1.22    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3120      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3121      1.22    nonaka 	error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0);
   3122      1.22    nonaka 	if (error == 0) {
   3123      1.22    nonaka 		rsp = (struct hvn_nvs_init_resp *)&sc->sc_nvsrsp;
   3124      1.22    nonaka 		if (rsp->nvs_status != HVN_NVS_STATUS_OK)
   3125      1.22    nonaka 			error = EINVAL;
   3126      1.22    nonaka 	}
   3127      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3128      1.22    nonaka 
   3129      1.22    nonaka 	return error;
   3130      1.22    nonaka }
   3131      1.22    nonaka 
   3132      1.22    nonaka static int
   3133      1.22    nonaka hvn_nvs_conf_ndis(struct hvn_softc *sc, int mtu)
   3134      1.22    nonaka {
   3135      1.22    nonaka 	struct hvn_nvs_ndis_conf cmd;
   3136      1.22    nonaka 	uint64_t tid;
   3137      1.22    nonaka 	int error;
   3138      1.22    nonaka 
   3139      1.22    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3140      1.22    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_NDIS_CONF;
   3141      1.22    nonaka 	cmd.nvs_mtu = mtu + ETHER_HDR_LEN;
   3142      1.22    nonaka 	cmd.nvs_caps = HVN_NVS_NDIS_CONF_VLAN;
   3143      1.22    nonaka 
   3144      1.22    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3145      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3146      1.22    nonaka 	/* NOTE: No response. */
   3147      1.22    nonaka 	error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0);
   3148      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3149      1.22    nonaka 
   3150      1.22    nonaka 	if (error == 0)
   3151      1.22    nonaka 		sc->sc_caps |= HVN_CAPS_MTU | HVN_CAPS_VLAN;
   3152      1.22    nonaka 	return error;
   3153      1.22    nonaka }
   3154      1.22    nonaka 
   3155      1.22    nonaka static int
   3156      1.22    nonaka hvn_nvs_init_ndis(struct hvn_softc *sc)
   3157      1.22    nonaka {
   3158      1.22    nonaka 	struct hvn_nvs_ndis_init cmd;
   3159      1.22    nonaka 	uint64_t tid;
   3160      1.22    nonaka 	int error;
   3161      1.22    nonaka 
   3162      1.22    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3163      1.22    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_NDIS_INIT;
   3164      1.22    nonaka 	cmd.nvs_ndis_major = (sc->sc_ndisver & 0xffff0000) >> 16;
   3165      1.22    nonaka 	cmd.nvs_ndis_minor = sc->sc_ndisver & 0x0000ffff;
   3166      1.22    nonaka 
   3167      1.22    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3168      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3169      1.22    nonaka 	/* NOTE: No response. */
   3170      1.22    nonaka 	error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0);
   3171      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3172      1.22    nonaka 
   3173      1.22    nonaka 	return error;
   3174      1.22    nonaka }
   3175      1.22    nonaka 
   3176      1.22    nonaka static int
   3177      1.22    nonaka hvn_nvs_attach(struct hvn_softc *sc, int mtu)
   3178      1.22    nonaka {
   3179      1.22    nonaka 	static const uint32_t protos[] = {
   3180      1.22    nonaka 		HVN_NVS_PROTO_VERSION_5,
   3181      1.22    nonaka 		HVN_NVS_PROTO_VERSION_4,
   3182      1.22    nonaka 		HVN_NVS_PROTO_VERSION_2,
   3183      1.22    nonaka 		HVN_NVS_PROTO_VERSION_1
   3184      1.22    nonaka 	};
   3185      1.22    nonaka 	int i;
   3186      1.22    nonaka 
   3187      1.22    nonaka 	if (hyperv_ver_major >= 10)
   3188      1.22    nonaka 		sc->sc_caps |= HVN_CAPS_UDPHASH;
   3189      1.22    nonaka 
   3190      1.22    nonaka 	/*
   3191      1.22    nonaka 	 * Initialize NVS.
   3192      1.22    nonaka 	 */
   3193      1.22    nonaka 	if (sc->sc_flags & HVN_SCF_ATTACHED) {
   3194      1.22    nonaka 		/*
   3195      1.22    nonaka 		 * NVS version and NDIS version MUST NOT be changed.
   3196      1.22    nonaka 		 */
   3197      1.22    nonaka 		DPRINTF("%s: reinit NVS version %#x, NDIS version %u.%u\n",
   3198      1.22    nonaka 		    device_xname(sc->sc_dev), sc->sc_proto,
   3199      1.22    nonaka 		    (sc->sc_ndisver >> 16), sc->sc_ndisver & 0xffff);
   3200      1.22    nonaka 
   3201      1.22    nonaka 		if (hvn_nvs_doinit(sc, sc->sc_proto)) {
   3202      1.22    nonaka 			DPRINTF("%s: failed to reinit NVSP version %#x\n",
   3203      1.22    nonaka 			    device_xname(sc->sc_dev), sc->sc_proto);
   3204      1.22    nonaka 			return -1;
   3205      1.22    nonaka 		}
   3206      1.22    nonaka 	} else {
   3207      1.22    nonaka 		/*
   3208      1.22    nonaka 		 * Find the supported NVS version and set NDIS version
   3209      1.22    nonaka 		 * accordingly.
   3210      1.22    nonaka 		 */
   3211      1.22    nonaka 		for (i = 0; i < __arraycount(protos); i++) {
   3212      1.22    nonaka 			if (hvn_nvs_doinit(sc, protos[i]) == 0)
   3213      1.22    nonaka 				break;
   3214      1.22    nonaka 		}
   3215      1.22    nonaka 		if (i == __arraycount(protos)) {
   3216      1.22    nonaka 			DPRINTF("%s: failed to negotiate NVSP version\n",
   3217      1.22    nonaka 			    device_xname(sc->sc_dev));
   3218      1.22    nonaka 			return -1;
   3219      1.22    nonaka 		}
   3220      1.22    nonaka 
   3221      1.22    nonaka 		sc->sc_proto = protos[i];
   3222      1.22    nonaka 		if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_4)
   3223      1.22    nonaka 			sc->sc_ndisver = NDIS_VERSION_6_1;
   3224      1.22    nonaka 		else
   3225      1.22    nonaka 			sc->sc_ndisver = NDIS_VERSION_6_30;
   3226       1.1    nonaka 
   3227      1.22    nonaka 		DPRINTF("%s: NVS version %#x, NDIS version %u.%u\n",
   3228      1.22    nonaka 		    device_xname(sc->sc_dev), sc->sc_proto,
   3229      1.22    nonaka 		    (sc->sc_ndisver >> 16), sc->sc_ndisver & 0xffff);
   3230       1.1    nonaka 	}
   3231       1.1    nonaka 
   3232      1.22    nonaka 	if (sc->sc_proto >= HVN_NVS_PROTO_VERSION_5)
   3233      1.22    nonaka 		sc->sc_caps |= HVN_CAPS_HASHVAL;
   3234       1.1    nonaka 
   3235      1.22    nonaka 	if (sc->sc_proto >= HVN_NVS_PROTO_VERSION_2) {
   3236      1.22    nonaka 		/*
   3237      1.22    nonaka 		 * Configure NDIS before initializing it.
   3238      1.22    nonaka 		 */
   3239      1.22    nonaka 		if (hvn_nvs_conf_ndis(sc, mtu))
   3240      1.22    nonaka 			return -1;
   3241       1.1    nonaka 	}
   3242       1.1    nonaka 
   3243      1.22    nonaka 	/*
   3244      1.22    nonaka 	 * Initialize NDIS.
   3245      1.22    nonaka 	 */
   3246      1.22    nonaka 	if (hvn_nvs_init_ndis(sc))
   3247      1.22    nonaka 		return -1;
   3248      1.22    nonaka 
   3249      1.22    nonaka 	/*
   3250      1.22    nonaka 	 * Connect RXBUF.
   3251      1.22    nonaka 	 */
   3252      1.22    nonaka 	if (hvn_nvs_connect_rxbuf(sc))
   3253      1.22    nonaka 		return -1;
   3254       1.1    nonaka 
   3255      1.22    nonaka 	/*
   3256      1.22    nonaka 	 * Connect chimney sending buffer.
   3257      1.22    nonaka 	 */
   3258      1.22    nonaka 	if (hvn_nvs_connect_chim(sc))
   3259      1.22    nonaka 		return -1;
   3260       1.1    nonaka 
   3261      1.22    nonaka 	return 0;
   3262       1.1    nonaka }
   3263       1.1    nonaka 
   3264       1.1    nonaka static int
   3265      1.22    nonaka hvn_nvs_connect_rxbuf(struct hvn_softc *sc)
   3266       1.1    nonaka {
   3267       1.1    nonaka 	struct hvn_nvs_rxbuf_conn cmd;
   3268       1.1    nonaka 	struct hvn_nvs_rxbuf_conn_resp *rsp;
   3269       1.1    nonaka 	uint64_t tid;
   3270       1.1    nonaka 
   3271      1.22    nonaka 	if (vmbus_handle_alloc(sc->sc_prichan, &sc->sc_rx_dma, sc->sc_rx_size,
   3272       1.1    nonaka 	    &sc->sc_rx_hndl)) {
   3273       1.1    nonaka 		DPRINTF("%s: failed to obtain a PA handle\n",
   3274       1.1    nonaka 		    device_xname(sc->sc_dev));
   3275      1.22    nonaka 		return -1;
   3276       1.1    nonaka 	}
   3277       1.1    nonaka 
   3278       1.1    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3279       1.1    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_RXBUF_CONN;
   3280       1.1    nonaka 	cmd.nvs_gpadl = sc->sc_rx_hndl;
   3281       1.1    nonaka 	cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
   3282       1.1    nonaka 
   3283       1.1    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3284      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3285      1.22    nonaka 	if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0))
   3286       1.1    nonaka 		goto errout;
   3287       1.1    nonaka 
   3288       1.1    nonaka 	rsp = (struct hvn_nvs_rxbuf_conn_resp *)&sc->sc_nvsrsp;
   3289       1.1    nonaka 	if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
   3290       1.1    nonaka 		DPRINTF("%s: failed to set up the Rx ring\n",
   3291       1.1    nonaka 		    device_xname(sc->sc_dev));
   3292       1.1    nonaka 		goto errout;
   3293       1.1    nonaka 	}
   3294      1.22    nonaka 
   3295      1.22    nonaka 	SET(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED);
   3296      1.22    nonaka 
   3297       1.1    nonaka 	if (rsp->nvs_nsect > 1) {
   3298       1.1    nonaka 		DPRINTF("%s: invalid number of Rx ring sections: %u\n",
   3299       1.1    nonaka 		    device_xname(sc->sc_dev), rsp->nvs_nsect);
   3300      1.22    nonaka 		goto errout;
   3301       1.1    nonaka 	}
   3302      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3303      1.22    nonaka 
   3304       1.1    nonaka 	return 0;
   3305       1.1    nonaka 
   3306       1.1    nonaka  errout:
   3307      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3308      1.22    nonaka 	hvn_nvs_disconnect_rxbuf(sc);
   3309       1.1    nonaka 	return -1;
   3310       1.1    nonaka }
   3311       1.1    nonaka 
   3312       1.1    nonaka static int
   3313      1.22    nonaka hvn_nvs_disconnect_rxbuf(struct hvn_softc *sc)
   3314       1.1    nonaka {
   3315       1.1    nonaka 	struct hvn_nvs_rxbuf_disconn cmd;
   3316       1.1    nonaka 	uint64_t tid;
   3317      1.22    nonaka 	int s, error;
   3318       1.1    nonaka 
   3319      1.22    nonaka 	if (ISSET(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED)) {
   3320      1.22    nonaka 		memset(&cmd, 0, sizeof(cmd));
   3321      1.22    nonaka 		cmd.nvs_type = HVN_NVS_TYPE_RXBUF_DISCONN;
   3322      1.22    nonaka 		cmd.nvs_sig = HVN_NVS_RXBUF_SIG;
   3323       1.1    nonaka 
   3324      1.22    nonaka 		tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3325      1.22    nonaka 		mutex_enter(&sc->sc_nvsrsp_lock);
   3326      1.22    nonaka 		error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid,
   3327      1.22    nonaka 		    HVN_NVS_CMD_NORESP);
   3328      1.22    nonaka 		if (error) {
   3329      1.22    nonaka 			device_printf(sc->sc_dev,
   3330      1.22    nonaka 			    "failed to send rxbuf disconn: %d", error);
   3331      1.22    nonaka 		}
   3332      1.22    nonaka 		CLR(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED);
   3333      1.22    nonaka 		mutex_exit(&sc->sc_nvsrsp_lock);
   3334       1.1    nonaka 
   3335      1.22    nonaka 		/*
   3336      1.22    nonaka 		 * Wait for the hypervisor to receive this NVS request.
   3337      1.22    nonaka 		 *
   3338      1.22    nonaka 		 * NOTE:
   3339      1.22    nonaka 		 * The TX bufring will not be drained by the hypervisor,
   3340      1.22    nonaka 		 * if the primary channel is revoked.
   3341      1.22    nonaka 		 */
   3342      1.22    nonaka 		while (!vmbus_channel_tx_empty(sc->sc_prichan) &&
   3343      1.22    nonaka 		    !vmbus_channel_is_revoked(sc->sc_prichan)) {
   3344      1.22    nonaka 			DELAY(20);
   3345      1.22    nonaka 			s = splnet();
   3346      1.22    nonaka 			hvn_nvs_intr1(&sc->sc_rxr[0], sc->sc_tx_process_limit,
   3347      1.22    nonaka 			    sc->sc_rx_process_limit);
   3348      1.22    nonaka 			splx(s);
   3349      1.22    nonaka 		}
   3350      1.22    nonaka 		/*
   3351      1.22    nonaka 		 * Linger long enough for NVS to disconnect RXBUF.
   3352      1.22    nonaka 		 */
   3353      1.22    nonaka 		DELAY(200);
   3354      1.22    nonaka 	}
   3355       1.1    nonaka 
   3356      1.22    nonaka 	if (sc->sc_prichan->ch_sc->sc_proto < VMBUS_VERSION_WIN10 &&
   3357      1.22    nonaka 	    sc->sc_rx_hndl) {
   3358      1.22    nonaka 		/*
   3359      1.22    nonaka 		 * Disconnect RXBUF from primary channel.
   3360      1.22    nonaka 		 */
   3361      1.22    nonaka 		vmbus_handle_free(sc->sc_prichan, sc->sc_rx_hndl);
   3362      1.22    nonaka 		sc->sc_rx_hndl = 0;
   3363      1.22    nonaka 	}
   3364       1.1    nonaka 
   3365       1.1    nonaka 	return 0;
   3366       1.1    nonaka }
   3367       1.1    nonaka 
   3368       1.1    nonaka static int
   3369      1.22    nonaka hvn_nvs_connect_chim(struct hvn_softc *sc)
   3370       1.1    nonaka {
   3371      1.22    nonaka 	struct hvn_nvs_chim_conn cmd;
   3372      1.22    nonaka 	const struct hvn_nvs_chim_conn_resp *rsp;
   3373      1.22    nonaka 	uint64_t tid;
   3374       1.1    nonaka 
   3375      1.22    nonaka 	mutex_init(&sc->sc_chim_bmap_lock, MUTEX_DEFAULT, IPL_NET);
   3376       1.1    nonaka 
   3377      1.22    nonaka 	/*
   3378      1.22    nonaka 	 * Connect chimney sending buffer GPADL to the primary channel.
   3379      1.22    nonaka 	 *
   3380      1.22    nonaka 	 * NOTE:
   3381      1.22    nonaka 	 * Only primary channel has chimney sending buffer connected to it.
   3382      1.22    nonaka 	 * Sub-channels just share this chimney sending buffer.
   3383      1.22    nonaka 	 */
   3384      1.22    nonaka 	if (vmbus_handle_alloc(sc->sc_prichan, &sc->sc_chim_dma, HVN_CHIM_SIZE,
   3385      1.22    nonaka 	    &sc->sc_chim_hndl)) {
   3386      1.22    nonaka 		DPRINTF("%s: failed to obtain a PA handle for chimney\n",
   3387       1.1    nonaka 		    device_xname(sc->sc_dev));
   3388      1.22    nonaka 		return -1;
   3389       1.1    nonaka 	}
   3390      1.22    nonaka 
   3391      1.22    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3392      1.22    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_CHIM_CONN;
   3393      1.22    nonaka 	cmd.nvs_gpadl = sc->sc_chim_hndl;
   3394      1.22    nonaka 	cmd.nvs_sig = HVN_NVS_CHIM_SIG;
   3395      1.22    nonaka 
   3396      1.22    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3397      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3398      1.22    nonaka 	if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0))
   3399       1.1    nonaka 		goto errout;
   3400      1.22    nonaka 
   3401      1.22    nonaka 	rsp = (struct hvn_nvs_chim_conn_resp *)&sc->sc_nvsrsp;
   3402      1.22    nonaka 	if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
   3403      1.22    nonaka 		DPRINTF("%s: failed to set up chimney sending buffer\n",
   3404       1.1    nonaka 		    device_xname(sc->sc_dev));
   3405       1.1    nonaka 		goto errout;
   3406       1.1    nonaka 	}
   3407       1.1    nonaka 
   3408      1.22    nonaka 	if (rsp->nvs_sectsz == 0 ||
   3409      1.22    nonaka 	    (rsp->nvs_sectsz % sizeof(uint32_t)) != 0) {
   3410      1.22    nonaka 		/*
   3411      1.22    nonaka 		 * Can't use chimney sending buffer; done!
   3412      1.22    nonaka 		 */
   3413      1.22    nonaka 		if (rsp->nvs_sectsz == 0) {
   3414      1.22    nonaka 			device_printf(sc->sc_dev,
   3415      1.22    nonaka 			    "zero chimney sending buffer section size\n");
   3416      1.22    nonaka 		} else {
   3417      1.22    nonaka 			device_printf(sc->sc_dev,
   3418      1.22    nonaka 			    "misaligned chimney sending buffers,"
   3419      1.22    nonaka 			    " section size: %d", rsp->nvs_sectsz);
   3420       1.1    nonaka 		}
   3421      1.22    nonaka 		sc->sc_chim_szmax = 0;
   3422      1.22    nonaka 		sc->sc_chim_cnt = 0;
   3423      1.22    nonaka 	} else {
   3424      1.22    nonaka 		sc->sc_chim_szmax = rsp->nvs_sectsz;
   3425      1.22    nonaka 		sc->sc_chim_cnt = HVN_CHIM_SIZE / sc->sc_chim_szmax;
   3426       1.1    nonaka 	}
   3427       1.1    nonaka 
   3428      1.22    nonaka 	if (sc->sc_chim_szmax > 0) {
   3429      1.22    nonaka 		if ((HVN_CHIM_SIZE % sc->sc_chim_szmax) != 0) {
   3430      1.22    nonaka 			device_printf(sc->sc_dev,
   3431      1.22    nonaka 			    "chimney sending sections are not properly "
   3432      1.22    nonaka 			    "aligned\n");
   3433      1.22    nonaka 		}
   3434      1.22    nonaka 		if ((sc->sc_chim_cnt % LONG_BIT) != 0) {
   3435      1.22    nonaka 			device_printf(sc->sc_dev,
   3436      1.22    nonaka 			    "discard %d chimney sending sections\n",
   3437      1.22    nonaka 			    sc->sc_chim_cnt % LONG_BIT);
   3438      1.22    nonaka 		}
   3439       1.1    nonaka 
   3440      1.22    nonaka 		sc->sc_chim_bmap_cnt = sc->sc_chim_cnt / LONG_BIT;
   3441      1.22    nonaka 		sc->sc_chim_bmap = kmem_zalloc(sc->sc_chim_bmap_cnt *
   3442      1.22    nonaka 		    sizeof(u_long), KM_SLEEP);
   3443      1.22    nonaka 	}
   3444       1.1    nonaka 
   3445      1.22    nonaka 	/* Done! */
   3446      1.22    nonaka 	SET(sc->sc_flags, HVN_SCF_CHIM_CONNECTED);
   3447       1.1    nonaka 
   3448      1.22    nonaka 	aprint_verbose_dev(sc->sc_dev, "chimney sending buffer %d/%d\n",
   3449      1.22    nonaka 	    sc->sc_chim_szmax, sc->sc_chim_cnt);
   3450       1.1    nonaka 
   3451      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3452       1.1    nonaka 
   3453      1.22    nonaka 	return 0;
   3454       1.1    nonaka 
   3455      1.22    nonaka errout:
   3456      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3457      1.22    nonaka 	hvn_nvs_disconnect_chim(sc);
   3458      1.22    nonaka 	return -1;
   3459       1.1    nonaka }
   3460       1.1    nonaka 
   3461       1.1    nonaka static int
   3462      1.22    nonaka hvn_nvs_disconnect_chim(struct hvn_softc *sc)
   3463       1.1    nonaka {
   3464      1.22    nonaka 	struct hvn_nvs_chim_disconn cmd;
   3465       1.1    nonaka 	uint64_t tid;
   3466      1.22    nonaka 	int s, error;
   3467       1.1    nonaka 
   3468      1.22    nonaka 	if (ISSET(sc->sc_flags, HVN_SCF_CHIM_CONNECTED)) {
   3469      1.22    nonaka 		memset(&cmd, 0, sizeof(cmd));
   3470      1.22    nonaka 		cmd.nvs_type = HVN_NVS_TYPE_CHIM_DISCONN;
   3471      1.22    nonaka 		cmd.nvs_sig = HVN_NVS_CHIM_SIG;
   3472       1.1    nonaka 
   3473       1.1    nonaka 		tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3474      1.22    nonaka 		mutex_enter(&sc->sc_nvsrsp_lock);
   3475      1.22    nonaka 		error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid,
   3476      1.22    nonaka 		    HVN_NVS_CMD_NORESP);
   3477      1.22    nonaka 		if (error) {
   3478      1.22    nonaka 			device_printf(sc->sc_dev,
   3479      1.22    nonaka 			    "failed to send chim disconn: %d", error);
   3480      1.22    nonaka 		}
   3481      1.22    nonaka 		CLR(sc->sc_flags, HVN_SCF_CHIM_CONNECTED);
   3482      1.22    nonaka 		mutex_exit(&sc->sc_nvsrsp_lock);
   3483       1.1    nonaka 
   3484      1.22    nonaka 		/*
   3485      1.22    nonaka 		 * Wait for the hypervisor to receive this NVS request.
   3486      1.22    nonaka 		 *
   3487      1.22    nonaka 		 * NOTE:
   3488      1.22    nonaka 		 * The TX bufring will not be drained by the hypervisor,
   3489      1.22    nonaka 		 * if the primary channel is revoked.
   3490      1.22    nonaka 		 */
   3491      1.22    nonaka 		while (!vmbus_channel_tx_empty(sc->sc_prichan) &&
   3492      1.22    nonaka 		    !vmbus_channel_is_revoked(sc->sc_prichan)) {
   3493      1.22    nonaka 			DELAY(20);
   3494      1.22    nonaka 			s = splnet();
   3495      1.22    nonaka 			hvn_nvs_intr1(&sc->sc_rxr[0], sc->sc_tx_process_limit,
   3496      1.22    nonaka 			    sc->sc_rx_process_limit);
   3497      1.22    nonaka 			splx(s);
   3498       1.1    nonaka 		}
   3499      1.22    nonaka 		/*
   3500      1.22    nonaka 		 * Linger long enough for NVS to disconnect chimney
   3501      1.22    nonaka 		 * sending buffer.
   3502      1.22    nonaka 		 */
   3503      1.22    nonaka 		DELAY(200);
   3504       1.1    nonaka 	}
   3505      1.22    nonaka 
   3506      1.22    nonaka 	if (sc->sc_prichan->ch_sc->sc_proto < VMBUS_VERSION_WIN10 &&
   3507      1.22    nonaka 	    sc->sc_chim_hndl) {
   3508      1.22    nonaka 		/*
   3509      1.22    nonaka 		 * Disconnect chimney sending buffer from primary channel.
   3510      1.22    nonaka 		 */
   3511      1.22    nonaka 		vmbus_handle_free(sc->sc_prichan, sc->sc_chim_hndl);
   3512      1.22    nonaka 		sc->sc_chim_hndl = 0;
   3513       1.1    nonaka 	}
   3514       1.1    nonaka 
   3515      1.22    nonaka 	if (sc->sc_chim_bmap != NULL) {
   3516      1.22    nonaka 		kmem_free(sc->sc_chim_bmap, sc->sc_chim_cnt / LONG_BIT);
   3517      1.22    nonaka 		sc->sc_chim_bmap = NULL;
   3518      1.22    nonaka 		sc->sc_chim_bmap_cnt = 0;
   3519       1.1    nonaka 	}
   3520       1.1    nonaka 
   3521      1.22    nonaka 	mutex_destroy(&sc->sc_chim_bmap_lock);
   3522       1.1    nonaka 
   3523       1.1    nonaka 	return 0;
   3524       1.1    nonaka }
   3525       1.1    nonaka 
   3526      1.22    nonaka #define HVN_HANDLE_RING_DOTX	__BIT(0)
   3527      1.22    nonaka 
   3528      1.22    nonaka static int
   3529      1.22    nonaka hvn_handle_ring(struct hvn_rx_ring *rxr, int txlimit, int rxlimit)
   3530       1.1    nonaka {
   3531      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   3532       1.1    nonaka 	struct vmbus_chanpkt_hdr *cph;
   3533       1.1    nonaka 	const struct hvn_nvs_hdr *nvs;
   3534       1.1    nonaka 	uint64_t rid;
   3535       1.1    nonaka 	uint32_t rlen;
   3536      1.22    nonaka 	int n, tx = 0, rx = 0;
   3537      1.22    nonaka 	int result = 0;
   3538       1.1    nonaka 	int rv;
   3539       1.1    nonaka 
   3540      1.22    nonaka 	mutex_enter(&rxr->rxr_lock);
   3541       1.1    nonaka 	for (;;) {
   3542      1.22    nonaka 		rv = vmbus_channel_recv(rxr->rxr_chan, rxr->rxr_nvsbuf,
   3543       1.1    nonaka 		    HVN_NVS_BUFSIZE, &rlen, &rid, 1);
   3544       1.1    nonaka 		if (rv != 0 || rlen == 0) {
   3545       1.1    nonaka 			if (rv != EAGAIN)
   3546       1.1    nonaka 				device_printf(sc->sc_dev,
   3547       1.1    nonaka 				    "failed to receive an NVSP packet\n");
   3548       1.1    nonaka 			break;
   3549       1.1    nonaka 		}
   3550      1.22    nonaka 		cph = (struct vmbus_chanpkt_hdr *)rxr->rxr_nvsbuf;
   3551       1.1    nonaka 		nvs = (const struct hvn_nvs_hdr *)VMBUS_CHANPKT_CONST_DATA(cph);
   3552       1.1    nonaka 
   3553       1.1    nonaka 		if (cph->cph_type == VMBUS_CHANPKT_TYPE_COMP) {
   3554       1.1    nonaka 			switch (nvs->nvs_type) {
   3555       1.1    nonaka 			case HVN_NVS_TYPE_INIT_RESP:
   3556       1.1    nonaka 			case HVN_NVS_TYPE_RXBUF_CONNRESP:
   3557       1.1    nonaka 			case HVN_NVS_TYPE_CHIM_CONNRESP:
   3558       1.1    nonaka 			case HVN_NVS_TYPE_SUBCH_RESP:
   3559      1.22    nonaka 				mutex_enter(&sc->sc_nvsrsp_lock);
   3560       1.1    nonaka 				/* copy the response back */
   3561       1.1    nonaka 				memcpy(&sc->sc_nvsrsp, nvs, HVN_NVS_MSGSIZE);
   3562       1.1    nonaka 				sc->sc_nvsdone = 1;
   3563      1.22    nonaka 				cv_signal(&sc->sc_nvsrsp_cv);
   3564      1.22    nonaka 				mutex_exit(&sc->sc_nvsrsp_lock);
   3565       1.1    nonaka 				break;
   3566       1.1    nonaka 			case HVN_NVS_TYPE_RNDIS_ACK:
   3567      1.22    nonaka 				if (rxr->rxr_txr == NULL)
   3568      1.22    nonaka 					break;
   3569      1.22    nonaka 
   3570      1.22    nonaka 				result |= HVN_HANDLE_RING_DOTX;
   3571      1.22    nonaka 				mutex_enter(&rxr->rxr_txr->txr_lock);
   3572      1.22    nonaka 				hvn_txeof(rxr->rxr_txr, cph->cph_tid);
   3573      1.22    nonaka 				mutex_exit(&rxr->rxr_txr->txr_lock);
   3574      1.22    nonaka 				if (txlimit > 0 && ++tx >= txlimit)
   3575      1.22    nonaka 					goto out;
   3576       1.1    nonaka 				break;
   3577       1.1    nonaka 			default:
   3578       1.1    nonaka 				device_printf(sc->sc_dev,
   3579       1.1    nonaka 				    "unhandled NVSP packet type %u "
   3580       1.1    nonaka 				    "on completion\n", nvs->nvs_type);
   3581       1.1    nonaka 				break;
   3582       1.1    nonaka 			}
   3583       1.1    nonaka 		} else if (cph->cph_type == VMBUS_CHANPKT_TYPE_RXBUF) {
   3584       1.1    nonaka 			switch (nvs->nvs_type) {
   3585       1.1    nonaka 			case HVN_NVS_TYPE_RNDIS:
   3586      1.22    nonaka 				n = hvn_rndis_input(rxr, cph->cph_tid, cph);
   3587      1.22    nonaka 				if (rxlimit > 0) {
   3588      1.22    nonaka 					if (n < 0)
   3589      1.22    nonaka 						goto out;
   3590      1.22    nonaka 					rx += n;
   3591      1.22    nonaka 					if (rx >= rxlimit)
   3592      1.22    nonaka 						goto out;
   3593      1.22    nonaka 				}
   3594       1.1    nonaka 				break;
   3595       1.1    nonaka 			default:
   3596       1.1    nonaka 				device_printf(sc->sc_dev,
   3597       1.1    nonaka 				    "unhandled NVSP packet type %u "
   3598       1.1    nonaka 				    "on receive\n", nvs->nvs_type);
   3599       1.1    nonaka 				break;
   3600       1.1    nonaka 			}
   3601      1.12    nonaka 		} else if (cph->cph_type == VMBUS_CHANPKT_TYPE_INBAND) {
   3602      1.12    nonaka 			switch (nvs->nvs_type) {
   3603      1.12    nonaka 			case HVN_NVS_TYPE_TXTBL_NOTE:
   3604      1.12    nonaka 				/* Useless; ignore */
   3605      1.12    nonaka 				break;
   3606      1.12    nonaka 			default:
   3607      1.12    nonaka 				device_printf(sc->sc_dev,
   3608      1.12    nonaka 				    "got notify, nvs type %u\n", nvs->nvs_type);
   3609      1.12    nonaka 				break;
   3610      1.12    nonaka 			}
   3611       1.1    nonaka 		} else
   3612       1.1    nonaka 			device_printf(sc->sc_dev,
   3613       1.1    nonaka 			    "unknown NVSP packet type %u\n", cph->cph_type);
   3614       1.1    nonaka 	}
   3615      1.22    nonaka out:
   3616      1.22    nonaka 	mutex_exit(&rxr->rxr_lock);
   3617      1.22    nonaka 
   3618      1.22    nonaka 	return result;
   3619      1.22    nonaka }
   3620      1.22    nonaka 
   3621      1.22    nonaka static void
   3622      1.22    nonaka hvn_nvs_intr1(struct hvn_rx_ring *rxr, int txlimit, int rxlimit)
   3623      1.22    nonaka {
   3624      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   3625      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   3626      1.22    nonaka 	struct hvn_tx_ring *txr = rxr->rxr_txr;
   3627      1.22    nonaka 	int result;
   3628      1.22    nonaka 
   3629      1.22    nonaka 	rxr->rxr_workqueue = sc->sc_txrx_workqueue;
   3630      1.22    nonaka 
   3631      1.22    nonaka 	result = hvn_handle_ring(rxr, txlimit, rxlimit);
   3632      1.22    nonaka 
   3633      1.22    nonaka 	if ((result & HVN_HANDLE_RING_DOTX) && txr != NULL) {
   3634      1.22    nonaka 		mutex_enter(&txr->txr_lock);
   3635      1.22    nonaka 		/* ALTQ */
   3636      1.22    nonaka 		if (txr->txr_id == 0) {
   3637      1.22    nonaka 			if_schedule_deferred_start(ifp);
   3638      1.22    nonaka 		}
   3639      1.22    nonaka 		softint_schedule(txr->txr_si);
   3640      1.22    nonaka 		mutex_exit(&txr->txr_lock);
   3641      1.22    nonaka 	}
   3642      1.22    nonaka }
   3643      1.22    nonaka 
   3644      1.22    nonaka static void
   3645      1.22    nonaka hvn_schedule_handle_ring(struct hvn_softc *sc, struct hvn_rx_ring *rxr,
   3646      1.22    nonaka     bool intr)
   3647      1.22    nonaka {
   3648      1.22    nonaka 
   3649      1.22    nonaka 	KASSERT(mutex_owned(&rxr->rxr_onwork_lock));
   3650      1.22    nonaka 
   3651      1.22    nonaka 	if (rxr->rxr_workqueue) {
   3652      1.22    nonaka 		if (!rxr->rxr_onlist) {
   3653      1.22    nonaka 			rxr->rxr_onlist = true;
   3654      1.22    nonaka 			if (intr)
   3655      1.22    nonaka 				rxr->rxr_evdeferreq.ev_count++;
   3656      1.22    nonaka 			else
   3657      1.22    nonaka 				rxr->rxr_evredeferreq.ev_count++;
   3658      1.22    nonaka 			workqueue_enqueue(sc->sc_wq, &rxr->rxr_wk, NULL);
   3659      1.22    nonaka 		}
   3660      1.22    nonaka 	} else {
   3661      1.22    nonaka 		rxr->rxr_onlist = true;
   3662      1.22    nonaka 		if (intr)
   3663      1.22    nonaka 			rxr->rxr_evdeferreq.ev_count++;
   3664      1.22    nonaka 		else
   3665      1.22    nonaka 			rxr->rxr_evredeferreq.ev_count++;
   3666      1.22    nonaka 		softint_schedule(rxr->rxr_si);
   3667      1.22    nonaka 	}
   3668      1.22    nonaka }
   3669      1.22    nonaka 
   3670      1.22    nonaka static void
   3671      1.22    nonaka hvn_handle_ring_common(struct hvn_rx_ring *rxr)
   3672      1.22    nonaka {
   3673      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   3674      1.22    nonaka 	int txlimit = sc->sc_tx_process_limit;
   3675      1.22    nonaka 	int rxlimit = sc->sc_rx_process_limit;
   3676      1.22    nonaka 
   3677      1.22    nonaka 	rxr->rxr_evdefer.ev_count++;
   3678      1.22    nonaka 
   3679      1.22    nonaka 	mutex_enter(&rxr->rxr_onwork_lock);
   3680      1.22    nonaka 	rxr->rxr_onproc = true;
   3681      1.22    nonaka 	rxr->rxr_onlist = false;
   3682      1.22    nonaka 	mutex_exit(&rxr->rxr_onwork_lock);
   3683      1.22    nonaka 
   3684      1.22    nonaka 	hvn_nvs_intr1(rxr, txlimit, rxlimit);
   3685      1.22    nonaka 
   3686      1.22    nonaka 	mutex_enter(&rxr->rxr_onwork_lock);
   3687      1.22    nonaka 	if (vmbus_channel_unpause(rxr->rxr_chan)) {
   3688      1.22    nonaka 		vmbus_channel_pause(rxr->rxr_chan);
   3689      1.22    nonaka 		hvn_schedule_handle_ring(sc, rxr, false);
   3690      1.22    nonaka 	}
   3691      1.22    nonaka 	rxr->rxr_onproc = false;
   3692      1.22    nonaka 	cv_broadcast(&rxr->rxr_onwork_cv);
   3693      1.22    nonaka 	mutex_exit(&rxr->rxr_onwork_lock);
   3694      1.22    nonaka }
   3695      1.22    nonaka 
   3696      1.22    nonaka static void
   3697      1.22    nonaka hvn_handle_ring_work(struct work *wk, void *arg)
   3698      1.22    nonaka {
   3699      1.22    nonaka 	struct hvn_rx_ring *rxr = container_of(wk, struct hvn_rx_ring, rxr_wk);
   3700      1.22    nonaka 
   3701      1.22    nonaka 	hvn_handle_ring_common(rxr);
   3702      1.22    nonaka }
   3703      1.22    nonaka 
   3704      1.22    nonaka static void
   3705      1.22    nonaka hvn_nvs_softintr(void *arg)
   3706      1.22    nonaka {
   3707      1.22    nonaka 	struct hvn_rx_ring *rxr = arg;
   3708      1.22    nonaka 
   3709      1.22    nonaka 	hvn_handle_ring_common(rxr);
   3710      1.22    nonaka }
   3711      1.22    nonaka 
   3712      1.22    nonaka static void
   3713      1.22    nonaka hvn_nvs_intr(void *arg)
   3714      1.22    nonaka {
   3715      1.22    nonaka 	struct hvn_rx_ring *rxr = arg;
   3716      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   3717      1.22    nonaka 	int txlimit = cold ? 0 : sc->sc_tx_intr_process_limit;
   3718      1.22    nonaka 	int rxlimit = cold ? 0 : sc->sc_rx_intr_process_limit;
   3719      1.22    nonaka 
   3720      1.22    nonaka 	rxr->rxr_evintr.ev_count++;
   3721      1.22    nonaka 
   3722      1.22    nonaka 	KASSERT(!rxr->rxr_onproc);
   3723      1.22    nonaka 	KASSERT(!rxr->rxr_onlist);
   3724       1.1    nonaka 
   3725      1.22    nonaka 	vmbus_channel_pause(rxr->rxr_chan);
   3726      1.22    nonaka 
   3727      1.22    nonaka 	hvn_nvs_intr1(rxr, txlimit, rxlimit);
   3728      1.22    nonaka 
   3729      1.22    nonaka 	if (vmbus_channel_unpause(rxr->rxr_chan) && !cold) {
   3730      1.22    nonaka 		vmbus_channel_pause(rxr->rxr_chan);
   3731      1.22    nonaka 		mutex_enter(&rxr->rxr_onwork_lock);
   3732      1.22    nonaka 		hvn_schedule_handle_ring(sc, rxr, true);
   3733      1.22    nonaka 		mutex_exit(&rxr->rxr_onwork_lock);
   3734      1.22    nonaka 	}
   3735       1.1    nonaka }
   3736       1.1    nonaka 
   3737       1.1    nonaka static int
   3738       1.1    nonaka hvn_nvs_cmd(struct hvn_softc *sc, void *cmd, size_t cmdsize, uint64_t tid,
   3739      1.22    nonaka     u_int flags)
   3740       1.1    nonaka {
   3741      1.22    nonaka 	struct hvn_rx_ring *rxr = &sc->sc_rxr[0];	/* primary channel */
   3742       1.1    nonaka 	struct hvn_nvs_hdr *hdr = cmd;
   3743       1.1    nonaka 	int tries = 10;
   3744       1.1    nonaka 	int rv, s;
   3745       1.1    nonaka 
   3746      1.22    nonaka 	KASSERT(mutex_owned(&sc->sc_nvsrsp_lock));
   3747      1.22    nonaka 
   3748       1.1    nonaka 	sc->sc_nvsdone = 0;
   3749       1.1    nonaka 
   3750       1.1    nonaka 	do {
   3751      1.22    nonaka 		rv = vmbus_channel_send(rxr->rxr_chan, cmd, cmdsize,
   3752       1.1    nonaka 		    tid, VMBUS_CHANPKT_TYPE_INBAND,
   3753      1.22    nonaka 		    ISSET(flags, HVN_NVS_CMD_NORESP) ? 0 :
   3754      1.22    nonaka 		      VMBUS_CHANPKT_FLAG_RC);
   3755       1.1    nonaka 		if (rv == EAGAIN) {
   3756      1.22    nonaka 			DELAY(1000);
   3757       1.1    nonaka 		} else if (rv) {
   3758       1.1    nonaka 			DPRINTF("%s: NVSP operation %u send error %d\n",
   3759       1.1    nonaka 			    device_xname(sc->sc_dev), hdr->nvs_type, rv);
   3760       1.1    nonaka 			return rv;
   3761       1.1    nonaka 		}
   3762       1.1    nonaka 	} while (rv != 0 && --tries > 0);
   3763       1.1    nonaka 
   3764       1.1    nonaka 	if (tries == 0 && rv != 0) {
   3765       1.1    nonaka 		device_printf(sc->sc_dev,
   3766       1.1    nonaka 		    "NVSP operation %u send error %d\n", hdr->nvs_type, rv);
   3767       1.1    nonaka 		return rv;
   3768       1.1    nonaka 	}
   3769       1.1    nonaka 
   3770      1.22    nonaka 	if (ISSET(flags, HVN_NVS_CMD_NORESP))
   3771       1.1    nonaka 		return 0;
   3772       1.1    nonaka 
   3773      1.22    nonaka 	while (!sc->sc_nvsdone && !ISSET(sc->sc_flags, HVN_SCF_REVOKED)) {
   3774      1.22    nonaka 		mutex_exit(&sc->sc_nvsrsp_lock);
   3775      1.22    nonaka 		DELAY(1000);
   3776      1.22    nonaka 		s = splnet();
   3777      1.22    nonaka 		hvn_nvs_intr1(rxr, 0, 0);
   3778      1.22    nonaka 		splx(s);
   3779      1.22    nonaka 		mutex_enter(&sc->sc_nvsrsp_lock);
   3780      1.22    nonaka 	}
   3781       1.1    nonaka 
   3782       1.1    nonaka 	return 0;
   3783       1.1    nonaka }
   3784       1.1    nonaka 
   3785       1.1    nonaka static int
   3786      1.22    nonaka hvn_nvs_ack(struct hvn_rx_ring *rxr, uint64_t tid)
   3787       1.1    nonaka {
   3788      1.22    nonaka 	struct hvn_softc *sc __unused = rxr->rxr_softc;
   3789       1.1    nonaka 	struct hvn_nvs_rndis_ack cmd;
   3790       1.1    nonaka 	int tries = 5;
   3791       1.1    nonaka 	int rv;
   3792       1.1    nonaka 
   3793       1.1    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_RNDIS_ACK;
   3794       1.1    nonaka 	cmd.nvs_status = HVN_NVS_STATUS_OK;
   3795       1.1    nonaka 	do {
   3796      1.22    nonaka 		rv = vmbus_channel_send(rxr->rxr_chan, &cmd, sizeof(cmd),
   3797       1.1    nonaka 		    tid, VMBUS_CHANPKT_TYPE_COMP, 0);
   3798       1.1    nonaka 		if (rv == EAGAIN)
   3799      1.22    nonaka 			DELAY(10);
   3800       1.1    nonaka 		else if (rv) {
   3801       1.1    nonaka 			DPRINTF("%s: NVSP acknowledgement error %d\n",
   3802       1.1    nonaka 			    device_xname(sc->sc_dev), rv);
   3803       1.1    nonaka 			return rv;
   3804       1.1    nonaka 		}
   3805      1.22    nonaka 	} while (rv != 0 && --tries > 0);
   3806      1.22    nonaka 	return rv;
   3807      1.22    nonaka }
   3808      1.22    nonaka 
   3809      1.22    nonaka static void
   3810      1.22    nonaka hvn_nvs_detach(struct hvn_softc *sc)
   3811      1.22    nonaka {
   3812      1.22    nonaka 
   3813      1.22    nonaka 	hvn_nvs_disconnect_rxbuf(sc);
   3814      1.22    nonaka 	hvn_nvs_disconnect_chim(sc);
   3815      1.22    nonaka }
   3816      1.22    nonaka 
   3817      1.22    nonaka static int
   3818      1.22    nonaka hvn_nvs_alloc_subchannels(struct hvn_softc *sc, int *nsubchp)
   3819      1.22    nonaka {
   3820      1.22    nonaka 	struct hvn_nvs_subch_req cmd;
   3821      1.22    nonaka 	struct hvn_nvs_subch_resp *rsp;
   3822      1.22    nonaka 	uint64_t tid;
   3823      1.22    nonaka 	int nsubch, nsubch_req;
   3824      1.22    nonaka 
   3825      1.22    nonaka 	nsubch_req = *nsubchp;
   3826      1.22    nonaka 	KASSERTMSG(nsubch_req > 0, "invalid # of sub-channels %d", nsubch_req);
   3827      1.22    nonaka 
   3828      1.22    nonaka 	memset(&cmd, 0, sizeof(cmd));
   3829      1.22    nonaka 	cmd.nvs_type = HVN_NVS_TYPE_SUBCH_REQ;
   3830      1.22    nonaka 	cmd.nvs_op = HVN_NVS_SUBCH_OP_ALLOC;
   3831      1.22    nonaka 	cmd.nvs_nsubch = nsubch_req;
   3832      1.22    nonaka 
   3833      1.22    nonaka 	tid = atomic_inc_uint_nv(&sc->sc_nvstid);
   3834      1.22    nonaka 	mutex_enter(&sc->sc_nvsrsp_lock);
   3835      1.22    nonaka 	if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0)) {
   3836      1.22    nonaka 		mutex_exit(&sc->sc_nvsrsp_lock);
   3837      1.22    nonaka 		return EIO;
   3838      1.22    nonaka 	}
   3839      1.22    nonaka 
   3840      1.22    nonaka 	rsp = (struct hvn_nvs_subch_resp *)&sc->sc_nvsrsp;
   3841      1.22    nonaka 	if (rsp->nvs_status != HVN_NVS_STATUS_OK) {
   3842      1.22    nonaka 		mutex_exit(&sc->sc_nvsrsp_lock);
   3843      1.22    nonaka 		DPRINTF("%s: failed to alloc sub-channels\n",
   3844      1.22    nonaka 		    device_xname(sc->sc_dev));
   3845      1.22    nonaka 		return EIO;
   3846      1.22    nonaka 	}
   3847      1.22    nonaka 
   3848      1.22    nonaka 	nsubch = rsp->nvs_nsubch;
   3849      1.22    nonaka 	if (nsubch > nsubch_req) {
   3850      1.22    nonaka 		aprint_debug_dev(sc->sc_dev,
   3851      1.22    nonaka 		    "%u subchans are allocated, requested %d\n",
   3852      1.22    nonaka 		    nsubch, nsubch_req);
   3853      1.22    nonaka 		nsubch = nsubch_req;
   3854      1.22    nonaka 	}
   3855      1.22    nonaka 	mutex_exit(&sc->sc_nvsrsp_lock);
   3856       1.1    nonaka 
   3857      1.22    nonaka 	*nsubchp = nsubch;
   3858       1.1    nonaka 
   3859      1.22    nonaka 	return 0;
   3860       1.1    nonaka }
   3861       1.1    nonaka 
   3862       1.1    nonaka static inline struct rndis_cmd *
   3863       1.1    nonaka hvn_alloc_cmd(struct hvn_softc *sc)
   3864       1.1    nonaka {
   3865       1.1    nonaka 	struct rndis_cmd *rc;
   3866       1.1    nonaka 
   3867       1.1    nonaka 	mutex_enter(&sc->sc_cntl_fqlck);
   3868       1.1    nonaka 	while ((rc = TAILQ_FIRST(&sc->sc_cntl_fq)) == NULL)
   3869      1.22    nonaka 		cv_wait(&sc->sc_cntl_fqcv, &sc->sc_cntl_fqlck);
   3870       1.1    nonaka 	TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry);
   3871       1.1    nonaka 	mutex_exit(&sc->sc_cntl_fqlck);
   3872       1.1    nonaka 	return rc;
   3873       1.1    nonaka }
   3874       1.1    nonaka 
   3875       1.1    nonaka static inline void
   3876       1.1    nonaka hvn_submit_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
   3877       1.1    nonaka {
   3878       1.1    nonaka 
   3879       1.1    nonaka 	mutex_enter(&sc->sc_cntl_sqlck);
   3880       1.1    nonaka 	TAILQ_INSERT_TAIL(&sc->sc_cntl_sq, rc, rc_entry);
   3881       1.1    nonaka 	mutex_exit(&sc->sc_cntl_sqlck);
   3882       1.1    nonaka }
   3883       1.1    nonaka 
   3884       1.1    nonaka static inline struct rndis_cmd *
   3885       1.1    nonaka hvn_complete_cmd(struct hvn_softc *sc, uint32_t id)
   3886       1.1    nonaka {
   3887       1.1    nonaka 	struct rndis_cmd *rc;
   3888       1.1    nonaka 
   3889       1.1    nonaka 	mutex_enter(&sc->sc_cntl_sqlck);
   3890       1.1    nonaka 	TAILQ_FOREACH(rc, &sc->sc_cntl_sq, rc_entry) {
   3891       1.1    nonaka 		if (rc->rc_id == id) {
   3892       1.1    nonaka 			TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry);
   3893       1.1    nonaka 			break;
   3894       1.1    nonaka 		}
   3895       1.1    nonaka 	}
   3896       1.1    nonaka 	mutex_exit(&sc->sc_cntl_sqlck);
   3897       1.1    nonaka 	if (rc != NULL) {
   3898       1.1    nonaka 		mutex_enter(&sc->sc_cntl_cqlck);
   3899       1.1    nonaka 		TAILQ_INSERT_TAIL(&sc->sc_cntl_cq, rc, rc_entry);
   3900       1.1    nonaka 		mutex_exit(&sc->sc_cntl_cqlck);
   3901       1.1    nonaka 	}
   3902       1.1    nonaka 	return rc;
   3903       1.1    nonaka }
   3904       1.1    nonaka 
   3905       1.1    nonaka static inline void
   3906       1.1    nonaka hvn_release_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
   3907       1.1    nonaka {
   3908       1.1    nonaka 
   3909       1.1    nonaka 	mutex_enter(&sc->sc_cntl_cqlck);
   3910       1.1    nonaka 	TAILQ_REMOVE(&sc->sc_cntl_cq, rc, rc_entry);
   3911       1.1    nonaka 	mutex_exit(&sc->sc_cntl_cqlck);
   3912       1.1    nonaka }
   3913       1.1    nonaka 
   3914       1.1    nonaka static inline int
   3915       1.1    nonaka hvn_rollback_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
   3916       1.1    nonaka {
   3917       1.1    nonaka 	struct rndis_cmd *rn;
   3918       1.1    nonaka 
   3919       1.1    nonaka 	mutex_enter(&sc->sc_cntl_sqlck);
   3920       1.1    nonaka 	TAILQ_FOREACH(rn, &sc->sc_cntl_sq, rc_entry) {
   3921       1.1    nonaka 		if (rn == rc) {
   3922       1.1    nonaka 			TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry);
   3923       1.1    nonaka 			mutex_exit(&sc->sc_cntl_sqlck);
   3924       1.1    nonaka 			return 0;
   3925       1.1    nonaka 		}
   3926       1.1    nonaka 	}
   3927       1.1    nonaka 	mutex_exit(&sc->sc_cntl_sqlck);
   3928       1.1    nonaka 	return -1;
   3929       1.1    nonaka }
   3930       1.1    nonaka 
   3931       1.1    nonaka static inline void
   3932       1.1    nonaka hvn_free_cmd(struct hvn_softc *sc, struct rndis_cmd *rc)
   3933       1.1    nonaka {
   3934       1.1    nonaka 
   3935       1.1    nonaka 	memset(rc->rc_req, 0, sizeof(struct rndis_packet_msg));
   3936       1.1    nonaka 	memset(&rc->rc_cmp, 0, sizeof(rc->rc_cmp));
   3937       1.1    nonaka 	memset(&rc->rc_msg, 0, sizeof(rc->rc_msg));
   3938       1.1    nonaka 	mutex_enter(&sc->sc_cntl_fqlck);
   3939       1.1    nonaka 	TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry);
   3940      1.22    nonaka 	cv_signal(&sc->sc_cntl_fqcv);
   3941       1.1    nonaka 	mutex_exit(&sc->sc_cntl_fqlck);
   3942       1.1    nonaka }
   3943       1.1    nonaka 
   3944       1.1    nonaka static int
   3945      1.22    nonaka hvn_rndis_init(struct hvn_softc *sc)
   3946       1.1    nonaka {
   3947       1.1    nonaka 	struct rndis_cmd *rc;
   3948      1.22    nonaka 	int i;
   3949       1.1    nonaka 
   3950       1.1    nonaka 	/* RNDIS control message queues */
   3951       1.1    nonaka 	TAILQ_INIT(&sc->sc_cntl_sq);
   3952       1.1    nonaka 	TAILQ_INIT(&sc->sc_cntl_cq);
   3953       1.1    nonaka 	TAILQ_INIT(&sc->sc_cntl_fq);
   3954       1.1    nonaka 	mutex_init(&sc->sc_cntl_sqlck, MUTEX_DEFAULT, IPL_NET);
   3955       1.1    nonaka 	mutex_init(&sc->sc_cntl_cqlck, MUTEX_DEFAULT, IPL_NET);
   3956       1.1    nonaka 	mutex_init(&sc->sc_cntl_fqlck, MUTEX_DEFAULT, IPL_NET);
   3957      1.22    nonaka 	cv_init(&sc->sc_cntl_fqcv, "nvsalloc");
   3958       1.1    nonaka 
   3959       1.1    nonaka 	for (i = 0; i < HVN_RNDIS_CTLREQS; i++) {
   3960       1.1    nonaka 		rc = &sc->sc_cntl_msgs[i];
   3961       1.1    nonaka 		if (bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
   3962      1.22    nonaka 		    BUS_DMA_WAITOK, &rc->rc_dmap)) {
   3963       1.1    nonaka 			DPRINTF("%s: failed to create RNDIS command map\n",
   3964       1.1    nonaka 			    device_xname(sc->sc_dev));
   3965       1.1    nonaka 			goto errout;
   3966       1.1    nonaka 		}
   3967       1.1    nonaka 		if (bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
   3968      1.22    nonaka 		    0, &rc->rc_segs, 1, &rc->rc_nsegs, BUS_DMA_WAITOK)) {
   3969       1.1    nonaka 			DPRINTF("%s: failed to allocate RNDIS command\n",
   3970       1.1    nonaka 			    device_xname(sc->sc_dev));
   3971       1.1    nonaka 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
   3972       1.1    nonaka 			goto errout;
   3973       1.1    nonaka 		}
   3974       1.1    nonaka 		if (bus_dmamem_map(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs,
   3975      1.22    nonaka 		    PAGE_SIZE, (void **)&rc->rc_req, BUS_DMA_WAITOK)) {
   3976       1.1    nonaka 			DPRINTF("%s: failed to allocate RNDIS command\n",
   3977       1.1    nonaka 			    device_xname(sc->sc_dev));
   3978       1.1    nonaka 			bus_dmamem_free(sc->sc_dmat, &rc->rc_segs,
   3979       1.1    nonaka 			    rc->rc_nsegs);
   3980       1.1    nonaka 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
   3981       1.1    nonaka 			goto errout;
   3982       1.1    nonaka 		}
   3983       1.1    nonaka 		memset(rc->rc_req, 0, PAGE_SIZE);
   3984       1.1    nonaka 		if (bus_dmamap_load(sc->sc_dmat, rc->rc_dmap, rc->rc_req,
   3985      1.22    nonaka 		    PAGE_SIZE, NULL, BUS_DMA_WAITOK)) {
   3986       1.1    nonaka 			DPRINTF("%s: failed to load RNDIS command map\n",
   3987       1.1    nonaka 			    device_xname(sc->sc_dev));
   3988      1.23       rin 			bus_dmamem_unmap(sc->sc_dmat, rc->rc_req, PAGE_SIZE);
   3989      1.23       rin 			rc->rc_req = NULL;
   3990       1.1    nonaka 			bus_dmamem_free(sc->sc_dmat, &rc->rc_segs,
   3991       1.1    nonaka 			    rc->rc_nsegs);
   3992       1.1    nonaka 			bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
   3993       1.1    nonaka 			goto errout;
   3994       1.1    nonaka 		}
   3995       1.1    nonaka 		rc->rc_gpa = atop(rc->rc_dmap->dm_segs[0].ds_addr);
   3996      1.22    nonaka 		mutex_init(&rc->rc_lock, MUTEX_DEFAULT, IPL_NET);
   3997      1.22    nonaka 		cv_init(&rc->rc_cv, "rndiscmd");
   3998       1.1    nonaka 		TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry);
   3999       1.1    nonaka 	}
   4000       1.1    nonaka 
   4001      1.22    nonaka 	/* Initialize RNDIS Data command */
   4002      1.22    nonaka 	memset(&sc->sc_data_msg, 0, sizeof(sc->sc_data_msg));
   4003      1.22    nonaka 	sc->sc_data_msg.nvs_type = HVN_NVS_TYPE_RNDIS;
   4004      1.22    nonaka 	sc->sc_data_msg.nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_DATA;
   4005      1.22    nonaka 	sc->sc_data_msg.nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID;
   4006      1.22    nonaka 
   4007      1.22    nonaka 	return 0;
   4008      1.22    nonaka 
   4009      1.22    nonaka errout:
   4010      1.22    nonaka 	hvn_rndis_destroy(sc);
   4011      1.22    nonaka 	return -1;
   4012      1.22    nonaka }
   4013      1.22    nonaka 
   4014      1.22    nonaka static void
   4015      1.22    nonaka hvn_rndis_destroy(struct hvn_softc *sc)
   4016      1.22    nonaka {
   4017      1.22    nonaka 	struct rndis_cmd *rc;
   4018      1.22    nonaka 	int i;
   4019      1.22    nonaka 
   4020      1.22    nonaka 	for (i = 0; i < HVN_RNDIS_CTLREQS; i++) {
   4021      1.22    nonaka 		rc = &sc->sc_cntl_msgs[i];
   4022      1.22    nonaka 		if (rc->rc_req == NULL)
   4023      1.22    nonaka 			continue;
   4024      1.22    nonaka 
   4025      1.22    nonaka 		TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry);
   4026      1.23       rin 		bus_dmamap_unload(sc->sc_dmat, rc->rc_dmap);
   4027      1.23       rin 		bus_dmamem_unmap(sc->sc_dmat, rc->rc_req, PAGE_SIZE);
   4028      1.23       rin 		rc->rc_req = NULL;
   4029      1.22    nonaka 		bus_dmamem_free(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs);
   4030      1.22    nonaka 		bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap);
   4031      1.22    nonaka 		mutex_destroy(&rc->rc_lock);
   4032      1.22    nonaka 		cv_destroy(&rc->rc_cv);
   4033      1.22    nonaka 	}
   4034      1.22    nonaka 
   4035      1.22    nonaka 	mutex_destroy(&sc->sc_cntl_sqlck);
   4036      1.22    nonaka 	mutex_destroy(&sc->sc_cntl_cqlck);
   4037      1.22    nonaka 	mutex_destroy(&sc->sc_cntl_fqlck);
   4038      1.22    nonaka 	cv_destroy(&sc->sc_cntl_fqcv);
   4039      1.22    nonaka }
   4040      1.22    nonaka 
   4041      1.22    nonaka static int
   4042      1.22    nonaka hvn_rndis_attach(struct hvn_softc *sc, int mtu)
   4043      1.22    nonaka {
   4044      1.22    nonaka 	struct rndis_init_req *req;
   4045      1.22    nonaka 	struct rndis_init_comp *cmp;
   4046      1.22    nonaka 	struct rndis_cmd *rc;
   4047      1.22    nonaka 	int rv;
   4048      1.22    nonaka 
   4049       1.1    nonaka 	rc = hvn_alloc_cmd(sc);
   4050       1.1    nonaka 
   4051       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4052       1.1    nonaka 	    BUS_DMASYNC_PREREAD);
   4053       1.1    nonaka 
   4054       1.1    nonaka 	rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid);
   4055       1.1    nonaka 
   4056       1.1    nonaka 	req = rc->rc_req;
   4057       1.1    nonaka 	req->rm_type = REMOTE_NDIS_INITIALIZE_MSG;
   4058       1.1    nonaka 	req->rm_len = sizeof(*req);
   4059       1.1    nonaka 	req->rm_rid = rc->rc_id;
   4060       1.1    nonaka 	req->rm_ver_major = RNDIS_VERSION_MAJOR;
   4061       1.1    nonaka 	req->rm_ver_minor = RNDIS_VERSION_MINOR;
   4062       1.1    nonaka 	req->rm_max_xfersz = HVN_RNDIS_XFER_SIZE;
   4063       1.1    nonaka 
   4064       1.1    nonaka 	rc->rc_cmplen = sizeof(*cmp);
   4065       1.1    nonaka 
   4066       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4067       1.1    nonaka 	    BUS_DMASYNC_PREWRITE);
   4068       1.1    nonaka 
   4069      1.22    nonaka 	if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) {
   4070       1.1    nonaka 		DPRINTF("%s: INITIALIZE_MSG failed, error %d\n",
   4071       1.1    nonaka 		    device_xname(sc->sc_dev), rv);
   4072       1.1    nonaka 		hvn_free_cmd(sc, rc);
   4073      1.22    nonaka 		return -1;
   4074       1.1    nonaka 	}
   4075       1.1    nonaka 	cmp = (struct rndis_init_comp *)&rc->rc_cmp;
   4076       1.1    nonaka 	if (cmp->rm_status != RNDIS_STATUS_SUCCESS) {
   4077       1.1    nonaka 		DPRINTF("%s: failed to init RNDIS, error %#x\n",
   4078       1.1    nonaka 		    device_xname(sc->sc_dev), cmp->rm_status);
   4079       1.1    nonaka 		hvn_free_cmd(sc, rc);
   4080      1.22    nonaka 		return -1;
   4081       1.1    nonaka 	}
   4082       1.1    nonaka 
   4083      1.22    nonaka 	sc->sc_rndis_agg_size = cmp->rm_pktmaxsz;
   4084      1.22    nonaka 	sc->sc_rndis_agg_pkts = cmp->rm_pktmaxcnt;
   4085      1.22    nonaka 	sc->sc_rndis_agg_align = __BIT(cmp->rm_align);
   4086      1.22    nonaka 
   4087      1.22    nonaka 	if (sc->sc_rndis_agg_align < sizeof(uint32_t)) {
   4088      1.22    nonaka 		/*
   4089      1.25    andvar 		 * The RNDIS packet message encap assumes that the RNDIS
   4090      1.22    nonaka 		 * packet message is at least 4 bytes aligned.  Fix up the
   4091      1.22    nonaka 		 * alignment here, if the remote side sets the alignment
   4092      1.22    nonaka 		 * too low.
   4093      1.22    nonaka 		 */
   4094      1.22    nonaka 		aprint_verbose_dev(sc->sc_dev,
   4095      1.22    nonaka 		    "fixup RNDIS aggpkt align: %u -> %zu\n",
   4096      1.22    nonaka 		    sc->sc_rndis_agg_align, sizeof(uint32_t));
   4097      1.22    nonaka 		sc->sc_rndis_agg_align = sizeof(uint32_t);
   4098      1.22    nonaka 	}
   4099      1.22    nonaka 
   4100      1.22    nonaka 	aprint_verbose_dev(sc->sc_dev,
   4101      1.22    nonaka 	    "RNDIS ver %u.%u, aggpkt size %u, aggpkt cnt %u, aggpkt align %u\n",
   4102      1.22    nonaka 	    cmp->rm_ver_major, cmp->rm_ver_minor, sc->sc_rndis_agg_size,
   4103      1.22    nonaka 	    sc->sc_rndis_agg_pkts, sc->sc_rndis_agg_align);
   4104      1.22    nonaka 
   4105       1.1    nonaka 	hvn_free_cmd(sc, rc);
   4106       1.1    nonaka 
   4107      1.22    nonaka 	return 0;
   4108      1.22    nonaka }
   4109      1.22    nonaka 
   4110      1.22    nonaka static int
   4111      1.22    nonaka hvn_get_rsscaps(struct hvn_softc *sc, int *nrxr)
   4112      1.22    nonaka {
   4113      1.22    nonaka 	struct ndis_rss_caps in, caps;
   4114      1.22    nonaka 	size_t caps_len;
   4115      1.22    nonaka 	int error, rxr_cnt, indsz, hash_fnidx;
   4116      1.22    nonaka 	uint32_t hash_func = 0, hash_types = 0;
   4117      1.22    nonaka 
   4118      1.22    nonaka 	*nrxr = 0;
   4119      1.22    nonaka 
   4120      1.22    nonaka 	if (sc->sc_ndisver < NDIS_VERSION_6_20)
   4121      1.22    nonaka 		return EOPNOTSUPP;
   4122      1.22    nonaka 
   4123      1.22    nonaka 	memset(&in, 0, sizeof(in));
   4124      1.22    nonaka 	in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS;
   4125      1.22    nonaka 	in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2;
   4126      1.22    nonaka 	in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE;
   4127      1.22    nonaka 
   4128      1.22    nonaka 	caps_len = NDIS_RSS_CAPS_SIZE;
   4129      1.22    nonaka 	error = hvn_rndis_query2(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES,
   4130      1.22    nonaka 	    &in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len, NDIS_RSS_CAPS_SIZE_6_0);
   4131      1.22    nonaka 	if (error)
   4132      1.22    nonaka 		return error;
   4133      1.22    nonaka 
   4134      1.22    nonaka 	/*
   4135      1.22    nonaka 	 * Preliminary verification.
   4136      1.22    nonaka 	 */
   4137      1.22    nonaka 	if (caps.ndis_hdr.ndis_type != NDIS_OBJTYPE_RSS_CAPS) {
   4138      1.22    nonaka 		DPRINTF("%s: invalid NDIS objtype 0x%02x\n",
   4139      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_hdr.ndis_type);
   4140      1.22    nonaka 		return EINVAL;
   4141      1.22    nonaka 	}
   4142      1.22    nonaka 	if (caps.ndis_hdr.ndis_rev < NDIS_RSS_CAPS_REV_1) {
   4143      1.22    nonaka 		DPRINTF("%s: invalid NDIS objrev 0x%02x\n",
   4144      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_hdr.ndis_rev);
   4145      1.22    nonaka 		return EINVAL;
   4146      1.22    nonaka 	}
   4147      1.22    nonaka 	if (caps.ndis_hdr.ndis_size > caps_len) {
   4148      1.22    nonaka 		DPRINTF("%s: invalid NDIS objsize %u, data size %zu\n",
   4149      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_hdr.ndis_size,
   4150      1.22    nonaka 		    caps_len);
   4151      1.22    nonaka 		return EINVAL;
   4152      1.22    nonaka 	} else if (caps.ndis_hdr.ndis_size < NDIS_RSS_CAPS_SIZE_6_0) {
   4153      1.22    nonaka 		DPRINTF("%s: invalid NDIS objsize %u\n",
   4154      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_hdr.ndis_size);
   4155      1.22    nonaka 		return EINVAL;
   4156      1.22    nonaka 	}
   4157      1.22    nonaka 
   4158      1.22    nonaka 	/*
   4159      1.22    nonaka 	 * Save information for later RSS configuration.
   4160      1.22    nonaka 	 */
   4161      1.22    nonaka 	if (caps.ndis_nrxr == 0) {
   4162      1.22    nonaka 		DPRINTF("%s: 0 RX rings!?\n", device_xname(sc->sc_dev));
   4163      1.22    nonaka 		return EINVAL;
   4164      1.22    nonaka 	}
   4165      1.22    nonaka 	rxr_cnt = caps.ndis_nrxr;
   4166      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "%u Rx rings\n", rxr_cnt);
   4167      1.22    nonaka 
   4168      1.22    nonaka 	if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE &&
   4169      1.22    nonaka 	    caps.ndis_hdr.ndis_rev >= NDIS_RSS_CAPS_REV_2) {
   4170      1.22    nonaka 		if (caps.ndis_nind > NDIS_HASH_INDCNT) {
   4171      1.22    nonaka 			DPRINTF("%s: too many RSS indirect table entries %u\n",
   4172      1.22    nonaka 			    device_xname(sc->sc_dev), caps.ndis_nind);
   4173      1.22    nonaka 			return EOPNOTSUPP;
   4174      1.22    nonaka 		}
   4175      1.22    nonaka 		if (!powerof2(caps.ndis_nind)) {
   4176      1.22    nonaka 			DPRINTF("%s: RSS indirect table size is not power-of-2:"
   4177      1.22    nonaka 			    " %u\n", device_xname(sc->sc_dev), caps.ndis_nind);
   4178      1.22    nonaka 			return EOPNOTSUPP;
   4179      1.22    nonaka 		}
   4180      1.22    nonaka 
   4181      1.22    nonaka 		indsz = caps.ndis_nind;
   4182      1.22    nonaka 	} else {
   4183      1.22    nonaka 		indsz = NDIS_HASH_INDCNT;
   4184      1.22    nonaka 	}
   4185      1.22    nonaka 	if (rxr_cnt > indsz) {
   4186      1.22    nonaka 		aprint_debug_dev(sc->sc_dev,
   4187      1.22    nonaka 		    "# of RX rings (%u) > RSS indirect table size %u\n",
   4188      1.22    nonaka 		    rxr_cnt, indsz);
   4189      1.22    nonaka 		rxr_cnt = indsz;
   4190      1.22    nonaka 	}
   4191      1.22    nonaka 
   4192      1.22    nonaka 	/*
   4193      1.22    nonaka 	 * NOTE:
   4194      1.22    nonaka 	 * Toeplitz is at the lowest bit, and it is prefered; so ffs(),
   4195      1.22    nonaka 	 * instead of fls(), is used here.
   4196      1.22    nonaka 	 */
   4197      1.22    nonaka 	hash_fnidx = ffs(caps.ndis_caps & NDIS_RSS_CAP_HASHFUNC_MASK);
   4198      1.22    nonaka 	if (hash_fnidx == 0) {
   4199      1.22    nonaka 		DPRINTF("%s: no hash functions, caps 0x%08x\n",
   4200      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_caps);
   4201      1.22    nonaka 		return EOPNOTSUPP;
   4202      1.22    nonaka 	}
   4203      1.22    nonaka 	hash_func = 1 << (hash_fnidx - 1);	/* ffs is 1-based */
   4204      1.22    nonaka 
   4205      1.22    nonaka 	if (caps.ndis_caps & NDIS_RSS_CAP_IPV4)
   4206      1.22    nonaka 		hash_types |= NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4;
   4207      1.22    nonaka 	if (caps.ndis_caps & NDIS_RSS_CAP_IPV6)
   4208      1.22    nonaka 		hash_types |= NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6;
   4209      1.22    nonaka 	if (caps.ndis_caps & NDIS_RSS_CAP_IPV6_EX)
   4210      1.22    nonaka 		hash_types |= NDIS_HASH_IPV6_EX | NDIS_HASH_TCP_IPV6_EX;
   4211      1.22    nonaka 	if (hash_types == 0) {
   4212      1.22    nonaka 		DPRINTF("%s: no hash types, caps 0x%08x\n",
   4213      1.22    nonaka 		    device_xname(sc->sc_dev), caps.ndis_caps);
   4214      1.22    nonaka 		return EOPNOTSUPP;
   4215      1.22    nonaka 	}
   4216      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "RSS caps %#x\n", caps.ndis_caps);
   4217      1.22    nonaka 
   4218      1.22    nonaka 	sc->sc_rss_ind_size = indsz;
   4219      1.22    nonaka 	sc->sc_rss_hcap = hash_func | hash_types;
   4220      1.22    nonaka 	if (sc->sc_caps & HVN_CAPS_UDPHASH) {
   4221      1.22    nonaka 		/* UDP 4-tuple hash is unconditionally enabled. */
   4222      1.22    nonaka 		sc->sc_rss_hcap |= NDIS_HASH_UDP_IPV4_X;
   4223      1.22    nonaka 	}
   4224      1.22    nonaka 	*nrxr = rxr_cnt;
   4225       1.1    nonaka 
   4226       1.1    nonaka 	return 0;
   4227      1.22    nonaka }
   4228      1.22    nonaka 
   4229      1.22    nonaka static int
   4230      1.22    nonaka hvn_set_rss(struct hvn_softc *sc, uint16_t flags)
   4231      1.22    nonaka {
   4232      1.22    nonaka 	struct ndis_rssprm_toeplitz *rss = &sc->sc_rss;
   4233      1.22    nonaka 	struct ndis_rss_params *params = &rss->rss_params;
   4234      1.22    nonaka 	int len;
   4235      1.22    nonaka 
   4236      1.22    nonaka 	/*
   4237      1.22    nonaka 	 * Only NDIS 6.20+ is supported:
   4238      1.22    nonaka 	 * We only support 4bytes element in indirect table, which has been
   4239      1.22    nonaka 	 * adopted since NDIS 6.20.
   4240      1.22    nonaka 	 */
   4241      1.22    nonaka 	if (sc->sc_ndisver < NDIS_VERSION_6_20)
   4242      1.22    nonaka 		return 0;
   4243      1.22    nonaka 
   4244      1.22    nonaka 	/* XXX only one can be specified through, popcnt? */
   4245      1.22    nonaka 	KASSERTMSG((sc->sc_rss_hash & NDIS_HASH_FUNCTION_MASK),
   4246      1.22    nonaka 	    "no hash func %08x", sc->sc_rss_hash);
   4247      1.22    nonaka 	KASSERTMSG((sc->sc_rss_hash & NDIS_HASH_STD),
   4248      1.22    nonaka 	    "no standard hash types %08x", sc->sc_rss_hash);
   4249      1.22    nonaka 	KASSERTMSG(sc->sc_rss_ind_size > 0, "no indirect table size");
   4250      1.22    nonaka 
   4251      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "RSS indirect table size %d, hash %#x\n",
   4252      1.22    nonaka 	    sc->sc_rss_ind_size, sc->sc_rss_hash);
   4253      1.22    nonaka 
   4254      1.22    nonaka 	len = NDIS_RSSPRM_TOEPLITZ_SIZE(sc->sc_rss_ind_size);
   4255      1.22    nonaka 
   4256      1.22    nonaka 	memset(params, 0, sizeof(*params));
   4257      1.22    nonaka 	params->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS;
   4258      1.22    nonaka 	params->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2;
   4259      1.22    nonaka 	params->ndis_hdr.ndis_size = len;
   4260      1.22    nonaka 	params->ndis_flags = flags;
   4261      1.22    nonaka 	params->ndis_hash =
   4262      1.22    nonaka 	    sc->sc_rss_hash & (NDIS_HASH_FUNCTION_MASK | NDIS_HASH_STD);
   4263      1.22    nonaka 	params->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->sc_rss_ind_size;
   4264      1.22    nonaka 	params->ndis_indoffset =
   4265      1.22    nonaka 	    offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]);
   4266      1.22    nonaka 	params->ndis_keysize = sizeof(rss->rss_key);
   4267      1.22    nonaka 	params->ndis_keyoffset =
   4268      1.22    nonaka 	    offsetof(struct ndis_rssprm_toeplitz, rss_key[0]);
   4269      1.22    nonaka 
   4270      1.22    nonaka 	return hvn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS, rss, len);
   4271      1.22    nonaka }
   4272      1.22    nonaka 
   4273      1.22    nonaka static void
   4274      1.22    nonaka hvn_fixup_rss_ind(struct hvn_softc *sc)
   4275      1.22    nonaka {
   4276      1.22    nonaka 	struct ndis_rssprm_toeplitz *rss = &sc->sc_rss;
   4277      1.22    nonaka 	int i, nchan;
   4278      1.22    nonaka 
   4279      1.22    nonaka 	nchan = sc->sc_nrxr_inuse;
   4280      1.22    nonaka 	KASSERTMSG(nchan > 1, "invalid # of channels %d", nchan);
   4281      1.22    nonaka 
   4282      1.22    nonaka 	/*
   4283      1.22    nonaka 	 * Check indirect table to make sure that all channels in it
   4284      1.22    nonaka 	 * can be used.
   4285      1.22    nonaka 	 */
   4286      1.22    nonaka 	for (i = 0; i < NDIS_HASH_INDCNT; i++) {
   4287      1.22    nonaka 		if (rss->rss_ind[i] >= nchan) {
   4288      1.22    nonaka 			DPRINTF("%s: RSS indirect table %d fixup: %u -> %d\n",
   4289      1.22    nonaka 			    device_xname(sc->sc_dev), i, rss->rss_ind[i],
   4290      1.22    nonaka 			    nchan - 1);
   4291      1.22    nonaka 			rss->rss_ind[i] = nchan - 1;
   4292      1.22    nonaka 		}
   4293      1.22    nonaka 	}
   4294      1.22    nonaka }
   4295      1.22    nonaka 
   4296      1.22    nonaka static int
   4297      1.22    nonaka hvn_get_hwcaps(struct hvn_softc *sc, struct ndis_offload *caps)
   4298      1.22    nonaka {
   4299      1.22    nonaka 	struct ndis_offload in;
   4300      1.22    nonaka 	size_t caps_len, len;
   4301      1.22    nonaka 	int error;
   4302       1.1    nonaka 
   4303      1.22    nonaka 	memset(&in, 0, sizeof(in));
   4304      1.22    nonaka 	in.ndis_hdr.ndis_type = NDIS_OBJTYPE_OFFLOAD;
   4305      1.22    nonaka 	if (sc->sc_ndisver >= NDIS_VERSION_6_30) {
   4306      1.22    nonaka 		in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_3;
   4307      1.22    nonaka 		len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE;
   4308      1.22    nonaka 	} else if (sc->sc_ndisver >= NDIS_VERSION_6_1) {
   4309      1.22    nonaka 		in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_2;
   4310      1.22    nonaka 		len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE_6_1;
   4311      1.22    nonaka 	} else {
   4312      1.22    nonaka 		in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_1;
   4313      1.22    nonaka 		len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE_6_0;
   4314       1.1    nonaka 	}
   4315      1.22    nonaka 
   4316      1.22    nonaka 	caps_len = NDIS_OFFLOAD_SIZE;
   4317      1.22    nonaka 	error = hvn_rndis_query2(sc, OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES,
   4318      1.22    nonaka 	    &in, len, caps, &caps_len, NDIS_OFFLOAD_SIZE_6_0);
   4319      1.22    nonaka 	if (error)
   4320      1.22    nonaka 		return error;
   4321      1.22    nonaka 
   4322      1.22    nonaka 	/*
   4323      1.22    nonaka 	 * Preliminary verification.
   4324      1.22    nonaka 	 */
   4325      1.22    nonaka 	if (caps->ndis_hdr.ndis_type != NDIS_OBJTYPE_OFFLOAD) {
   4326      1.22    nonaka 		DPRINTF("%s: invalid NDIS objtype 0x%02x\n",
   4327      1.22    nonaka 		    device_xname(sc->sc_dev), caps->ndis_hdr.ndis_type);
   4328      1.22    nonaka 		return EINVAL;
   4329      1.22    nonaka 	}
   4330      1.22    nonaka 	if (caps->ndis_hdr.ndis_rev < NDIS_OFFLOAD_REV_1) {
   4331      1.22    nonaka 		DPRINTF("%s: invalid NDIS objrev 0x%02x\n",
   4332      1.22    nonaka 		    device_xname(sc->sc_dev), caps->ndis_hdr.ndis_rev);
   4333      1.22    nonaka 		return EINVAL;
   4334      1.22    nonaka 	}
   4335      1.22    nonaka 	if (caps->ndis_hdr.ndis_size > caps_len) {
   4336      1.22    nonaka 		DPRINTF("%s: invalid NDIS objsize %u, data size %zu\n",
   4337      1.22    nonaka 		    device_xname(sc->sc_dev), caps->ndis_hdr.ndis_size,
   4338      1.22    nonaka 		    caps_len);
   4339      1.22    nonaka 		return EINVAL;
   4340      1.22    nonaka 	} else if (caps->ndis_hdr.ndis_size < NDIS_OFFLOAD_SIZE_6_0) {
   4341      1.22    nonaka 		DPRINTF("%s: invalid NDIS objsize %u\n",
   4342      1.22    nonaka 		    device_xname(sc->sc_dev), caps->ndis_hdr.ndis_size);
   4343      1.22    nonaka 		return EINVAL;
   4344      1.22    nonaka 	}
   4345      1.22    nonaka 
   4346      1.22    nonaka 	/*
   4347      1.22    nonaka 	 * NOTE:
   4348      1.22    nonaka 	 * caps->ndis_hdr.ndis_size MUST be checked before accessing
   4349      1.22    nonaka 	 * NDIS 6.1+ specific fields.
   4350      1.22    nonaka 	 */
   4351      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "hwcaps rev %u\n",
   4352      1.22    nonaka 	    caps->ndis_hdr.ndis_rev);
   4353      1.22    nonaka 
   4354      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "hwcaps csum: "
   4355      1.22    nonaka 	    "ip4 tx 0x%x/0x%x rx 0x%x/0x%x, "
   4356      1.22    nonaka 	    "ip6 tx 0x%x/0x%x rx 0x%x/0x%x\n",
   4357      1.22    nonaka 	    caps->ndis_csum.ndis_ip4_txcsum, caps->ndis_csum.ndis_ip4_txenc,
   4358      1.22    nonaka 	    caps->ndis_csum.ndis_ip4_rxcsum, caps->ndis_csum.ndis_ip4_rxenc,
   4359      1.22    nonaka 	    caps->ndis_csum.ndis_ip6_txcsum, caps->ndis_csum.ndis_ip6_txenc,
   4360      1.22    nonaka 	    caps->ndis_csum.ndis_ip6_rxcsum, caps->ndis_csum.ndis_ip6_rxenc);
   4361      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "hwcaps lsov2: "
   4362      1.22    nonaka 	    "ip4 maxsz %u minsg %u encap 0x%x, "
   4363      1.22    nonaka 	    "ip6 maxsz %u minsg %u encap 0x%x opts 0x%x\n",
   4364      1.22    nonaka 	    caps->ndis_lsov2.ndis_ip4_maxsz, caps->ndis_lsov2.ndis_ip4_minsg,
   4365      1.22    nonaka 	    caps->ndis_lsov2.ndis_ip4_encap, caps->ndis_lsov2.ndis_ip6_maxsz,
   4366      1.22    nonaka 	    caps->ndis_lsov2.ndis_ip6_minsg, caps->ndis_lsov2.ndis_ip6_encap,
   4367      1.22    nonaka 	    caps->ndis_lsov2.ndis_ip6_opts);
   4368      1.22    nonaka 
   4369      1.22    nonaka 	return 0;
   4370       1.1    nonaka }
   4371       1.1    nonaka 
   4372       1.1    nonaka static int
   4373      1.22    nonaka hvn_set_capabilities(struct hvn_softc *sc, int mtu)
   4374       1.1    nonaka {
   4375      1.22    nonaka 	struct ndis_offload hwcaps;
   4376       1.1    nonaka 	struct ndis_offload_params params;
   4377      1.22    nonaka 	size_t len;
   4378      1.22    nonaka 	uint32_t caps = 0;
   4379      1.22    nonaka 	int error, tso_maxsz, tso_minsg;
   4380      1.22    nonaka 
   4381      1.22    nonaka 	error = hvn_get_hwcaps(sc, &hwcaps);
   4382      1.22    nonaka 	if (error) {
   4383      1.22    nonaka 		DPRINTF("%s: failed to query hwcaps\n",
   4384      1.22    nonaka 		    device_xname(sc->sc_dev));
   4385      1.22    nonaka 		return error;
   4386      1.22    nonaka 	}
   4387       1.1    nonaka 
   4388      1.22    nonaka 	/* NOTE: 0 means "no change" */
   4389       1.1    nonaka 	memset(&params, 0, sizeof(params));
   4390       1.1    nonaka 
   4391       1.1    nonaka 	params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT;
   4392       1.1    nonaka 	if (sc->sc_ndisver < NDIS_VERSION_6_30) {
   4393       1.1    nonaka 		params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2;
   4394       1.1    nonaka 		len = params.ndis_hdr.ndis_size = NDIS_OFFLOAD_PARAMS_SIZE_6_1;
   4395       1.1    nonaka 	} else {
   4396       1.1    nonaka 		params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3;
   4397       1.1    nonaka 		len = params.ndis_hdr.ndis_size = NDIS_OFFLOAD_PARAMS_SIZE;
   4398       1.1    nonaka 	}
   4399       1.1    nonaka 
   4400      1.22    nonaka 	/*
   4401      1.22    nonaka 	 * TSO4/TSO6 setup.
   4402      1.22    nonaka 	 */
   4403      1.22    nonaka 	tso_maxsz = IP_MAXPACKET;
   4404      1.22    nonaka 	tso_minsg = 2;
   4405      1.22    nonaka 	if (hwcaps.ndis_lsov2.ndis_ip4_encap & NDIS_OFFLOAD_ENCAP_8023) {
   4406      1.22    nonaka 		caps |= HVN_CAPS_TSO4;
   4407      1.22    nonaka 		params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON;
   4408      1.22    nonaka 
   4409      1.22    nonaka 		if (hwcaps.ndis_lsov2.ndis_ip4_maxsz < tso_maxsz)
   4410      1.22    nonaka 			tso_maxsz = hwcaps.ndis_lsov2.ndis_ip4_maxsz;
   4411      1.22    nonaka 		if (hwcaps.ndis_lsov2.ndis_ip4_minsg > tso_minsg)
   4412      1.22    nonaka 			tso_minsg = hwcaps.ndis_lsov2.ndis_ip4_minsg;
   4413      1.22    nonaka 	}
   4414      1.22    nonaka 	if ((hwcaps.ndis_lsov2.ndis_ip6_encap & NDIS_OFFLOAD_ENCAP_8023) &&
   4415      1.22    nonaka 	    (hwcaps.ndis_lsov2.ndis_ip6_opts & HVN_NDIS_LSOV2_CAP_IP6) ==
   4416      1.22    nonaka 	    HVN_NDIS_LSOV2_CAP_IP6) {
   4417      1.22    nonaka 		caps |= HVN_CAPS_TSO6;
   4418      1.22    nonaka 		params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON;
   4419      1.22    nonaka 
   4420      1.22    nonaka 		if (hwcaps.ndis_lsov2.ndis_ip6_maxsz < tso_maxsz)
   4421      1.22    nonaka 			tso_maxsz = hwcaps.ndis_lsov2.ndis_ip6_maxsz;
   4422      1.22    nonaka 		if (hwcaps.ndis_lsov2.ndis_ip6_minsg > tso_minsg)
   4423      1.22    nonaka 			tso_minsg = hwcaps.ndis_lsov2.ndis_ip6_minsg;
   4424      1.22    nonaka 	}
   4425      1.22    nonaka 	sc->sc_tso_szmax = 0;
   4426      1.22    nonaka 	sc->sc_tso_sgmin = 0;
   4427      1.22    nonaka 	if (caps & (HVN_CAPS_TSO4 | HVN_CAPS_TSO6)) {
   4428      1.22    nonaka 		KASSERTMSG(tso_maxsz <= IP_MAXPACKET,
   4429      1.22    nonaka 		    "invalid NDIS TSO maxsz %d", tso_maxsz);
   4430      1.22    nonaka 		KASSERTMSG(tso_minsg >= 2,
   4431      1.22    nonaka 		    "invalid NDIS TSO minsg %d", tso_minsg);
   4432      1.22    nonaka 		if (tso_maxsz < tso_minsg * mtu) {
   4433      1.22    nonaka 			DPRINTF("%s: invalid NDIS TSO config: "
   4434      1.22    nonaka 			    "maxsz %d, minsg %d, mtu %d; "
   4435      1.22    nonaka 			    "disable TSO4 and TSO6\n", device_xname(sc->sc_dev),
   4436      1.22    nonaka 			    tso_maxsz, tso_minsg, mtu);
   4437      1.22    nonaka 			caps &= ~(HVN_CAPS_TSO4 | HVN_CAPS_TSO6);
   4438      1.22    nonaka 			params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_OFF;
   4439      1.22    nonaka 			params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_OFF;
   4440      1.22    nonaka 		} else {
   4441      1.22    nonaka 			sc->sc_tso_szmax = tso_maxsz;
   4442      1.22    nonaka 			sc->sc_tso_sgmin = tso_minsg;
   4443      1.22    nonaka 			aprint_debug_dev(sc->sc_dev,
   4444      1.22    nonaka 			    "NDIS TSO szmax %d sgmin %d\n",
   4445      1.22    nonaka 			    sc->sc_tso_szmax, sc->sc_tso_sgmin);
   4446      1.22    nonaka 		}
   4447      1.22    nonaka 	}
   4448      1.22    nonaka 
   4449      1.22    nonaka 	/* IPv4 checksum */
   4450      1.22    nonaka 	if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HVN_NDIS_TXCSUM_CAP_IP4) ==
   4451      1.22    nonaka 	    HVN_NDIS_TXCSUM_CAP_IP4) {
   4452      1.22    nonaka 		caps |= HVN_CAPS_IPCS;
   4453      1.22    nonaka 		params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TX;
   4454      1.22    nonaka 	}
   4455      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_IP4) {
   4456      1.22    nonaka 		if (params.ndis_ip4csum == NDIS_OFFLOAD_PARAM_TX)
   4457      1.22    nonaka 			params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX;
   4458      1.22    nonaka 		else
   4459      1.22    nonaka 			params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_RX;
   4460      1.22    nonaka 	}
   4461      1.22    nonaka 
   4462      1.22    nonaka 	/* TCP4 checksum */
   4463      1.22    nonaka 	if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HVN_NDIS_TXCSUM_CAP_TCP4) ==
   4464      1.22    nonaka 	    HVN_NDIS_TXCSUM_CAP_TCP4) {
   4465      1.22    nonaka 		caps |= HVN_CAPS_TCP4CS;
   4466      1.22    nonaka 		params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TX;
   4467      1.22    nonaka 	}
   4468      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_TCP4) {
   4469      1.22    nonaka 		if (params.ndis_tcp4csum == NDIS_OFFLOAD_PARAM_TX)
   4470      1.22    nonaka 			params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX;
   4471      1.22    nonaka 		else
   4472      1.22    nonaka 			params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_RX;
   4473      1.22    nonaka 	}
   4474      1.22    nonaka 
   4475      1.22    nonaka 	/* UDP4 checksum */
   4476      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip4_txcsum & NDIS_TXCSUM_CAP_UDP4) {
   4477      1.22    nonaka 		caps |= HVN_CAPS_UDP4CS;
   4478      1.22    nonaka 		params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TX;
   4479      1.22    nonaka 	}
   4480      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_UDP4) {
   4481      1.22    nonaka 		if (params.ndis_udp4csum == NDIS_OFFLOAD_PARAM_TX)
   4482      1.22    nonaka 			params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX;
   4483      1.22    nonaka 		else
   4484      1.22    nonaka 			params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_RX;
   4485      1.22    nonaka 	}
   4486      1.22    nonaka 
   4487      1.22    nonaka 	/* TCP6 checksum */
   4488      1.22    nonaka 	if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HVN_NDIS_TXCSUM_CAP_TCP6) ==
   4489      1.22    nonaka 	    HVN_NDIS_TXCSUM_CAP_TCP6) {
   4490      1.22    nonaka 		caps |= HVN_CAPS_TCP6CS;
   4491      1.22    nonaka 		params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TX;
   4492      1.22    nonaka 	}
   4493      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_TCP6) {
   4494      1.22    nonaka 		if (params.ndis_tcp6csum == NDIS_OFFLOAD_PARAM_TX)
   4495      1.22    nonaka 			params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX;
   4496      1.22    nonaka 		else
   4497      1.22    nonaka 			params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_RX;
   4498      1.22    nonaka 	}
   4499      1.22    nonaka 
   4500      1.22    nonaka 	/* UDP6 checksum */
   4501      1.22    nonaka 	if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HVN_NDIS_TXCSUM_CAP_UDP6) ==
   4502      1.22    nonaka 	    HVN_NDIS_TXCSUM_CAP_UDP6) {
   4503      1.22    nonaka 		caps |= HVN_CAPS_UDP6CS;
   4504      1.22    nonaka 		params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TX;
   4505      1.22    nonaka 	}
   4506      1.22    nonaka 	if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_UDP6) {
   4507      1.22    nonaka 		if (params.ndis_udp6csum == NDIS_OFFLOAD_PARAM_TX)
   4508      1.22    nonaka 			params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX;
   4509      1.22    nonaka 		else
   4510      1.22    nonaka 			params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_RX;
   4511      1.22    nonaka 	}
   4512      1.22    nonaka 
   4513      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "offload csum: "
   4514      1.22    nonaka 	    "ip4 %u, tcp4 %u, udp4 %u, tcp6 %u, udp6 %u\n",
   4515      1.22    nonaka 	    params.ndis_ip4csum, params.ndis_tcp4csum, params.ndis_udp4csum,
   4516      1.22    nonaka 	    params.ndis_tcp6csum, params.ndis_udp6csum);
   4517      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "offload lsov2: ip4 %u, ip6 %u\n",
   4518      1.22    nonaka 	    params.ndis_lsov2_ip4, params.ndis_lsov2_ip6);
   4519      1.22    nonaka 
   4520      1.22    nonaka 	error = hvn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, &params, len);
   4521      1.22    nonaka 	if (error) {
   4522      1.22    nonaka 		DPRINTF("%s: offload config failed: %d\n",
   4523      1.22    nonaka 		    device_xname(sc->sc_dev), error);
   4524      1.22    nonaka 		return error;
   4525       1.1    nonaka 	}
   4526       1.1    nonaka 
   4527      1.22    nonaka 	aprint_debug_dev(sc->sc_dev, "offload config done\n");
   4528      1.22    nonaka 	sc->sc_caps |= caps;
   4529      1.22    nonaka 
   4530      1.22    nonaka 	return 0;
   4531       1.1    nonaka }
   4532       1.1    nonaka 
   4533       1.1    nonaka static int
   4534      1.22    nonaka hvn_rndis_cmd(struct hvn_softc *sc, struct rndis_cmd *rc, u_int flags)
   4535       1.1    nonaka {
   4536      1.22    nonaka 	struct hvn_rx_ring *rxr = &sc->sc_rxr[0];	/* primary channel */
   4537       1.1    nonaka 	struct hvn_nvs_rndis *msg = &rc->rc_msg;
   4538       1.1    nonaka 	struct rndis_msghdr *hdr = rc->rc_req;
   4539       1.1    nonaka 	struct vmbus_gpa sgl[1];
   4540       1.1    nonaka 	int tries = 10;
   4541       1.1    nonaka 	int rv, s;
   4542       1.1    nonaka 
   4543       1.1    nonaka 	msg->nvs_type = HVN_NVS_TYPE_RNDIS;
   4544       1.1    nonaka 	msg->nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_CTRL;
   4545       1.1    nonaka 	msg->nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID;
   4546       1.1    nonaka 
   4547       1.1    nonaka 	sgl[0].gpa_page = rc->rc_gpa;
   4548       1.1    nonaka 	sgl[0].gpa_len = hdr->rm_len;
   4549       1.1    nonaka 	sgl[0].gpa_ofs = 0;
   4550       1.1    nonaka 
   4551       1.1    nonaka 	rc->rc_done = 0;
   4552       1.1    nonaka 
   4553      1.22    nonaka 	mutex_enter(&rc->rc_lock);
   4554      1.22    nonaka 
   4555       1.1    nonaka 	hvn_submit_cmd(sc, rc);
   4556       1.1    nonaka 
   4557       1.1    nonaka 	do {
   4558      1.22    nonaka 		rv = vmbus_channel_send_sgl(rxr->rxr_chan, sgl, 1, &rc->rc_msg,
   4559       1.1    nonaka 		    sizeof(*msg), rc->rc_id);
   4560       1.1    nonaka 		if (rv == EAGAIN) {
   4561      1.22    nonaka 			DELAY(1000);
   4562       1.1    nonaka 		} else if (rv) {
   4563      1.22    nonaka 			mutex_exit(&rc->rc_lock);
   4564       1.1    nonaka 			DPRINTF("%s: RNDIS operation %u send error %d\n",
   4565       1.1    nonaka 			    device_xname(sc->sc_dev), hdr->rm_type, rv);
   4566       1.1    nonaka 			hvn_rollback_cmd(sc, rc);
   4567       1.1    nonaka 			return rv;
   4568       1.1    nonaka 		}
   4569       1.1    nonaka 	} while (rv != 0 && --tries > 0);
   4570       1.1    nonaka 
   4571       1.1    nonaka 	if (tries == 0 && rv != 0) {
   4572      1.22    nonaka 		mutex_exit(&rc->rc_lock);
   4573       1.1    nonaka 		device_printf(sc->sc_dev,
   4574       1.1    nonaka 		    "RNDIS operation %u send error %d\n", hdr->rm_type, rv);
   4575      1.22    nonaka 		hvn_rollback_cmd(sc, rc);
   4576       1.1    nonaka 		return rv;
   4577       1.1    nonaka 	}
   4578      1.22    nonaka 	if (vmbus_channel_is_revoked(rxr->rxr_chan) ||
   4579      1.22    nonaka 	    ISSET(flags, HVN_RNDIS_CMD_NORESP)) {
   4580      1.13    nonaka 		/* No response */
   4581      1.22    nonaka 		mutex_exit(&rc->rc_lock);
   4582      1.22    nonaka 		if (hvn_rollback_cmd(sc, rc))
   4583      1.22    nonaka 			hvn_release_cmd(sc, rc);
   4584      1.13    nonaka 		return 0;
   4585      1.13    nonaka 	}
   4586       1.1    nonaka 
   4587       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4588       1.1    nonaka 	    BUS_DMASYNC_POSTWRITE);
   4589       1.1    nonaka 
   4590      1.22    nonaka 	while (!rc->rc_done && !ISSET(sc->sc_flags, HVN_SCF_REVOKED)) {
   4591      1.22    nonaka 		mutex_exit(&rc->rc_lock);
   4592      1.22    nonaka 		DELAY(1000);
   4593      1.22    nonaka 		s = splnet();
   4594      1.22    nonaka 		hvn_nvs_intr1(rxr, 0, 0);
   4595      1.22    nonaka 		splx(s);
   4596      1.22    nonaka 		mutex_enter(&rc->rc_lock);
   4597      1.22    nonaka 	}
   4598      1.22    nonaka 	mutex_exit(&rc->rc_lock);
   4599       1.1    nonaka 
   4600       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4601       1.1    nonaka 	    BUS_DMASYNC_POSTREAD);
   4602       1.1    nonaka 
   4603      1.22    nonaka 	if (!rc->rc_done) {
   4604      1.22    nonaka 		rv = EINTR;
   4605       1.1    nonaka 		if (hvn_rollback_cmd(sc, rc)) {
   4606       1.1    nonaka 			hvn_release_cmd(sc, rc);
   4607       1.1    nonaka 			rv = 0;
   4608       1.1    nonaka 		}
   4609       1.1    nonaka 		return rv;
   4610       1.1    nonaka 	}
   4611       1.1    nonaka 
   4612       1.1    nonaka 	hvn_release_cmd(sc, rc);
   4613       1.1    nonaka 	return 0;
   4614       1.1    nonaka }
   4615       1.1    nonaka 
   4616      1.22    nonaka static int
   4617      1.22    nonaka hvn_rndis_input(struct hvn_rx_ring *rxr, uint64_t tid, void *arg)
   4618       1.1    nonaka {
   4619      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   4620       1.1    nonaka 	struct vmbus_chanpkt_prplist *cp = arg;
   4621       1.1    nonaka 	uint32_t off, len, type;
   4622      1.22    nonaka 	int i, rv, rx = 0;
   4623      1.22    nonaka 	bool qfull = false;
   4624       1.1    nonaka 
   4625       1.1    nonaka 	if (sc->sc_rx_ring == NULL) {
   4626       1.1    nonaka 		DPRINTF("%s: invalid rx ring\n", device_xname(sc->sc_dev));
   4627      1.22    nonaka 		return 0;
   4628       1.1    nonaka 	}
   4629       1.1    nonaka 
   4630       1.1    nonaka 	for (i = 0; i < cp->cp_range_cnt; i++) {
   4631       1.1    nonaka 		off = cp->cp_range[i].gpa_ofs;
   4632       1.1    nonaka 		len = cp->cp_range[i].gpa_len;
   4633       1.1    nonaka 
   4634       1.1    nonaka 		KASSERT(off + len <= sc->sc_rx_size);
   4635       1.1    nonaka 		KASSERT(len >= RNDIS_HEADER_OFFSET + 4);
   4636       1.1    nonaka 
   4637       1.1    nonaka 		memcpy(&type, sc->sc_rx_ring + off, sizeof(type));
   4638       1.1    nonaka 		switch (type) {
   4639       1.1    nonaka 		/* data message */
   4640       1.1    nonaka 		case REMOTE_NDIS_PACKET_MSG:
   4641      1.22    nonaka 			rv = hvn_rxeof(rxr, sc->sc_rx_ring + off, len);
   4642      1.22    nonaka 			if (rv == 1)
   4643      1.22    nonaka 				rx++;
   4644      1.22    nonaka 			else if (rv == -1)	/* The receive queue is full. */
   4645      1.22    nonaka 				qfull = true;
   4646       1.1    nonaka 			break;
   4647       1.1    nonaka 		/* completion messages */
   4648       1.1    nonaka 		case REMOTE_NDIS_INITIALIZE_CMPLT:
   4649       1.1    nonaka 		case REMOTE_NDIS_QUERY_CMPLT:
   4650       1.1    nonaka 		case REMOTE_NDIS_SET_CMPLT:
   4651       1.1    nonaka 		case REMOTE_NDIS_RESET_CMPLT:
   4652       1.1    nonaka 		case REMOTE_NDIS_KEEPALIVE_CMPLT:
   4653       1.1    nonaka 			hvn_rndis_complete(sc, sc->sc_rx_ring + off, len);
   4654       1.1    nonaka 			break;
   4655       1.1    nonaka 		/* notification message */
   4656       1.1    nonaka 		case REMOTE_NDIS_INDICATE_STATUS_MSG:
   4657       1.1    nonaka 			hvn_rndis_status(sc, sc->sc_rx_ring + off, len);
   4658       1.1    nonaka 			break;
   4659       1.1    nonaka 		default:
   4660       1.1    nonaka 			device_printf(sc->sc_dev,
   4661       1.1    nonaka 			    "unhandled RNDIS message type %u\n", type);
   4662       1.1    nonaka 			break;
   4663       1.1    nonaka 		}
   4664       1.1    nonaka 	}
   4665       1.1    nonaka 
   4666      1.22    nonaka 	hvn_nvs_ack(rxr, tid);
   4667      1.22    nonaka 
   4668      1.22    nonaka 	if (qfull)
   4669      1.22    nonaka 		return -1;
   4670      1.22    nonaka 	return rx;
   4671       1.1    nonaka }
   4672       1.1    nonaka 
   4673       1.1    nonaka static inline struct mbuf *
   4674       1.1    nonaka hvn_devget(struct hvn_softc *sc, void *buf, uint32_t len)
   4675       1.1    nonaka {
   4676       1.1    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   4677       1.1    nonaka 	struct mbuf *m;
   4678      1.22    nonaka 	size_t size = len + ETHER_ALIGN + ETHER_VLAN_ENCAP_LEN;
   4679       1.1    nonaka 
   4680       1.1    nonaka 	MGETHDR(m, M_NOWAIT, MT_DATA);
   4681       1.1    nonaka 	if (m == NULL)
   4682       1.1    nonaka 		return NULL;
   4683       1.1    nonaka 
   4684       1.1    nonaka 	if (size > MHLEN) {
   4685       1.1    nonaka 		if (size <= MCLBYTES)
   4686       1.1    nonaka 			MCLGET(m, M_NOWAIT);
   4687       1.1    nonaka 		else
   4688       1.1    nonaka 			MEXTMALLOC(m, size, M_NOWAIT);
   4689       1.1    nonaka 		if ((m->m_flags & M_EXT) == 0) {
   4690       1.1    nonaka 			m_freem(m);
   4691       1.1    nonaka 			return NULL;
   4692       1.1    nonaka 		}
   4693       1.1    nonaka 	}
   4694       1.1    nonaka 
   4695       1.1    nonaka 	m->m_len = m->m_pkthdr.len = size;
   4696      1.22    nonaka 	m_adj(m, ETHER_ALIGN + ETHER_VLAN_ENCAP_LEN);
   4697       1.1    nonaka 	m_copyback(m, 0, len, buf);
   4698       1.1    nonaka 	m_set_rcvif(m, ifp);
   4699       1.1    nonaka 	return m;
   4700       1.1    nonaka }
   4701       1.1    nonaka 
   4702      1.22    nonaka #define HVN_RXINFO_CSUM		__BIT(NDIS_PKTINFO_TYPE_CSUM)
   4703      1.22    nonaka #define HVN_RXINFO_VLAN		__BIT(NDIS_PKTINFO_TYPE_VLAN)
   4704      1.22    nonaka #define HVN_RXINFO_HASHVAL	__BIT(HVN_NDIS_PKTINFO_TYPE_HASHVAL)
   4705      1.22    nonaka #define HVN_RXINFO_HASHINFO	__BIT(HVN_NDIS_PKTINFO_TYPE_HASHINF)
   4706      1.22    nonaka #define HVN_RXINFO_ALL		(HVN_RXINFO_CSUM | \
   4707      1.22    nonaka 				 HVN_RXINFO_VLAN | \
   4708      1.22    nonaka 				 HVN_RXINFO_HASHVAL | \
   4709      1.22    nonaka 				 HVN_RXINFO_HASHINFO)
   4710      1.22    nonaka 
   4711      1.22    nonaka static int
   4712      1.22    nonaka hvn_rxeof(struct hvn_rx_ring *rxr, uint8_t *buf, uint32_t len)
   4713       1.1    nonaka {
   4714      1.22    nonaka 	struct hvn_softc *sc = rxr->rxr_softc;
   4715       1.1    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   4716       1.1    nonaka 	struct rndis_packet_msg *pkt;
   4717       1.1    nonaka 	struct rndis_pktinfo *pi;
   4718       1.1    nonaka 	struct mbuf *m;
   4719      1.22    nonaka 	uint32_t mask, csum, vlan, hashval, hashinfo;
   4720       1.1    nonaka 
   4721       1.1    nonaka 	if (!(ifp->if_flags & IFF_RUNNING))
   4722      1.22    nonaka 		return 0;
   4723       1.1    nonaka 
   4724       1.1    nonaka 	if (len < sizeof(*pkt)) {
   4725       1.1    nonaka 		device_printf(sc->sc_dev, "data packet too short: %u\n",
   4726       1.1    nonaka 		    len);
   4727      1.22    nonaka 		return 0;
   4728       1.1    nonaka 	}
   4729       1.1    nonaka 
   4730       1.1    nonaka 	pkt = (struct rndis_packet_msg *)buf;
   4731       1.1    nonaka 	if (pkt->rm_dataoffset + pkt->rm_datalen > len) {
   4732       1.1    nonaka 		device_printf(sc->sc_dev,
   4733       1.1    nonaka 		    "data packet out of bounds: %u@%u\n", pkt->rm_dataoffset,
   4734       1.1    nonaka 		    pkt->rm_datalen);
   4735      1.22    nonaka 		return 0;
   4736       1.1    nonaka 	}
   4737       1.1    nonaka 
   4738       1.1    nonaka 	if ((m = hvn_devget(sc, buf + RNDIS_HEADER_OFFSET + pkt->rm_dataoffset,
   4739       1.1    nonaka 	    pkt->rm_datalen)) == NULL) {
   4740      1.16   thorpej 		if_statinc(ifp, if_ierrors);
   4741      1.22    nonaka 		return 0;
   4742       1.1    nonaka 	}
   4743       1.1    nonaka 
   4744       1.1    nonaka 	if (pkt->rm_pktinfooffset + pkt->rm_pktinfolen > len) {
   4745       1.1    nonaka 		device_printf(sc->sc_dev,
   4746       1.1    nonaka 		    "pktinfo is out of bounds: %u@%u vs %u\n",
   4747       1.1    nonaka 		    pkt->rm_pktinfolen, pkt->rm_pktinfooffset, len);
   4748       1.1    nonaka 		goto done;
   4749       1.1    nonaka 	}
   4750       1.1    nonaka 
   4751      1.22    nonaka 	mask = csum = hashval = hashinfo = 0;
   4752      1.22    nonaka 	vlan = 0xffffffff;
   4753       1.1    nonaka 	pi = (struct rndis_pktinfo *)(buf + RNDIS_HEADER_OFFSET +
   4754       1.1    nonaka 	    pkt->rm_pktinfooffset);
   4755       1.1    nonaka 	while (pkt->rm_pktinfolen > 0) {
   4756       1.1    nonaka 		if (pi->rm_size > pkt->rm_pktinfolen) {
   4757       1.1    nonaka 			device_printf(sc->sc_dev,
   4758       1.1    nonaka 			    "invalid pktinfo size: %u/%u\n", pi->rm_size,
   4759       1.1    nonaka 			    pkt->rm_pktinfolen);
   4760       1.1    nonaka 			break;
   4761       1.1    nonaka 		}
   4762       1.1    nonaka 
   4763       1.1    nonaka 		switch (pi->rm_type) {
   4764       1.1    nonaka 		case NDIS_PKTINFO_TYPE_CSUM:
   4765       1.1    nonaka 			memcpy(&csum, pi->rm_data, sizeof(csum));
   4766      1.22    nonaka 			SET(mask, HVN_RXINFO_CSUM);
   4767       1.1    nonaka 			break;
   4768       1.1    nonaka 		case NDIS_PKTINFO_TYPE_VLAN:
   4769       1.1    nonaka 			memcpy(&vlan, pi->rm_data, sizeof(vlan));
   4770      1.22    nonaka 			SET(mask, HVN_RXINFO_VLAN);
   4771      1.22    nonaka 			break;
   4772      1.22    nonaka 		case HVN_NDIS_PKTINFO_TYPE_HASHVAL:
   4773      1.22    nonaka 			memcpy(&hashval, pi->rm_data, sizeof(hashval));
   4774      1.22    nonaka 			SET(mask, HVN_RXINFO_HASHVAL);
   4775      1.22    nonaka 			break;
   4776      1.22    nonaka 		case HVN_NDIS_PKTINFO_TYPE_HASHINF:
   4777      1.22    nonaka 			memcpy(&hashinfo, pi->rm_data, sizeof(hashinfo));
   4778      1.22    nonaka 			SET(mask, HVN_RXINFO_HASHINFO);
   4779       1.1    nonaka 			break;
   4780       1.1    nonaka 		default:
   4781       1.1    nonaka 			DPRINTF("%s: unhandled pktinfo type %u\n",
   4782       1.1    nonaka 			    device_xname(sc->sc_dev), pi->rm_type);
   4783      1.22    nonaka 			goto next;
   4784      1.22    nonaka 		}
   4785      1.22    nonaka 
   4786      1.22    nonaka 		if (mask == HVN_RXINFO_ALL) {
   4787      1.22    nonaka 			/* All found; done */
   4788       1.1    nonaka 			break;
   4789       1.1    nonaka 		}
   4790      1.22    nonaka  next:
   4791       1.1    nonaka 		pkt->rm_pktinfolen -= pi->rm_size;
   4792       1.1    nonaka 		pi = (struct rndis_pktinfo *)((char *)pi + pi->rm_size);
   4793       1.1    nonaka 	}
   4794       1.1    nonaka 
   4795      1.22    nonaka 	/*
   4796      1.22    nonaka 	 * Final fixup.
   4797      1.22    nonaka 	 * - If there is no hash value, invalidate the hash info.
   4798      1.22    nonaka 	 */
   4799      1.22    nonaka 	if (!ISSET(mask, HVN_RXINFO_HASHVAL))
   4800      1.22    nonaka 		hashinfo = 0;
   4801      1.22    nonaka 
   4802      1.22    nonaka 	if (csum != 0) {
   4803      1.22    nonaka 		if (ISSET(csum, NDIS_RXCSUM_INFO_IPCS_OK) &&
   4804      1.22    nonaka 			ISSET(ifp->if_csum_flags_rx, M_CSUM_IPv4)) {
   4805      1.22    nonaka 			SET(m->m_pkthdr.csum_flags, M_CSUM_IPv4);
   4806      1.22    nonaka 			rxr->rxr_evcsum_ip.ev_count++;
   4807      1.22    nonaka 		}
   4808      1.22    nonaka 		if (ISSET(csum, NDIS_RXCSUM_INFO_TCPCS_OK) &&
   4809      1.22    nonaka 			ISSET(ifp->if_csum_flags_rx, M_CSUM_TCPv4)) {
   4810      1.22    nonaka 			SET(m->m_pkthdr.csum_flags, M_CSUM_TCPv4);
   4811      1.22    nonaka 			rxr->rxr_evcsum_tcp.ev_count++;
   4812      1.22    nonaka 		}
   4813      1.22    nonaka 		if (ISSET(csum, NDIS_RXCSUM_INFO_UDPCS_OK) &&
   4814      1.22    nonaka 			ISSET(ifp->if_csum_flags_rx, M_CSUM_UDPv4)) {
   4815      1.22    nonaka 			SET(m->m_pkthdr.csum_flags, M_CSUM_UDPv4);
   4816      1.22    nonaka 			rxr->rxr_evcsum_udp.ev_count++;
   4817      1.22    nonaka 		}
   4818      1.22    nonaka 	}
   4819      1.22    nonaka 
   4820      1.22    nonaka 	if (vlan != 0xffffffff) {
   4821      1.22    nonaka 		uint16_t t = NDIS_VLAN_INFO_ID(vlan);
   4822      1.22    nonaka 		t |= NDIS_VLAN_INFO_PRI(vlan) << EVL_PRIO_BITS;
   4823      1.22    nonaka 		t |= NDIS_VLAN_INFO_CFI(vlan) << EVL_CFI_BITS;
   4824      1.22    nonaka 
   4825      1.22    nonaka 		if (ISSET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWTAGGING)) {
   4826      1.22    nonaka 			vlan_set_tag(m, t);
   4827      1.22    nonaka 			rxr->rxr_evvlanhwtagging.ev_count++;
   4828      1.22    nonaka 		} else {
   4829      1.22    nonaka 			struct ether_header eh;
   4830      1.22    nonaka 			struct ether_vlan_header *evl;
   4831      1.22    nonaka 
   4832      1.22    nonaka 			KDASSERT(m->m_pkthdr.len >= sizeof(eh));
   4833      1.22    nonaka 			m_copydata(m, 0, sizeof(eh), &eh);
   4834      1.22    nonaka 			M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_NOWAIT);
   4835      1.22    nonaka 			KDASSERT(m != NULL);
   4836      1.22    nonaka 
   4837      1.22    nonaka 			evl = mtod(m, struct ether_vlan_header *);
   4838  1.27.2.1  perseant 			memcpy(evl, &eh, ETHER_ADDR_LEN * 2);
   4839      1.22    nonaka 			evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
   4840      1.22    nonaka 			evl->evl_tag = htons(t);
   4841      1.22    nonaka 			evl->evl_proto = eh.ether_type;
   4842      1.22    nonaka 		}
   4843      1.22    nonaka 	}
   4844      1.22    nonaka 
   4845      1.22    nonaka 	/* XXX RSS hash is not supported. */
   4846      1.22    nonaka 
   4847       1.1    nonaka  done:
   4848      1.22    nonaka 	rxr->rxr_evpkts.ev_count++;
   4849       1.1    nonaka 	if_percpuq_enqueue(sc->sc_ipq, m);
   4850      1.22    nonaka 	/* XXX Unable to detect that the receive queue is full. */
   4851      1.22    nonaka 	return 1;
   4852       1.1    nonaka }
   4853       1.1    nonaka 
   4854       1.1    nonaka static void
   4855       1.1    nonaka hvn_rndis_complete(struct hvn_softc *sc, uint8_t *buf, uint32_t len)
   4856       1.1    nonaka {
   4857       1.1    nonaka 	struct rndis_cmd *rc;
   4858       1.1    nonaka 	uint32_t id;
   4859       1.1    nonaka 
   4860       1.1    nonaka 	memcpy(&id, buf + RNDIS_HEADER_OFFSET, sizeof(id));
   4861       1.1    nonaka 	if ((rc = hvn_complete_cmd(sc, id)) != NULL) {
   4862      1.22    nonaka 		mutex_enter(&rc->rc_lock);
   4863       1.1    nonaka 		if (len < rc->rc_cmplen)
   4864       1.1    nonaka 			device_printf(sc->sc_dev,
   4865       1.1    nonaka 			    "RNDIS response %u too short: %u\n", id, len);
   4866       1.1    nonaka 		else
   4867       1.1    nonaka 			memcpy(&rc->rc_cmp, buf, rc->rc_cmplen);
   4868       1.1    nonaka 		if (len > rc->rc_cmplen &&
   4869       1.1    nonaka 		    len - rc->rc_cmplen > HVN_RNDIS_BUFSIZE)
   4870       1.1    nonaka 			device_printf(sc->sc_dev,
   4871       1.1    nonaka 			    "RNDIS response %u too large: %u\n", id, len);
   4872       1.1    nonaka 		else if (len > rc->rc_cmplen)
   4873       1.1    nonaka 			memcpy(&rc->rc_cmpbuf, buf + rc->rc_cmplen,
   4874       1.1    nonaka 			    len - rc->rc_cmplen);
   4875       1.1    nonaka 		rc->rc_done = 1;
   4876      1.22    nonaka 		cv_signal(&rc->rc_cv);
   4877      1.22    nonaka 		mutex_exit(&rc->rc_lock);
   4878       1.1    nonaka 	} else {
   4879       1.1    nonaka 		DPRINTF("%s: failed to complete RNDIS request id %u\n",
   4880       1.1    nonaka 		    device_xname(sc->sc_dev), id);
   4881       1.1    nonaka 	}
   4882       1.1    nonaka }
   4883       1.1    nonaka 
   4884       1.1    nonaka static int
   4885      1.22    nonaka hvn_rndis_output_sgl(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd)
   4886       1.1    nonaka {
   4887      1.22    nonaka 	struct hvn_softc *sc = txr->txr_softc;
   4888       1.1    nonaka 	uint64_t rid = (uint64_t)txd->txd_id << 32;
   4889       1.1    nonaka 	int rv;
   4890       1.1    nonaka 
   4891      1.22    nonaka 	rv = vmbus_channel_send_sgl(txr->txr_chan, txd->txd_sgl, txd->txd_nsge,
   4892       1.1    nonaka 	    &sc->sc_data_msg, sizeof(sc->sc_data_msg), rid);
   4893       1.1    nonaka 	if (rv) {
   4894       1.1    nonaka 		DPRINTF("%s: RNDIS data send error %d\n",
   4895       1.1    nonaka 		    device_xname(sc->sc_dev), rv);
   4896       1.1    nonaka 		return rv;
   4897       1.1    nonaka 	}
   4898       1.1    nonaka 	return 0;
   4899       1.1    nonaka }
   4900       1.1    nonaka 
   4901      1.22    nonaka static int
   4902      1.22    nonaka hvn_rndis_output_chim(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd)
   4903      1.22    nonaka {
   4904      1.22    nonaka 	struct hvn_nvs_rndis rndis;
   4905      1.22    nonaka 	uint64_t rid = (uint64_t)txd->txd_id << 32;
   4906      1.22    nonaka 	int rv;
   4907      1.22    nonaka 
   4908      1.22    nonaka 	memset(&rndis, 0, sizeof(rndis));
   4909      1.22    nonaka 	rndis.nvs_type = HVN_NVS_TYPE_RNDIS;
   4910      1.22    nonaka 	rndis.nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_DATA;
   4911      1.22    nonaka 	rndis.nvs_chim_idx = txd->txd_chim_index;
   4912      1.22    nonaka 	rndis.nvs_chim_sz = txd->txd_chim_size;
   4913      1.22    nonaka 
   4914      1.22    nonaka 	rv = vmbus_channel_send(txr->txr_chan, &rndis, sizeof(rndis),
   4915      1.22    nonaka 	    rid, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC);
   4916      1.22    nonaka 	if (rv) {
   4917      1.22    nonaka 		DPRINTF("%s: RNDIS chimney data send error %d: idx %u, sz %u\n",
   4918      1.22    nonaka 		    device_xname(sc->sc_dev), rv, rndis.nvs_chim_idx,
   4919      1.22    nonaka 		    rndis.nvs_chim_sz);
   4920      1.22    nonaka 		return rv;
   4921      1.22    nonaka 	}
   4922      1.22    nonaka 	return 0;
   4923      1.22    nonaka }
   4924      1.22    nonaka 
   4925       1.1    nonaka static void
   4926       1.1    nonaka hvn_rndis_status(struct hvn_softc *sc, uint8_t *buf, uint32_t len)
   4927       1.1    nonaka {
   4928       1.1    nonaka 	uint32_t status;
   4929       1.1    nonaka 
   4930       1.1    nonaka 	memcpy(&status, buf + RNDIS_HEADER_OFFSET, sizeof(status));
   4931       1.1    nonaka 	switch (status) {
   4932       1.1    nonaka 	case RNDIS_STATUS_MEDIA_CONNECT:
   4933      1.22    nonaka 	case RNDIS_STATUS_MEDIA_DISCONNECT:
   4934      1.22    nonaka 		hvn_link_event(sc, HVN_LINK_EV_STATE_CHANGE);
   4935       1.1    nonaka 		break;
   4936      1.22    nonaka 	case RNDIS_STATUS_NETWORK_CHANGE:
   4937      1.22    nonaka 		hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE);
   4938       1.1    nonaka 		break;
   4939       1.1    nonaka 	/* Ignore these */
   4940       1.1    nonaka 	case RNDIS_STATUS_OFFLOAD_CURRENT_CONFIG:
   4941      1.22    nonaka 	case RNDIS_STATUS_LINK_SPEED_CHANGE:
   4942       1.1    nonaka 		return;
   4943       1.1    nonaka 	default:
   4944       1.1    nonaka 		DPRINTF("%s: unhandled status %#x\n", device_xname(sc->sc_dev),
   4945       1.1    nonaka 		    status);
   4946       1.1    nonaka 		return;
   4947       1.1    nonaka 	}
   4948       1.1    nonaka }
   4949       1.1    nonaka 
   4950       1.1    nonaka static int
   4951       1.1    nonaka hvn_rndis_query(struct hvn_softc *sc, uint32_t oid, void *res, size_t *length)
   4952       1.1    nonaka {
   4953      1.22    nonaka 
   4954      1.22    nonaka 	return hvn_rndis_query2(sc, oid, NULL, 0, res, length, 0);
   4955      1.22    nonaka }
   4956      1.22    nonaka 
   4957      1.22    nonaka static int
   4958      1.22    nonaka hvn_rndis_query2(struct hvn_softc *sc, uint32_t oid, const void *idata,
   4959      1.22    nonaka     size_t idlen, void *odata, size_t *odlen, size_t min_odlen)
   4960      1.22    nonaka {
   4961       1.1    nonaka 	struct rndis_cmd *rc;
   4962       1.1    nonaka 	struct rndis_query_req *req;
   4963       1.1    nonaka 	struct rndis_query_comp *cmp;
   4964      1.22    nonaka 	size_t olength = *odlen;
   4965       1.1    nonaka 	int rv;
   4966       1.1    nonaka 
   4967       1.1    nonaka 	rc = hvn_alloc_cmd(sc);
   4968       1.1    nonaka 
   4969       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4970       1.1    nonaka 	    BUS_DMASYNC_PREREAD);
   4971       1.1    nonaka 
   4972       1.1    nonaka 	rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid);
   4973       1.1    nonaka 
   4974       1.1    nonaka 	req = rc->rc_req;
   4975       1.1    nonaka 	req->rm_type = REMOTE_NDIS_QUERY_MSG;
   4976      1.22    nonaka 	req->rm_len = sizeof(*req) + idlen;
   4977       1.1    nonaka 	req->rm_rid = rc->rc_id;
   4978       1.1    nonaka 	req->rm_oid = oid;
   4979       1.1    nonaka 	req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET;
   4980      1.22    nonaka 	if (idlen > 0) {
   4981      1.22    nonaka 		KASSERT(sizeof(*req) + idlen <= PAGE_SIZE);
   4982      1.22    nonaka 		req->rm_infobuflen = idlen;
   4983      1.22    nonaka 		memcpy(req + 1, idata, idlen);
   4984      1.22    nonaka 	}
   4985       1.1    nonaka 
   4986       1.1    nonaka 	rc->rc_cmplen = sizeof(*cmp);
   4987       1.1    nonaka 
   4988       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   4989       1.1    nonaka 	    BUS_DMASYNC_PREWRITE);
   4990       1.1    nonaka 
   4991      1.22    nonaka 	if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) {
   4992       1.1    nonaka 		DPRINTF("%s: QUERY_MSG failed, error %d\n",
   4993       1.1    nonaka 		    device_xname(sc->sc_dev), rv);
   4994       1.1    nonaka 		hvn_free_cmd(sc, rc);
   4995       1.1    nonaka 		return rv;
   4996       1.1    nonaka 	}
   4997       1.1    nonaka 
   4998       1.1    nonaka 	cmp = (struct rndis_query_comp *)&rc->rc_cmp;
   4999       1.1    nonaka 	switch (cmp->rm_status) {
   5000       1.1    nonaka 	case RNDIS_STATUS_SUCCESS:
   5001      1.22    nonaka 		if (cmp->rm_infobuflen > olength ||
   5002      1.22    nonaka 		    (min_odlen > 0 && cmp->rm_infobuflen < min_odlen)) {
   5003       1.1    nonaka 			rv = EINVAL;
   5004       1.1    nonaka 			break;
   5005       1.1    nonaka 		}
   5006      1.22    nonaka 		memcpy(odata, rc->rc_cmpbuf, cmp->rm_infobuflen);
   5007      1.22    nonaka 		*odlen = cmp->rm_infobuflen;
   5008       1.1    nonaka 		break;
   5009       1.1    nonaka 	default:
   5010      1.22    nonaka 		*odlen = 0;
   5011       1.1    nonaka 		rv = EIO;
   5012       1.1    nonaka 		break;
   5013       1.1    nonaka 	}
   5014       1.1    nonaka 
   5015       1.1    nonaka 	hvn_free_cmd(sc, rc);
   5016       1.1    nonaka 	return rv;
   5017       1.1    nonaka }
   5018       1.1    nonaka 
   5019       1.1    nonaka static int
   5020       1.1    nonaka hvn_rndis_set(struct hvn_softc *sc, uint32_t oid, void *data, size_t length)
   5021       1.1    nonaka {
   5022       1.1    nonaka 	struct rndis_cmd *rc;
   5023       1.1    nonaka 	struct rndis_set_req *req;
   5024       1.1    nonaka 	struct rndis_set_comp *cmp;
   5025       1.1    nonaka 	int rv;
   5026       1.1    nonaka 
   5027       1.1    nonaka 	rc = hvn_alloc_cmd(sc);
   5028       1.1    nonaka 
   5029       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   5030       1.1    nonaka 	    BUS_DMASYNC_PREREAD);
   5031       1.1    nonaka 
   5032       1.1    nonaka 	rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid);
   5033       1.1    nonaka 
   5034       1.1    nonaka 	req = rc->rc_req;
   5035       1.1    nonaka 	req->rm_type = REMOTE_NDIS_SET_MSG;
   5036       1.1    nonaka 	req->rm_len = sizeof(*req) + length;
   5037       1.1    nonaka 	req->rm_rid = rc->rc_id;
   5038       1.1    nonaka 	req->rm_oid = oid;
   5039       1.1    nonaka 	req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET;
   5040       1.1    nonaka 
   5041       1.1    nonaka 	rc->rc_cmplen = sizeof(*cmp);
   5042       1.1    nonaka 
   5043       1.1    nonaka 	if (length > 0) {
   5044       1.1    nonaka 		KASSERT(sizeof(*req) + length < PAGE_SIZE);
   5045       1.1    nonaka 		req->rm_infobuflen = length;
   5046       1.1    nonaka 		memcpy(req + 1, data, length);
   5047       1.1    nonaka 	}
   5048       1.1    nonaka 
   5049       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   5050       1.1    nonaka 	    BUS_DMASYNC_PREWRITE);
   5051       1.1    nonaka 
   5052      1.22    nonaka 	if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) {
   5053       1.1    nonaka 		DPRINTF("%s: SET_MSG failed, error %d\n",
   5054       1.1    nonaka 		    device_xname(sc->sc_dev), rv);
   5055       1.1    nonaka 		hvn_free_cmd(sc, rc);
   5056       1.1    nonaka 		return rv;
   5057       1.1    nonaka 	}
   5058       1.1    nonaka 
   5059       1.1    nonaka 	cmp = (struct rndis_set_comp *)&rc->rc_cmp;
   5060       1.1    nonaka 	if (cmp->rm_status != RNDIS_STATUS_SUCCESS)
   5061       1.1    nonaka 		rv = EIO;
   5062       1.1    nonaka 
   5063       1.1    nonaka 	hvn_free_cmd(sc, rc);
   5064       1.1    nonaka 	return rv;
   5065       1.1    nonaka }
   5066       1.1    nonaka 
   5067       1.1    nonaka static int
   5068       1.1    nonaka hvn_rndis_open(struct hvn_softc *sc)
   5069       1.1    nonaka {
   5070      1.22    nonaka 	struct ifnet *ifp = SC2IFP(sc);
   5071       1.1    nonaka 	uint32_t filter;
   5072       1.1    nonaka 	int rv;
   5073       1.1    nonaka 
   5074      1.22    nonaka 	if (ifp->if_flags & IFF_PROMISC) {
   5075       1.1    nonaka 		filter = RNDIS_PACKET_TYPE_PROMISCUOUS;
   5076      1.22    nonaka 	} else {
   5077      1.22    nonaka 		filter = RNDIS_PACKET_TYPE_DIRECTED;
   5078      1.22    nonaka 		if (ifp->if_flags & IFF_BROADCAST)
   5079      1.22    nonaka 			filter |= RNDIS_PACKET_TYPE_BROADCAST;
   5080      1.22    nonaka 		if (ifp->if_flags & IFF_ALLMULTI)
   5081      1.22    nonaka 			filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
   5082      1.22    nonaka 		else {
   5083      1.22    nonaka 			struct ethercom *ec = &sc->sc_ec;
   5084      1.22    nonaka 			struct ether_multi *enm;
   5085      1.22    nonaka 			struct ether_multistep step;
   5086      1.22    nonaka 
   5087      1.22    nonaka 			ETHER_LOCK(ec);
   5088      1.22    nonaka 			ETHER_FIRST_MULTI(step, ec, enm);
   5089      1.22    nonaka 			/* TODO: support multicast list */
   5090      1.22    nonaka 			if (enm != NULL)
   5091      1.22    nonaka 				filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
   5092      1.22    nonaka 			ETHER_UNLOCK(ec);
   5093      1.22    nonaka 		}
   5094      1.22    nonaka 	}
   5095       1.1    nonaka 
   5096       1.1    nonaka 	rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
   5097       1.1    nonaka 	    &filter, sizeof(filter));
   5098       1.1    nonaka 	if (rv) {
   5099       1.1    nonaka 		DPRINTF("%s: failed to set RNDIS filter to %#x\n",
   5100       1.1    nonaka 		    device_xname(sc->sc_dev), filter);
   5101       1.1    nonaka 	}
   5102       1.1    nonaka 	return rv;
   5103       1.1    nonaka }
   5104       1.1    nonaka 
   5105       1.1    nonaka static int
   5106       1.1    nonaka hvn_rndis_close(struct hvn_softc *sc)
   5107       1.1    nonaka {
   5108       1.1    nonaka 	uint32_t filter = 0;
   5109       1.1    nonaka 	int rv;
   5110       1.1    nonaka 
   5111       1.1    nonaka 	rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
   5112       1.1    nonaka 	    &filter, sizeof(filter));
   5113       1.1    nonaka 	if (rv) {
   5114       1.1    nonaka 		DPRINTF("%s: failed to clear RNDIS filter\n",
   5115       1.1    nonaka 		    device_xname(sc->sc_dev));
   5116       1.1    nonaka 	}
   5117       1.1    nonaka 	return rv;
   5118       1.1    nonaka }
   5119       1.1    nonaka 
   5120       1.1    nonaka static void
   5121       1.1    nonaka hvn_rndis_detach(struct hvn_softc *sc)
   5122       1.1    nonaka {
   5123       1.1    nonaka 	struct rndis_cmd *rc;
   5124       1.1    nonaka 	struct rndis_halt_req *req;
   5125       1.1    nonaka 	int rv;
   5126       1.1    nonaka 
   5127       1.1    nonaka 	rc = hvn_alloc_cmd(sc);
   5128       1.1    nonaka 
   5129       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   5130       1.1    nonaka 	    BUS_DMASYNC_PREREAD);
   5131       1.1    nonaka 
   5132       1.1    nonaka 	rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid);
   5133       1.1    nonaka 
   5134       1.1    nonaka 	req = rc->rc_req;
   5135       1.1    nonaka 	req->rm_type = REMOTE_NDIS_HALT_MSG;
   5136       1.1    nonaka 	req->rm_len = sizeof(*req);
   5137       1.1    nonaka 	req->rm_rid = rc->rc_id;
   5138       1.1    nonaka 
   5139       1.1    nonaka 	bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE,
   5140       1.1    nonaka 	    BUS_DMASYNC_PREWRITE);
   5141       1.1    nonaka 
   5142      1.22    nonaka 	/* No RNDIS completion; rely on NVS message send completion */
   5143      1.22    nonaka 	if ((rv = hvn_rndis_cmd(sc, rc, HVN_RNDIS_CMD_NORESP)) != 0) {
   5144       1.1    nonaka 		DPRINTF("%s: HALT_MSG failed, error %d\n",
   5145       1.1    nonaka 		    device_xname(sc->sc_dev), rv);
   5146       1.1    nonaka 	}
   5147       1.1    nonaka 	hvn_free_cmd(sc, rc);
   5148      1.22    nonaka }
   5149      1.22    nonaka 
   5150      1.22    nonaka static void
   5151      1.22    nonaka hvn_init_sysctls(struct hvn_softc *sc)
   5152      1.22    nonaka {
   5153      1.22    nonaka 	struct sysctllog **log;
   5154      1.22    nonaka 	const struct sysctlnode *rnode, *cnode, *rxnode, *txnode;
   5155      1.22    nonaka 	const char *dvname;
   5156      1.22    nonaka 	int error;
   5157      1.22    nonaka 
   5158      1.22    nonaka 	log = &sc->sc_sysctllog;
   5159      1.22    nonaka 	dvname = device_xname(sc->sc_dev);
   5160      1.22    nonaka 
   5161      1.22    nonaka 	error = sysctl_createv(log, 0, NULL, &rnode,
   5162      1.22    nonaka 	    0, CTLTYPE_NODE, dvname,
   5163      1.22    nonaka 	    SYSCTL_DESCR("hvn information and settings"),
   5164      1.22    nonaka 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
   5165      1.22    nonaka 	if (error)
   5166      1.22    nonaka 		goto err;
   5167      1.22    nonaka 
   5168      1.22    nonaka 	error = sysctl_createv(log, 0, &rnode, &cnode,
   5169      1.22    nonaka 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue",
   5170      1.22    nonaka 	    SYSCTL_DESCR("Use workqueue for packet processing"),
   5171      1.22    nonaka 	    NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL);
   5172      1.22    nonaka 	if (error)
   5173      1.22    nonaka 		goto out;
   5174      1.22    nonaka 
   5175      1.22    nonaka 	error = sysctl_createv(log, 0, &rnode, &rxnode,
   5176      1.22    nonaka 	    0, CTLTYPE_NODE, "rx",
   5177      1.22    nonaka 	    SYSCTL_DESCR("hvn information and settings for Rx"),
   5178      1.22    nonaka 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   5179      1.22    nonaka 	if (error)
   5180      1.22    nonaka 		goto out;
   5181      1.13    nonaka 
   5182      1.22    nonaka 	error = sysctl_createv(log, 0, &rxnode, NULL,
   5183      1.22    nonaka 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   5184      1.22    nonaka 	    SYSCTL_DESCR("max number of Rx packets"
   5185      1.22    nonaka 	      " to process for interrupt processing"),
   5186      1.22    nonaka 	    NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   5187      1.22    nonaka 	if (error)
   5188      1.22    nonaka 		goto out;
   5189      1.22    nonaka 
   5190      1.22    nonaka 	error = sysctl_createv(log, 0, &rxnode, NULL,
   5191      1.22    nonaka 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   5192      1.22    nonaka 	    SYSCTL_DESCR("max number of Rx packets"
   5193      1.22    nonaka 	      " to process for deferred processing"),
   5194      1.22    nonaka 	    NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL);
   5195      1.22    nonaka 	if (error)
   5196      1.22    nonaka 		goto out;
   5197      1.22    nonaka 
   5198      1.22    nonaka 	error = sysctl_createv(log, 0, &rnode, &txnode,
   5199      1.22    nonaka 	    0, CTLTYPE_NODE, "tx",
   5200      1.22    nonaka 	    SYSCTL_DESCR("hvn information and settings for Tx"),
   5201      1.22    nonaka 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   5202      1.22    nonaka 	if (error)
   5203      1.22    nonaka 		goto out;
   5204      1.22    nonaka 
   5205      1.22    nonaka 	error = sysctl_createv(log, 0, &txnode, NULL,
   5206      1.22    nonaka 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   5207      1.22    nonaka 	    SYSCTL_DESCR("max number of Tx packets"
   5208      1.22    nonaka 	      " to process for interrupt processing"),
   5209      1.22    nonaka 	    NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   5210      1.22    nonaka 	if (error)
   5211      1.22    nonaka 		goto out;
   5212      1.22    nonaka 
   5213      1.22    nonaka 	error = sysctl_createv(log, 0, &txnode, NULL,
   5214      1.22    nonaka 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   5215      1.22    nonaka 	    SYSCTL_DESCR("max number of Tx packets"
   5216      1.22    nonaka 	      " to process for deferred processing"),
   5217      1.22    nonaka 	    NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL);
   5218      1.22    nonaka 	if (error)
   5219      1.22    nonaka 		goto out;
   5220      1.22    nonaka 
   5221      1.22    nonaka 	return;
   5222      1.22    nonaka 
   5223      1.22    nonaka out:
   5224      1.22    nonaka 	sysctl_teardown(log);
   5225      1.22    nonaka 	sc->sc_sysctllog = NULL;
   5226      1.22    nonaka err:
   5227      1.22    nonaka 	aprint_error_dev(sc->sc_dev, "sysctl_createv failed (err = %d)\n",
   5228      1.22    nonaka 	    error);
   5229      1.22    nonaka }
   5230      1.22    nonaka 
   5231      1.22    nonaka SYSCTL_SETUP(sysctl_hw_hvn_setup, "sysctl hw.hvn setup")
   5232      1.22    nonaka {
   5233      1.22    nonaka 	const struct sysctlnode *rnode;
   5234      1.22    nonaka 	const struct sysctlnode *cnode;
   5235      1.22    nonaka 	int error;
   5236      1.22    nonaka 
   5237      1.22    nonaka 	error = sysctl_createv(clog, 0, NULL, &rnode,
   5238      1.22    nonaka 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hvn",
   5239      1.22    nonaka 	    SYSCTL_DESCR("hvn global controls"),
   5240      1.22    nonaka 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
   5241      1.22    nonaka 	if (error)
   5242      1.22    nonaka 		goto fail;
   5243      1.22    nonaka 
   5244      1.22    nonaka 	error = sysctl_createv(clog, 0, &rnode, &cnode,
   5245      1.22    nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   5246      1.22    nonaka 	    "udp_csum_fixup_mtu",
   5247      1.22    nonaka 	    SYSCTL_DESCR("UDP checksum offloding fixup MTU"),
   5248      1.22    nonaka 	    NULL, 0, &hvn_udpcs_fixup_mtu, sizeof(hvn_udpcs_fixup_mtu),
   5249      1.22    nonaka 	    CTL_CREATE, CTL_EOL);
   5250      1.22    nonaka 	if (error)
   5251      1.22    nonaka 		goto fail;
   5252      1.22    nonaka 
   5253      1.22    nonaka 	error = sysctl_createv(clog, 0, &rnode, &cnode,
   5254      1.22    nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   5255      1.22    nonaka 	    "chimney_size",
   5256      1.22    nonaka 	    SYSCTL_DESCR("Chimney send packet size limit"),
   5257      1.22    nonaka 	    NULL, 0, &hvn_tx_chimney_size, sizeof(hvn_tx_chimney_size),
   5258      1.22    nonaka 	    CTL_CREATE, CTL_EOL);
   5259      1.22    nonaka 	if (error)
   5260      1.22    nonaka 		goto fail;
   5261      1.22    nonaka 
   5262      1.22    nonaka 	error = sysctl_createv(clog, 0, &rnode, &cnode,
   5263      1.22    nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   5264      1.22    nonaka 	    "channel_count",
   5265      1.22    nonaka 	    SYSCTL_DESCR("# of channels to use"),
   5266      1.22    nonaka 	    NULL, 0, &hvn_channel_cnt, sizeof(hvn_channel_cnt),
   5267      1.22    nonaka 	    CTL_CREATE, CTL_EOL);
   5268      1.22    nonaka 	if (error)
   5269      1.22    nonaka 		goto fail;
   5270      1.22    nonaka 
   5271      1.22    nonaka 	error = sysctl_createv(clog, 0, &rnode, &cnode,
   5272      1.22    nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   5273      1.22    nonaka 	    "tx_ring_count",
   5274      1.22    nonaka 	    SYSCTL_DESCR("# of transmit rings to use"),
   5275      1.22    nonaka 	    NULL, 0, &hvn_tx_ring_cnt, sizeof(hvn_tx_ring_cnt),
   5276      1.22    nonaka 	    CTL_CREATE, CTL_EOL);
   5277      1.22    nonaka 	if (error)
   5278      1.22    nonaka 		goto fail;
   5279      1.22    nonaka 
   5280      1.22    nonaka 	return;
   5281      1.22    nonaka 
   5282      1.22    nonaka fail:
   5283      1.22    nonaka 	aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, error);
   5284       1.1    nonaka }
   5285