Home | History | Annotate | Line # | Download | only in hyperv
      1  1.30       joe /*	$NetBSD: if_hvn.c,v 1.30 2025/02/17 23:28:48 joe 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.30       joe __KERNEL_RCSID(0, "$NetBSD: if_hvn.c,v 1.30 2025/02/17 23:28:48 joe 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.30       joe 	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.28       rin 	m_freem(txd->txd_buf);
   2288  1.28       rin 	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.30       joe 			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