Home | History | Annotate | Line # | Download | only in pci
if_iavf.c revision 1.2
      1  1.2  jakllsch /*	$NetBSD: if_iavf.c,v 1.2 2020/09/08 13:28:51 jakllsch Exp $	*/
      2  1.1  yamaguch 
      3  1.1  yamaguch /*
      4  1.1  yamaguch  * Copyright (c) 2013-2015, Intel Corporation
      5  1.1  yamaguch  * All rights reserved.
      6  1.1  yamaguch 
      7  1.1  yamaguch  * Redistribution and use in source and binary forms, with or without
      8  1.1  yamaguch  * modification, are permitted provided that the following conditions are met:
      9  1.1  yamaguch  *
     10  1.1  yamaguch  *  1. Redistributions of source code must retain the above copyright notice,
     11  1.1  yamaguch  *     this list of conditions and the following disclaimer.
     12  1.1  yamaguch  *
     13  1.1  yamaguch  *  2. Redistributions in binary form must reproduce the above copyright
     14  1.1  yamaguch  *     notice, this list of conditions and the following disclaimer in the
     15  1.1  yamaguch  *     documentation and/or other materials provided with the distribution.
     16  1.1  yamaguch  *
     17  1.1  yamaguch  *  3. Neither the name of the Intel Corporation nor the names of its
     18  1.1  yamaguch  *     contributors may be used to endorse or promote products derived from
     19  1.1  yamaguch  *     this software without specific prior written permission.
     20  1.1  yamaguch  *
     21  1.1  yamaguch  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     22  1.1  yamaguch  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1  yamaguch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1  yamaguch  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     25  1.1  yamaguch  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26  1.1  yamaguch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27  1.1  yamaguch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28  1.1  yamaguch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29  1.1  yamaguch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30  1.1  yamaguch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31  1.1  yamaguch  * POSSIBILITY OF SUCH DAMAGE.
     32  1.1  yamaguch  */
     33  1.1  yamaguch 
     34  1.1  yamaguch /*
     35  1.1  yamaguch  * Copyright (c) 2016,2017 David Gwynne <dlg (at) openbsd.org>
     36  1.1  yamaguch  * Copyright (c) 2019 Jonathan Matthew <jmatthew (at) openbsd.org>
     37  1.1  yamaguch  *
     38  1.1  yamaguch  * Permission to use, copy, modify, and distribute this software for any
     39  1.1  yamaguch  * purpose with or without fee is hereby granted, provided that the above
     40  1.1  yamaguch  * copyright notice and this permission notice appear in all copies.
     41  1.1  yamaguch  *
     42  1.1  yamaguch  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     43  1.1  yamaguch  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     44  1.1  yamaguch  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     45  1.1  yamaguch  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     46  1.1  yamaguch  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     47  1.1  yamaguch  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     48  1.1  yamaguch  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     49  1.1  yamaguch  */
     50  1.1  yamaguch 
     51  1.1  yamaguch /*
     52  1.1  yamaguch  * Copyright (c) 2020 Internet Initiative Japan, Inc.
     53  1.1  yamaguch  * All rights reserved.
     54  1.1  yamaguch  *
     55  1.1  yamaguch  * Redistribution and use in source and binary forms, with or without
     56  1.1  yamaguch  * modification, are permitted provided that the following conditions
     57  1.1  yamaguch  * are met:
     58  1.1  yamaguch  * 1. Redistributions of source code must retain the above copyright
     59  1.1  yamaguch  *    notice, this list of conditions and the following disclaimer.
     60  1.1  yamaguch  * 2. Redistributions in binary form must reproduce the above copyright
     61  1.1  yamaguch  *    notice, this list of conditions and the following disclaimer in the
     62  1.1  yamaguch  *    documentation and/or other materials provided with the distribution.
     63  1.1  yamaguch  *
     64  1.1  yamaguch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     65  1.1  yamaguch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     66  1.1  yamaguch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     67  1.1  yamaguch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     68  1.1  yamaguch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     69  1.1  yamaguch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     70  1.1  yamaguch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     71  1.1  yamaguch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     72  1.1  yamaguch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     73  1.1  yamaguch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     74  1.1  yamaguch  * POSSIBILITY OF SUCH DAMAGE.
     75  1.1  yamaguch  */
     76  1.1  yamaguch 
     77  1.1  yamaguch #include <sys/cdefs.h>
     78  1.2  jakllsch __KERNEL_RCSID(0, "$NetBSD: if_iavf.c,v 1.2 2020/09/08 13:28:51 jakllsch Exp $");
     79  1.1  yamaguch 
     80  1.1  yamaguch #include <sys/param.h>
     81  1.1  yamaguch #include <sys/types.h>
     82  1.1  yamaguch 
     83  1.1  yamaguch #include <sys/bitops.h>
     84  1.1  yamaguch #include <sys/bus.h>
     85  1.1  yamaguch #include <sys/cprng.h>
     86  1.1  yamaguch #include <sys/cpu.h>
     87  1.1  yamaguch #include <sys/device.h>
     88  1.1  yamaguch #include <sys/evcnt.h>
     89  1.1  yamaguch #include <sys/interrupt.h>
     90  1.1  yamaguch #include <sys/kmem.h>
     91  1.1  yamaguch #include <sys/module.h>
     92  1.1  yamaguch #include <sys/mutex.h>
     93  1.1  yamaguch #include <sys/pcq.h>
     94  1.1  yamaguch #include <sys/queue.h>
     95  1.1  yamaguch #include <sys/syslog.h>
     96  1.1  yamaguch #include <sys/workqueue.h>
     97  1.1  yamaguch 
     98  1.1  yamaguch #include <net/bpf.h>
     99  1.1  yamaguch #include <net/if.h>
    100  1.1  yamaguch #include <net/if_dl.h>
    101  1.1  yamaguch #include <net/if_media.h>
    102  1.1  yamaguch #include <net/if_ether.h>
    103  1.1  yamaguch #include <net/rss_config.h>
    104  1.1  yamaguch 
    105  1.1  yamaguch #include <netinet/tcp.h>	/* for struct tcphdr */
    106  1.1  yamaguch #include <netinet/udp.h>	/* for struct udphdr */
    107  1.1  yamaguch 
    108  1.1  yamaguch #include <dev/pci/pcivar.h>
    109  1.1  yamaguch #include <dev/pci/pcidevs.h>
    110  1.1  yamaguch 
    111  1.1  yamaguch #include <dev/pci/if_ixlreg.h>
    112  1.1  yamaguch #include <dev/pci/if_ixlvar.h>
    113  1.1  yamaguch #include <dev/pci/if_iavfvar.h>
    114  1.1  yamaguch 
    115  1.1  yamaguch #include <prop/proplib.h>
    116  1.1  yamaguch 
    117  1.1  yamaguch #define IAVF_PCIREG		PCI_MAPREG_START
    118  1.1  yamaguch #define IAVF_AQ_NUM		256
    119  1.1  yamaguch #define IAVF_AQ_MASK		(IAVF_AQ_NUM-1)
    120  1.1  yamaguch #define IAVF_AQ_ALIGN		64
    121  1.1  yamaguch #define IAVF_AQ_BUFLEN		4096
    122  1.1  yamaguch #define I40E_AQ_LARGE_BUF	512
    123  1.1  yamaguch #define IAVF_VF_MAJOR		1
    124  1.1  yamaguch #define IAVF_VF_MINOR		1
    125  1.1  yamaguch 
    126  1.1  yamaguch #define IAVF_VFR_INPROGRESS	0
    127  1.1  yamaguch #define IAVF_VFR_COMPLETED	1
    128  1.1  yamaguch #define IAVF_VFR_VFACTIVE	2
    129  1.1  yamaguch 
    130  1.1  yamaguch #define IAVF_REG_VFR			0xdeadbeef
    131  1.1  yamaguch 
    132  1.1  yamaguch #define IAVF_ITR_RX			0x0
    133  1.1  yamaguch #define IAVF_ITR_TX			0x1
    134  1.1  yamaguch #define IAVF_ITR_MISC			0x2
    135  1.1  yamaguch #define IAVF_NOITR			0x3
    136  1.1  yamaguch 
    137  1.1  yamaguch #define IAVF_MTU_ETHERLEN		(ETHER_HDR_LEN \
    138  1.1  yamaguch 					+ ETHER_CRC_LEN)
    139  1.1  yamaguch #define IAVF_MAX_MTU			(9600 - IAVF_MTU_ETHERLEN)
    140  1.1  yamaguch #define IAVF_MIN_MTU			(ETHER_MIN_LEN - ETHER_CRC_LEN)
    141  1.1  yamaguch 
    142  1.1  yamaguch #define IAVF_WORKQUEUE_PRI	PRI_SOFTNET
    143  1.1  yamaguch 
    144  1.1  yamaguch #define IAVF_TX_PKT_DESCS		8
    145  1.1  yamaguch #define IAVF_TX_QUEUE_ALIGN		128
    146  1.1  yamaguch #define IAVF_RX_QUEUE_ALIGN		128
    147  1.1  yamaguch #define IAVF_TX_PKT_MAXSIZE		(MCLBYTES * IAVF_TX_PKT_DESCS)
    148  1.1  yamaguch #define IAVF_MCLBYTES			(MCLBYTES - ETHER_ALIGN)
    149  1.1  yamaguch 
    150  1.1  yamaguch #define IAVF_TICK_INTERVAL		(5 * hz)
    151  1.1  yamaguch #define IAVF_WATCHDOG_TICKS		3
    152  1.1  yamaguch #define IAVF_WATCHDOG_STOP		0
    153  1.1  yamaguch 
    154  1.1  yamaguch #define IAVF_TXRX_PROCESS_UNLIMIT	UINT_MAX
    155  1.1  yamaguch #define IAVF_TX_PROCESS_LIMIT		256
    156  1.1  yamaguch #define IAVF_RX_PROCESS_LIMIT		256
    157  1.1  yamaguch #define IAVF_TX_INTR_PROCESS_LIMIT	256
    158  1.1  yamaguch #define IAVF_RX_INTR_PROCESS_LIMIT	0U
    159  1.1  yamaguch 
    160  1.1  yamaguch #define IAVF_EXEC_TIMEOUT		3000
    161  1.1  yamaguch 
    162  1.1  yamaguch #define IAVF_IFCAP_RXCSUM	(IFCAP_CSUM_IPv4_Rx |	\
    163  1.1  yamaguch 				 IFCAP_CSUM_TCPv4_Rx |	\
    164  1.1  yamaguch 				 IFCAP_CSUM_UDPv4_Rx |	\
    165  1.1  yamaguch 				 IFCAP_CSUM_TCPv6_Rx |	\
    166  1.1  yamaguch 				 IFCAP_CSUM_UDPv6_Rx)
    167  1.1  yamaguch #define IAVF_IFCAP_TXCSUM	(IFCAP_CSUM_IPv4_Tx |	\
    168  1.1  yamaguch 				 IFCAP_CSUM_TCPv4_Tx |	\
    169  1.1  yamaguch 				 IFCAP_CSUM_UDPv4_Tx |	\
    170  1.1  yamaguch 				 IFCAP_CSUM_TCPv6_Tx |	\
    171  1.1  yamaguch 				 IFCAP_CSUM_UDPv6_Tx)
    172  1.1  yamaguch #define IAVF_CSUM_ALL_OFFLOAD	(M_CSUM_IPv4 |			\
    173  1.1  yamaguch 				 M_CSUM_TCPv4 | M_CSUM_TCPv6 |	\
    174  1.1  yamaguch 				 M_CSUM_UDPv4 | M_CSUM_UDPv6)
    175  1.1  yamaguch 
    176  1.1  yamaguch struct iavf_softc;	/* defined */
    177  1.1  yamaguch 
    178  1.1  yamaguch struct iavf_module_params {
    179  1.1  yamaguch 	int		 debug;
    180  1.1  yamaguch 	uint32_t	 rx_itr;
    181  1.1  yamaguch 	uint32_t	 tx_itr;
    182  1.1  yamaguch 	unsigned int	 rx_ndescs;
    183  1.1  yamaguch 	unsigned int	 tx_ndescs;
    184  1.1  yamaguch 	int		 max_qps;
    185  1.1  yamaguch };
    186  1.1  yamaguch 
    187  1.1  yamaguch struct iavf_product {
    188  1.1  yamaguch 	unsigned int	 vendor_id;
    189  1.1  yamaguch 	unsigned int	 product_id;
    190  1.1  yamaguch };
    191  1.1  yamaguch 
    192  1.1  yamaguch struct iavf_link_speed {
    193  1.1  yamaguch 	uint64_t	baudrate;
    194  1.1  yamaguch 	uint64_t	media;
    195  1.1  yamaguch };
    196  1.1  yamaguch 
    197  1.1  yamaguch struct iavf_aq_regs {
    198  1.1  yamaguch 	bus_size_t		atq_tail;
    199  1.1  yamaguch 	bus_size_t		atq_head;
    200  1.1  yamaguch 	bus_size_t		atq_len;
    201  1.1  yamaguch 	bus_size_t		atq_bal;
    202  1.1  yamaguch 	bus_size_t		atq_bah;
    203  1.1  yamaguch 
    204  1.1  yamaguch 	bus_size_t		arq_tail;
    205  1.1  yamaguch 	bus_size_t		arq_head;
    206  1.1  yamaguch 	bus_size_t		arq_len;
    207  1.1  yamaguch 	bus_size_t		arq_bal;
    208  1.1  yamaguch 	bus_size_t		arq_bah;
    209  1.1  yamaguch 
    210  1.1  yamaguch 	uint32_t		atq_len_enable;
    211  1.1  yamaguch 	uint32_t		atq_tail_mask;
    212  1.1  yamaguch 	uint32_t		atq_head_mask;
    213  1.1  yamaguch 
    214  1.1  yamaguch 	uint32_t		arq_len_enable;
    215  1.1  yamaguch 	uint32_t		arq_tail_mask;
    216  1.1  yamaguch 	uint32_t		arq_head_mask;
    217  1.1  yamaguch };
    218  1.1  yamaguch 
    219  1.1  yamaguch struct iavf_work {
    220  1.1  yamaguch 	struct work	 ixw_cookie;
    221  1.1  yamaguch 	void		(*ixw_func)(void *);
    222  1.1  yamaguch 	void		*ixw_arg;
    223  1.1  yamaguch 	unsigned int	 ixw_added;
    224  1.1  yamaguch };
    225  1.1  yamaguch 
    226  1.1  yamaguch struct iavf_tx_map {
    227  1.1  yamaguch 	struct mbuf		*txm_m;
    228  1.1  yamaguch 	bus_dmamap_t		 txm_map;
    229  1.1  yamaguch 	unsigned int		 txm_eop;
    230  1.1  yamaguch };
    231  1.1  yamaguch 
    232  1.1  yamaguch struct iavf_tx_ring {
    233  1.1  yamaguch 	unsigned int		 txr_qid;
    234  1.1  yamaguch 	char			 txr_name[16];
    235  1.1  yamaguch 
    236  1.1  yamaguch 	struct iavf_softc	*txr_sc;
    237  1.1  yamaguch 	kmutex_t		 txr_lock;
    238  1.1  yamaguch 	pcq_t			*txr_intrq;
    239  1.1  yamaguch 	void			*txr_si;
    240  1.1  yamaguch 	unsigned int		 txr_prod;
    241  1.1  yamaguch 	unsigned int		 txr_cons;
    242  1.1  yamaguch 
    243  1.1  yamaguch 	struct iavf_tx_map	*txr_maps;
    244  1.1  yamaguch 	struct ixl_dmamem	 txr_mem;
    245  1.1  yamaguch 	bus_size_t		 txr_tail;
    246  1.1  yamaguch 
    247  1.1  yamaguch 	int			 txr_watchdog;
    248  1.1  yamaguch 
    249  1.1  yamaguch 	struct evcnt		 txr_defragged;
    250  1.1  yamaguch 	struct evcnt		 txr_defrag_failed;
    251  1.1  yamaguch 	struct evcnt		 txr_pcqdrop;
    252  1.1  yamaguch 	struct evcnt		 txr_transmitdef;
    253  1.1  yamaguch 	struct evcnt		 txr_defer;
    254  1.1  yamaguch 	struct evcnt		 txr_watchdogto;
    255  1.1  yamaguch 	struct evcnt		 txr_intr;
    256  1.1  yamaguch };
    257  1.1  yamaguch 
    258  1.1  yamaguch struct iavf_rx_map {
    259  1.1  yamaguch 	struct mbuf		*rxm_m;
    260  1.1  yamaguch 	bus_dmamap_t		 rxm_map;
    261  1.1  yamaguch };
    262  1.1  yamaguch 
    263  1.1  yamaguch struct iavf_rx_ring {
    264  1.1  yamaguch 	unsigned int		 rxr_qid;
    265  1.1  yamaguch 	char			 rxr_name[16];
    266  1.1  yamaguch 
    267  1.1  yamaguch 	struct iavf_softc	*rxr_sc;
    268  1.1  yamaguch 	kmutex_t		 rxr_lock;
    269  1.1  yamaguch 
    270  1.1  yamaguch 	unsigned int		 rxr_prod;
    271  1.1  yamaguch 	unsigned int		 rxr_cons;
    272  1.1  yamaguch 
    273  1.1  yamaguch 	struct iavf_rx_map	*rxr_maps;
    274  1.1  yamaguch 	struct ixl_dmamem	 rxr_mem;
    275  1.1  yamaguch 	bus_size_t		 rxr_tail;
    276  1.1  yamaguch 
    277  1.1  yamaguch 	struct mbuf		*rxr_m_head;
    278  1.1  yamaguch 	struct mbuf		**rxr_m_tail;
    279  1.1  yamaguch 
    280  1.1  yamaguch 	struct evcnt		 rxr_mgethdr_failed;
    281  1.1  yamaguch 	struct evcnt		 rxr_mgetcl_failed;
    282  1.1  yamaguch 	struct evcnt		 rxr_mbuf_load_failed;
    283  1.1  yamaguch 	struct evcnt		 rxr_defer;
    284  1.1  yamaguch 	struct evcnt		 rxr_intr;
    285  1.1  yamaguch };
    286  1.1  yamaguch 
    287  1.1  yamaguch struct iavf_queue_pair {
    288  1.1  yamaguch 	struct iavf_tx_ring	*qp_txr;
    289  1.1  yamaguch 	struct iavf_rx_ring	*qp_rxr;
    290  1.1  yamaguch 	struct work		 qp_work;
    291  1.1  yamaguch 	void			*qp_si;
    292  1.1  yamaguch 	bool			 qp_workqueue;
    293  1.1  yamaguch };
    294  1.1  yamaguch 
    295  1.1  yamaguch struct iavf_stat_counters {
    296  1.1  yamaguch 	struct evcnt	 isc_rx_bytes;
    297  1.1  yamaguch 	struct evcnt	 isc_rx_unicast;
    298  1.1  yamaguch 	struct evcnt	 isc_rx_multicast;
    299  1.1  yamaguch 	struct evcnt	 isc_rx_broadcast;
    300  1.1  yamaguch 	struct evcnt	 isc_rx_discards;
    301  1.1  yamaguch 	struct evcnt	 isc_rx_unknown_protocol;
    302  1.1  yamaguch 	struct evcnt	 isc_tx_bytes;
    303  1.1  yamaguch 	struct evcnt	 isc_tx_unicast;
    304  1.1  yamaguch 	struct evcnt	 isc_tx_multicast;
    305  1.1  yamaguch 	struct evcnt	 isc_tx_broadcast;
    306  1.1  yamaguch 	struct evcnt	 isc_tx_discards;
    307  1.1  yamaguch 	struct evcnt	 isc_tx_errors;
    308  1.1  yamaguch };
    309  1.1  yamaguch 
    310  1.1  yamaguch /*
    311  1.1  yamaguch  * Locking notes:
    312  1.1  yamaguch  * + A field in iavf_tx_ring is protected by txr_lock (a spin mutex), and
    313  1.1  yamaguch  *   A field in iavf_rx_ring is protected by rxr_lock (a spin mutex).
    314  1.1  yamaguch  *   - more than one lock must not be held at once.
    315  1.1  yamaguch  * + fields named sc_atq_*, sc_arq_*, and sc_adminq_* are protected by
    316  1.1  yamaguch  *   sc_adminq_lock(a spin mutex).
    317  1.1  yamaguch  *   - The lock is held while accessing sc_aq_regs
    318  1.1  yamaguch  *     and is not held with txr_lock and rxr_lock together.
    319  1.1  yamaguch  * + Other fields in iavf_softc is protected by sc_cfg_lock
    320  1.1  yamaguch  *   (an adaptive mutex).
    321  1.1  yamaguch  *   - The lock must be held before acquiring another lock.
    322  1.1  yamaguch  */
    323  1.1  yamaguch 
    324  1.1  yamaguch struct iavf_softc {
    325  1.1  yamaguch 	device_t		 sc_dev;
    326  1.1  yamaguch 	enum i40e_mac_type	 sc_mac_type;
    327  1.1  yamaguch 	int			 sc_debuglevel;
    328  1.1  yamaguch 	bool			 sc_attached;
    329  1.1  yamaguch 	bool			 sc_dead;
    330  1.1  yamaguch 	kmutex_t		 sc_cfg_lock;
    331  1.1  yamaguch 	callout_t		 sc_tick;
    332  1.1  yamaguch 	struct ifmedia		 sc_media;
    333  1.1  yamaguch 	uint64_t		 sc_media_status;
    334  1.1  yamaguch 	uint64_t		 sc_media_active;
    335  1.1  yamaguch 	int			 sc_link_state;
    336  1.1  yamaguch 
    337  1.1  yamaguch 	const struct iavf_aq_regs *
    338  1.1  yamaguch 				 sc_aq_regs;
    339  1.1  yamaguch 
    340  1.1  yamaguch 	struct ethercom		 sc_ec;
    341  1.1  yamaguch 	uint8_t			 sc_enaddr[ETHER_ADDR_LEN];
    342  1.1  yamaguch 	uint8_t			 sc_enaddr_fake[ETHER_ADDR_LEN];
    343  1.1  yamaguch 	uint8_t			 sc_enaddr_added[ETHER_ADDR_LEN];
    344  1.1  yamaguch 	uint8_t			 sc_enaddr_reset[ETHER_ADDR_LEN];
    345  1.1  yamaguch 	struct if_percpuq	*sc_ipq;
    346  1.1  yamaguch 
    347  1.1  yamaguch 	struct pci_attach_args	 sc_pa;
    348  1.1  yamaguch 	bus_dma_tag_t		 sc_dmat;
    349  1.1  yamaguch 	bus_space_tag_t		 sc_memt;
    350  1.1  yamaguch 	bus_space_handle_t	 sc_memh;
    351  1.1  yamaguch 	bus_size_t		 sc_mems;
    352  1.1  yamaguch 	pci_intr_handle_t	*sc_ihp;
    353  1.1  yamaguch 	void			**sc_ihs;
    354  1.1  yamaguch 	unsigned int		 sc_nintrs;
    355  1.1  yamaguch 
    356  1.1  yamaguch 	uint32_t		 sc_major_ver;
    357  1.1  yamaguch 	uint32_t		 sc_minor_ver;
    358  1.1  yamaguch 	uint32_t		 sc_vf_id;
    359  1.1  yamaguch 	uint32_t		 sc_vf_cap;
    360  1.1  yamaguch 	uint16_t		 sc_vsi_id;
    361  1.1  yamaguch 	uint16_t		 sc_qset_handle;
    362  1.1  yamaguch 	uint16_t		 sc_max_mtu;
    363  1.1  yamaguch 	bool			 sc_got_vf_resources;
    364  1.1  yamaguch 	bool			 sc_got_irq_map;
    365  1.1  yamaguch 	unsigned int		 sc_max_vectors;
    366  1.1  yamaguch 
    367  1.1  yamaguch 	kmutex_t		 sc_adminq_lock;
    368  1.1  yamaguch 	kcondvar_t		 sc_adminq_cv;
    369  1.1  yamaguch 	struct ixl_dmamem	 sc_atq;
    370  1.1  yamaguch 	unsigned int		 sc_atq_prod;
    371  1.1  yamaguch 	unsigned int		 sc_atq_cons;
    372  1.1  yamaguch 	struct ixl_aq_bufs	 sc_atq_idle;
    373  1.1  yamaguch 	struct ixl_aq_bufs	 sc_atq_live;
    374  1.1  yamaguch 	struct ixl_dmamem	 sc_arq;
    375  1.1  yamaguch 	struct ixl_aq_bufs	 sc_arq_idle;
    376  1.1  yamaguch 	struct ixl_aq_bufs	 sc_arq_live;
    377  1.1  yamaguch 	unsigned int		 sc_arq_prod;
    378  1.1  yamaguch 	unsigned int		 sc_arq_cons;
    379  1.1  yamaguch 	struct iavf_work	 sc_arq_refill;
    380  1.1  yamaguch 	uint32_t		 sc_arq_opcode;
    381  1.1  yamaguch 	uint32_t		 sc_arq_retval;
    382  1.1  yamaguch 
    383  1.1  yamaguch 	uint32_t		 sc_tx_itr;
    384  1.1  yamaguch 	uint32_t		 sc_rx_itr;
    385  1.1  yamaguch 	unsigned int		 sc_tx_ring_ndescs;
    386  1.1  yamaguch 	unsigned int		 sc_rx_ring_ndescs;
    387  1.1  yamaguch 	unsigned int		 sc_nqueue_pairs;
    388  1.1  yamaguch 	unsigned int		 sc_nqps_alloc;
    389  1.1  yamaguch 	unsigned int		 sc_nqps_vsi;
    390  1.1  yamaguch 	unsigned int		 sc_nqps_req;
    391  1.1  yamaguch 	struct iavf_queue_pair	*sc_qps;
    392  1.1  yamaguch 	bool			 sc_txrx_workqueue;
    393  1.1  yamaguch 	u_int			 sc_tx_intr_process_limit;
    394  1.1  yamaguch 	u_int			 sc_tx_process_limit;
    395  1.1  yamaguch 	u_int			 sc_rx_intr_process_limit;
    396  1.1  yamaguch 	u_int			 sc_rx_process_limit;
    397  1.1  yamaguch 
    398  1.1  yamaguch 	struct workqueue	*sc_workq;
    399  1.1  yamaguch 	struct workqueue	*sc_workq_txrx;
    400  1.1  yamaguch 	struct iavf_work	 sc_reset_task;
    401  1.1  yamaguch 	struct iavf_work	 sc_wdto_task;
    402  1.1  yamaguch 	struct iavf_work	 sc_req_queues_task;
    403  1.1  yamaguch 	bool			 sc_req_queues_retried;
    404  1.1  yamaguch 	bool			 sc_resetting;
    405  1.1  yamaguch 	bool			 sc_reset_up;
    406  1.1  yamaguch 
    407  1.1  yamaguch 	struct sysctllog	*sc_sysctllog;
    408  1.1  yamaguch 	struct iavf_stat_counters
    409  1.1  yamaguch 				 sc_stat_counters;
    410  1.1  yamaguch };
    411  1.1  yamaguch 
    412  1.1  yamaguch #define IAVF_LOG(_sc, _lvl, _fmt, _args...)				\
    413  1.1  yamaguch do {									\
    414  1.1  yamaguch 	if (!(_sc)->sc_attached) {					\
    415  1.1  yamaguch 		switch (_lvl) {						\
    416  1.1  yamaguch 		case LOG_ERR:						\
    417  1.1  yamaguch 		case LOG_WARNING:					\
    418  1.1  yamaguch 			aprint_error_dev((_sc)->sc_dev, _fmt, ##_args);	\
    419  1.1  yamaguch 			break;						\
    420  1.1  yamaguch 		case LOG_INFO:						\
    421  1.1  yamaguch 			aprint_normal_dev((_sc)->sc_dev,_fmt, ##_args);	\
    422  1.1  yamaguch 			break;						\
    423  1.1  yamaguch 		case LOG_DEBUG:						\
    424  1.1  yamaguch 		default:						\
    425  1.1  yamaguch 			aprint_debug_dev((_sc)->sc_dev, _fmt, ##_args);	\
    426  1.1  yamaguch 		}							\
    427  1.1  yamaguch 	} else {							\
    428  1.1  yamaguch 		struct ifnet *_ifp = &(_sc)->sc_ec.ec_if;		\
    429  1.1  yamaguch 		log((_lvl), "%s: " _fmt, _ifp->if_xname, ##_args);	\
    430  1.1  yamaguch 	}								\
    431  1.1  yamaguch } while (0)
    432  1.1  yamaguch 
    433  1.1  yamaguch static int	iavf_dmamem_alloc(bus_dma_tag_t, struct ixl_dmamem *,
    434  1.1  yamaguch 		    bus_size_t, bus_size_t);
    435  1.1  yamaguch static void	iavf_dmamem_free(bus_dma_tag_t, struct ixl_dmamem *);
    436  1.1  yamaguch static struct ixl_aq_buf *
    437  1.1  yamaguch 		iavf_aqb_get(struct iavf_softc *, struct ixl_aq_bufs *);
    438  1.1  yamaguch static struct ixl_aq_buf *
    439  1.1  yamaguch 		iavf_aqb_get_locked(struct ixl_aq_bufs *);
    440  1.1  yamaguch static void	iavf_aqb_put_locked(struct ixl_aq_bufs *, struct ixl_aq_buf *);
    441  1.1  yamaguch static void	iavf_aqb_clean(struct ixl_aq_bufs *, bus_dma_tag_t);
    442  1.1  yamaguch 
    443  1.1  yamaguch static const struct iavf_product *
    444  1.1  yamaguch 		iavf_lookup(const struct pci_attach_args *);
    445  1.1  yamaguch static enum i40e_mac_type
    446  1.1  yamaguch 		iavf_mactype(pci_product_id_t);
    447  1.1  yamaguch static void	iavf_pci_csr_setup(pci_chipset_tag_t, pcitag_t);
    448  1.1  yamaguch static int	iavf_wait_active(struct iavf_softc *);
    449  1.1  yamaguch static bool	iavf_is_etheranyaddr(const uint8_t *);
    450  1.1  yamaguch static void	iavf_prepare_fakeaddr(struct iavf_softc *);
    451  1.1  yamaguch static int	iavf_replace_lla(struct ifnet *,
    452  1.1  yamaguch 		    const uint8_t *, const uint8_t *);
    453  1.1  yamaguch static void	iavf_evcnt_attach(struct evcnt *,
    454  1.1  yamaguch 		    const char *, const char *);
    455  1.1  yamaguch static int	iavf_setup_interrupts(struct iavf_softc *);
    456  1.1  yamaguch static void	iavf_teardown_interrupts(struct iavf_softc *);
    457  1.1  yamaguch static int	iavf_setup_sysctls(struct iavf_softc *);
    458  1.1  yamaguch static void	iavf_teardown_sysctls(struct iavf_softc *);
    459  1.1  yamaguch static int	iavf_setup_stats(struct iavf_softc *);
    460  1.1  yamaguch static void	iavf_teardown_stats(struct iavf_softc *);
    461  1.1  yamaguch static struct workqueue *
    462  1.1  yamaguch 		iavf_workq_create(const char *, pri_t, int, int);
    463  1.1  yamaguch static void	iavf_workq_destroy(struct workqueue *);
    464  1.1  yamaguch static int	iavf_work_set(struct iavf_work *, void (*)(void *), void *);
    465  1.1  yamaguch static void	iavf_work_add(struct workqueue *, struct iavf_work *);
    466  1.1  yamaguch static void	iavf_work_wait(struct workqueue *, struct iavf_work *);
    467  1.1  yamaguch static unsigned int
    468  1.1  yamaguch 		iavf_calc_msix_count(struct iavf_softc *);
    469  1.1  yamaguch static unsigned int
    470  1.1  yamaguch 		iavf_calc_queue_pair_size(struct iavf_softc *);
    471  1.1  yamaguch static int	iavf_queue_pairs_alloc(struct iavf_softc *);
    472  1.1  yamaguch static void	iavf_queue_pairs_free(struct iavf_softc *);
    473  1.1  yamaguch static int	iavf_arq_fill(struct iavf_softc *);
    474  1.1  yamaguch static void	iavf_arq_refill(void *);
    475  1.1  yamaguch static int	iavf_arq_poll(struct iavf_softc *, uint32_t, int);
    476  1.1  yamaguch static void	iavf_atq_done(struct iavf_softc *);
    477  1.1  yamaguch static int	iavf_init_admin_queue(struct iavf_softc *);
    478  1.1  yamaguch static void	iavf_cleanup_admin_queue(struct iavf_softc *);
    479  1.1  yamaguch static int	iavf_arq(struct iavf_softc *);
    480  1.1  yamaguch static int	iavf_adminq_exec(struct iavf_softc *,
    481  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    482  1.1  yamaguch static int	iavf_adminq_poll(struct iavf_softc *,
    483  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *, int);
    484  1.1  yamaguch static int	iavf_adminq_poll_locked(struct iavf_softc *,
    485  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *, int);
    486  1.1  yamaguch static int	iavf_add_multi(struct iavf_softc *, uint8_t *, uint8_t *);
    487  1.1  yamaguch static int	iavf_del_multi(struct iavf_softc *, uint8_t *, uint8_t *);
    488  1.1  yamaguch static void	iavf_del_all_multi(struct iavf_softc *);
    489  1.1  yamaguch 
    490  1.1  yamaguch static int	iavf_get_version(struct iavf_softc *, struct ixl_aq_buf *);
    491  1.1  yamaguch static int	iavf_get_vf_resources(struct iavf_softc *, struct ixl_aq_buf *);
    492  1.1  yamaguch static int	iavf_get_stats(struct iavf_softc *);
    493  1.1  yamaguch static int	iavf_config_irq_map(struct iavf_softc *, struct ixl_aq_buf *);
    494  1.1  yamaguch static int	iavf_config_vsi_queues(struct iavf_softc *);
    495  1.1  yamaguch static int	iavf_config_hena(struct iavf_softc *);
    496  1.1  yamaguch static int	iavf_config_rss_key(struct iavf_softc *);
    497  1.1  yamaguch static int	iavf_config_rss_lut(struct iavf_softc *);
    498  1.1  yamaguch static int	iavf_config_promisc_mode(struct iavf_softc *, int, int);
    499  1.1  yamaguch static int	iavf_config_vlan_stripping(struct iavf_softc *, int);
    500  1.1  yamaguch static int	iavf_config_vlan_id(struct iavf_softc *, uint16_t, uint32_t);
    501  1.1  yamaguch static int	iavf_queue_select(struct iavf_softc *, int);
    502  1.1  yamaguch static int	iavf_request_queues(struct iavf_softc *, unsigned int);
    503  1.1  yamaguch static int	iavf_reset_vf(struct iavf_softc *);
    504  1.1  yamaguch static int	iavf_eth_addr(struct iavf_softc *, const uint8_t *, uint32_t);
    505  1.1  yamaguch static void	iavf_process_version(struct iavf_softc *,
    506  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    507  1.1  yamaguch static void	iavf_process_vf_resources(struct iavf_softc *,
    508  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    509  1.1  yamaguch static void	iavf_process_irq_map(struct iavf_softc *,
    510  1.1  yamaguch 		    struct ixl_aq_desc *);
    511  1.1  yamaguch static void	iavf_process_vc_event(struct iavf_softc *,
    512  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    513  1.1  yamaguch static void	iavf_process_stats(struct iavf_softc *,
    514  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    515  1.1  yamaguch static void	iavf_process_req_queues(struct iavf_softc *,
    516  1.1  yamaguch 		    struct ixl_aq_desc *, struct ixl_aq_buf *);
    517  1.1  yamaguch 
    518  1.1  yamaguch static int	iavf_intr(void *);
    519  1.1  yamaguch static int	iavf_queue_intr(void *);
    520  1.1  yamaguch static void	iavf_tick(void *);
    521  1.1  yamaguch static void	iavf_tick_halt(void *);
    522  1.1  yamaguch static void	iavf_reset_request(void *);
    523  1.1  yamaguch static void	iavf_reset_start(void *);
    524  1.1  yamaguch static void	iavf_reset(void *);
    525  1.1  yamaguch static void	iavf_reset_finish(struct iavf_softc *);
    526  1.1  yamaguch static int	iavf_init(struct ifnet *);
    527  1.1  yamaguch static int	iavf_init_locked(struct iavf_softc *);
    528  1.1  yamaguch static void	iavf_stop(struct ifnet *, int);
    529  1.1  yamaguch static void	iavf_stop_locked(struct iavf_softc *);
    530  1.1  yamaguch static int	iavf_ioctl(struct ifnet *, u_long, void *);
    531  1.1  yamaguch static void	iavf_start(struct ifnet *);
    532  1.1  yamaguch static int	iavf_transmit(struct ifnet *, struct mbuf*);
    533  1.1  yamaguch static int	iavf_watchdog(struct iavf_tx_ring *);
    534  1.1  yamaguch static void	iavf_watchdog_timeout(void *);
    535  1.1  yamaguch static int	iavf_media_change(struct ifnet *);
    536  1.1  yamaguch static void	iavf_media_status(struct ifnet *, struct ifmediareq *);
    537  1.1  yamaguch static int	iavf_ifflags_cb(struct ethercom *);
    538  1.1  yamaguch static int	iavf_vlan_cb(struct ethercom *, uint16_t, bool);
    539  1.1  yamaguch static void	iavf_deferred_transmit(void *);
    540  1.1  yamaguch static void	iavf_handle_queue(void *);
    541  1.1  yamaguch static void	iavf_handle_queue_wk(struct work *, void *);
    542  1.1  yamaguch static int	iavf_reinit(struct iavf_softc *);
    543  1.1  yamaguch static int	iavf_rxfill(struct iavf_softc *, struct iavf_rx_ring *);
    544  1.1  yamaguch static void	iavf_txr_clean(struct iavf_softc *, struct iavf_tx_ring *);
    545  1.1  yamaguch static void	iavf_rxr_clean(struct iavf_softc *, struct iavf_rx_ring *);
    546  1.1  yamaguch static int	iavf_txeof(struct iavf_softc *, struct iavf_tx_ring *,
    547  1.1  yamaguch 		    u_int, struct evcnt *);
    548  1.1  yamaguch static int	iavf_rxeof(struct iavf_softc *, struct iavf_rx_ring *,
    549  1.1  yamaguch 		    u_int, struct evcnt *);
    550  1.1  yamaguch static int	iavf_iff(struct iavf_softc *);
    551  1.1  yamaguch static int	iavf_iff_locked(struct iavf_softc *);
    552  1.1  yamaguch static void	iavf_post_request_queues(void *);
    553  1.1  yamaguch static int	iavf_sysctl_itr_handler(SYSCTLFN_PROTO);
    554  1.1  yamaguch 
    555  1.1  yamaguch static int	iavf_match(device_t, cfdata_t, void *);
    556  1.1  yamaguch static void	iavf_attach(device_t, device_t, void*);
    557  1.1  yamaguch static int	iavf_detach(device_t, int);
    558  1.1  yamaguch static int	iavf_finalize_teardown(device_t);
    559  1.1  yamaguch 
    560  1.1  yamaguch CFATTACH_DECL3_NEW(iavf, sizeof(struct iavf_softc),
    561  1.1  yamaguch     iavf_match, iavf_attach, iavf_detach, NULL, NULL, NULL,
    562  1.1  yamaguch     DVF_DETACH_SHUTDOWN);
    563  1.1  yamaguch 
    564  1.1  yamaguch static const struct iavf_product iavf_products[] = {
    565  1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_VF },
    566  1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_VF_HV },
    567  1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_VF },
    568  1.1  yamaguch 	/* required last entry */
    569  1.1  yamaguch 	{0, 0}
    570  1.1  yamaguch };
    571  1.1  yamaguch 
    572  1.1  yamaguch static const struct iavf_link_speed iavf_link_speeds[] = {
    573  1.1  yamaguch 	{ 0, 0 },
    574  1.1  yamaguch 	{ IF_Mbps(100), IFM_100_TX },
    575  1.1  yamaguch 	{ IF_Mbps(1000), IFM_1000_T },
    576  1.1  yamaguch 	{ IF_Gbps(10), IFM_10G_T },
    577  1.1  yamaguch 	{ IF_Gbps(40), IFM_40G_CR4 },
    578  1.1  yamaguch 	{ IF_Gbps(20), IFM_20G_KR2 },
    579  1.1  yamaguch 	{ IF_Gbps(25), IFM_25G_CR }
    580  1.1  yamaguch };
    581  1.1  yamaguch 
    582  1.1  yamaguch static const struct iavf_aq_regs iavf_aq_regs = {
    583  1.1  yamaguch 	.atq_tail	= I40E_VF_ATQT1,
    584  1.1  yamaguch 	.atq_tail_mask	= I40E_VF_ATQT1_ATQT_MASK,
    585  1.1  yamaguch 	.atq_head	= I40E_VF_ATQH1,
    586  1.1  yamaguch 	.atq_head_mask	= I40E_VF_ARQH1_ARQH_MASK,
    587  1.1  yamaguch 	.atq_len	= I40E_VF_ATQLEN1,
    588  1.1  yamaguch 	.atq_bal	= I40E_VF_ATQBAL1,
    589  1.1  yamaguch 	.atq_bah	= I40E_VF_ATQBAH1,
    590  1.1  yamaguch 	.atq_len_enable	= I40E_VF_ATQLEN1_ATQENABLE_MASK,
    591  1.1  yamaguch 
    592  1.1  yamaguch 	.arq_tail	= I40E_VF_ARQT1,
    593  1.1  yamaguch 	.arq_tail_mask	= I40E_VF_ARQT1_ARQT_MASK,
    594  1.1  yamaguch 	.arq_head	= I40E_VF_ARQH1,
    595  1.1  yamaguch 	.arq_head_mask	= I40E_VF_ARQH1_ARQH_MASK,
    596  1.1  yamaguch 	.arq_len	= I40E_VF_ARQLEN1,
    597  1.1  yamaguch 	.arq_bal	= I40E_VF_ARQBAL1,
    598  1.1  yamaguch 	.arq_bah	= I40E_VF_ARQBAH1,
    599  1.1  yamaguch 	.arq_len_enable	= I40E_VF_ARQLEN1_ARQENABLE_MASK,
    600  1.1  yamaguch };
    601  1.1  yamaguch 
    602  1.1  yamaguch static struct iavf_module_params iavf_params = {
    603  1.1  yamaguch 	.debug = 0,
    604  1.1  yamaguch 	.rx_itr = 0x07a, /* 4K intrs/sec */
    605  1.1  yamaguch 	.tx_itr = 0x07a, /* 4K intrs/sec */
    606  1.1  yamaguch 	.tx_ndescs = 512,
    607  1.1  yamaguch 	.rx_ndescs = 256,
    608  1.1  yamaguch 	.max_qps = INT_MAX,
    609  1.1  yamaguch };
    610  1.1  yamaguch 
    611  1.1  yamaguch #define delaymsec(_x)	DELAY(1000 * (_x))
    612  1.1  yamaguch #define iavf_rd(_s, _r)			\
    613  1.1  yamaguch 	bus_space_read_4((_s)->sc_memt, (_s)->sc_memh, (_r))
    614  1.1  yamaguch #define iavf_wr(_s, _r, _v)		\
    615  1.1  yamaguch 	bus_space_write_4((_s)->sc_memt, (_s)->sc_memh, (_r), (_v))
    616  1.1  yamaguch #define iavf_barrier(_s, _r, _l, _o) \
    617  1.1  yamaguch 	bus_space_barrier((_s)->sc_memt, (_s)->sc_memh, (_r), (_l), (_o))
    618  1.1  yamaguch #define iavf_flush(_s)	(void)iavf_rd((_s), I40E_VFGEN_RSTAT)
    619  1.1  yamaguch #define iavf_nqueues(_sc)	(1 << ((_sc)->sc_nqueue_pairs - 1))
    620  1.1  yamaguch #define iavf_allqueues(_sc)	((1 << ((_sc)->sc_nqueue_pairs)) - 1)
    621  1.1  yamaguch 
    622  1.1  yamaguch static inline void
    623  1.1  yamaguch iavf_intr_enable(struct iavf_softc *sc)
    624  1.1  yamaguch {
    625  1.1  yamaguch 
    626  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTL01, I40E_VFINT_DYN_CTL0_INTENA_MASK |
    627  1.1  yamaguch 	    I40E_VFINT_DYN_CTL0_CLEARPBA_MASK |
    628  1.1  yamaguch 	    (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT));
    629  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ICR0_ENA1, I40E_VFINT_ICR0_ENA1_ADMINQ_MASK);
    630  1.1  yamaguch 	iavf_flush(sc);
    631  1.1  yamaguch }
    632  1.1  yamaguch 
    633  1.1  yamaguch static inline void
    634  1.1  yamaguch iavf_intr_disable(struct iavf_softc *sc)
    635  1.1  yamaguch {
    636  1.1  yamaguch 
    637  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTL01,
    638  1.1  yamaguch 	    (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT));
    639  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ICR0_ENA1, 0);
    640  1.1  yamaguch 	iavf_flush(sc);
    641  1.1  yamaguch }
    642  1.1  yamaguch 
    643  1.1  yamaguch static inline void
    644  1.1  yamaguch iavf_queue_intr_enable(struct iavf_softc *sc, unsigned int qid)
    645  1.1  yamaguch {
    646  1.1  yamaguch 
    647  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTLN1(qid),
    648  1.1  yamaguch 	    I40E_VFINT_DYN_CTLN1_INTENA_MASK |
    649  1.1  yamaguch 	    I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK |
    650  1.1  yamaguch 	    (IAVF_NOITR << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT));
    651  1.1  yamaguch 	iavf_flush(sc);
    652  1.1  yamaguch }
    653  1.1  yamaguch 
    654  1.1  yamaguch static inline void
    655  1.1  yamaguch iavf_queue_intr_disable(struct iavf_softc *sc, unsigned int qid)
    656  1.1  yamaguch {
    657  1.1  yamaguch 
    658  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTLN1(qid),
    659  1.1  yamaguch 	    (IAVF_NOITR << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT));
    660  1.1  yamaguch 	iavf_flush(sc);
    661  1.1  yamaguch }
    662  1.1  yamaguch 
    663  1.1  yamaguch static inline void
    664  1.1  yamaguch iavf_aq_vc_set_opcode(struct ixl_aq_desc *iaq, uint32_t opcode)
    665  1.1  yamaguch {
    666  1.1  yamaguch 	struct iavf_aq_vc *vc;
    667  1.1  yamaguch 
    668  1.1  yamaguch 	vc = (struct iavf_aq_vc *)&iaq->iaq_cookie;
    669  1.1  yamaguch 	vc->iaq_vc_opcode = htole32(opcode);
    670  1.1  yamaguch }
    671  1.1  yamaguch 
    672  1.1  yamaguch static inline uint32_t
    673  1.1  yamaguch iavf_aq_vc_get_opcode(const struct ixl_aq_desc *iaq)
    674  1.1  yamaguch {
    675  1.1  yamaguch 	const struct iavf_aq_vc *vc;
    676  1.1  yamaguch 
    677  1.1  yamaguch 	vc = (const struct iavf_aq_vc *)&iaq->iaq_cookie;
    678  1.1  yamaguch 	return le32toh(vc->iaq_vc_opcode);
    679  1.1  yamaguch }
    680  1.1  yamaguch 
    681  1.1  yamaguch static inline uint32_t
    682  1.1  yamaguch iavf_aq_vc_get_retval(const struct ixl_aq_desc *iaq)
    683  1.1  yamaguch {
    684  1.1  yamaguch 	const struct iavf_aq_vc *vc;
    685  1.1  yamaguch 
    686  1.1  yamaguch 	vc = (const struct iavf_aq_vc *)&iaq->iaq_cookie;
    687  1.1  yamaguch 	return le32toh(vc->iaq_vc_retval);
    688  1.1  yamaguch }
    689  1.1  yamaguch 
    690  1.1  yamaguch static int
    691  1.1  yamaguch iavf_match(device_t parent, cfdata_t match, void *aux)
    692  1.1  yamaguch {
    693  1.1  yamaguch 	const struct pci_attach_args *pa = aux;
    694  1.1  yamaguch 
    695  1.1  yamaguch 	return (iavf_lookup(pa) != NULL) ? 1 : 0;
    696  1.1  yamaguch }
    697  1.1  yamaguch 
    698  1.1  yamaguch static void
    699  1.1  yamaguch iavf_attach(device_t parent, device_t self, void *aux)
    700  1.1  yamaguch {
    701  1.1  yamaguch 	struct iavf_softc *sc;
    702  1.1  yamaguch 	struct pci_attach_args *pa = aux;
    703  1.1  yamaguch 	struct ifnet *ifp;
    704  1.1  yamaguch 	struct ixl_aq_buf *aqb;
    705  1.1  yamaguch 	pcireg_t memtype;
    706  1.1  yamaguch 	char xnamebuf[MAXCOMLEN];
    707  1.1  yamaguch 	int error, i;
    708  1.1  yamaguch 
    709  1.1  yamaguch 	sc = device_private(self);
    710  1.1  yamaguch 	sc->sc_dev = self;
    711  1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
    712  1.1  yamaguch 
    713  1.1  yamaguch 	sc->sc_pa = *pa;
    714  1.1  yamaguch 	sc->sc_dmat = (pci_dma64_available(pa)) ? pa->pa_dmat64 : pa->pa_dmat;
    715  1.1  yamaguch 	sc->sc_aq_regs = &iavf_aq_regs;
    716  1.1  yamaguch 	sc->sc_debuglevel = iavf_params.debug;
    717  1.1  yamaguch 	sc->sc_tx_ring_ndescs = iavf_params.tx_ndescs;
    718  1.1  yamaguch 	sc->sc_rx_ring_ndescs = iavf_params.rx_ndescs;
    719  1.1  yamaguch 	sc->sc_tx_itr = iavf_params.tx_itr;
    720  1.1  yamaguch 	sc->sc_rx_itr = iavf_params.rx_itr;
    721  1.1  yamaguch 	sc->sc_nqps_req = MIN(ncpu, iavf_params.max_qps);
    722  1.1  yamaguch 	iavf_prepare_fakeaddr(sc);
    723  1.1  yamaguch 
    724  1.1  yamaguch 	sc->sc_mac_type = iavf_mactype(PCI_PRODUCT(pa->pa_id));
    725  1.1  yamaguch 	iavf_pci_csr_setup(pa->pa_pc, pa->pa_tag);
    726  1.1  yamaguch 
    727  1.1  yamaguch 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IAVF_PCIREG);
    728  1.1  yamaguch 	if (pci_mapreg_map(pa, IAVF_PCIREG, memtype, 0,
    729  1.1  yamaguch 	    &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) {
    730  1.1  yamaguch 		aprint_error(": unable to map registers\n");
    731  1.1  yamaguch 		return;
    732  1.1  yamaguch 	}
    733  1.1  yamaguch 
    734  1.1  yamaguch 	if (iavf_wait_active(sc) != 0) {
    735  1.1  yamaguch 		aprint_error(": VF reset timed out\n");
    736  1.1  yamaguch 		goto unmap;
    737  1.1  yamaguch 	}
    738  1.1  yamaguch 
    739  1.1  yamaguch 	mutex_init(&sc->sc_cfg_lock, MUTEX_DEFAULT, IPL_SOFTNET);
    740  1.1  yamaguch 	mutex_init(&sc->sc_adminq_lock, MUTEX_DEFAULT, IPL_NET);
    741  1.1  yamaguch 	SIMPLEQ_INIT(&sc->sc_atq_idle);
    742  1.1  yamaguch 	SIMPLEQ_INIT(&sc->sc_atq_live);
    743  1.1  yamaguch 	SIMPLEQ_INIT(&sc->sc_arq_idle);
    744  1.1  yamaguch 	SIMPLEQ_INIT(&sc->sc_arq_live);
    745  1.1  yamaguch 	sc->sc_arq_cons = 0;
    746  1.1  yamaguch 	sc->sc_arq_prod = 0;
    747  1.1  yamaguch 	aqb = NULL;
    748  1.1  yamaguch 
    749  1.1  yamaguch 	if (iavf_dmamem_alloc(sc->sc_dmat, &sc->sc_atq,
    750  1.1  yamaguch 	    sizeof(struct ixl_aq_desc) * IAVF_AQ_NUM, IAVF_AQ_ALIGN) != 0) {
    751  1.1  yamaguch 		aprint_error(": unable to allocate atq\n");
    752  1.1  yamaguch 		goto free_mutex;
    753  1.1  yamaguch 	}
    754  1.1  yamaguch 
    755  1.1  yamaguch 	if (iavf_dmamem_alloc(sc->sc_dmat, &sc->sc_arq,
    756  1.1  yamaguch 	    sizeof(struct ixl_aq_desc) * IAVF_AQ_NUM, IAVF_AQ_ALIGN) != 0) {
    757  1.1  yamaguch 		aprint_error(": unable to allocate arq\n");
    758  1.1  yamaguch 		goto free_atq;
    759  1.1  yamaguch 	}
    760  1.1  yamaguch 
    761  1.1  yamaguch 	for (i = 0; i < IAVF_AQ_NUM; i++) {
    762  1.1  yamaguch 		aqb = iavf_aqb_get(sc, NULL);
    763  1.1  yamaguch 		if (aqb != NULL) {
    764  1.1  yamaguch 			iavf_aqb_put_locked(&sc->sc_arq_idle, aqb);
    765  1.1  yamaguch 		}
    766  1.1  yamaguch 	}
    767  1.1  yamaguch 	aqb = NULL;
    768  1.1  yamaguch 
    769  1.1  yamaguch 	if (!iavf_arq_fill(sc)) {
    770  1.1  yamaguch 		aprint_error(": unable to fill arq descriptors\n");
    771  1.1  yamaguch 		goto free_arq;
    772  1.1  yamaguch 	}
    773  1.1  yamaguch 
    774  1.1  yamaguch 	if (iavf_init_admin_queue(sc) != 0) {
    775  1.1  yamaguch 		aprint_error(": unable to initialize admin queue\n");
    776  1.1  yamaguch 		goto shutdown;
    777  1.1  yamaguch 	}
    778  1.1  yamaguch 
    779  1.1  yamaguch 	aqb = iavf_aqb_get(sc, NULL);
    780  1.1  yamaguch 	if (aqb == NULL) {
    781  1.1  yamaguch 		aprint_error(": unable to allocate buffer for ATQ\n");
    782  1.1  yamaguch 		goto shutdown;
    783  1.1  yamaguch 	}
    784  1.1  yamaguch 
    785  1.1  yamaguch 	error = iavf_get_version(sc, aqb);
    786  1.1  yamaguch 	switch (error) {
    787  1.1  yamaguch 	case 0:
    788  1.1  yamaguch 		break;
    789  1.1  yamaguch 	case ETIMEDOUT:
    790  1.1  yamaguch 		aprint_error(": timeout waiting for VF version\n");
    791  1.1  yamaguch 		goto shutdown;
    792  1.1  yamaguch 	case ENOTSUP:
    793  1.1  yamaguch 		aprint_error(": unsupported VF version %d\n", sc->sc_major_ver);
    794  1.1  yamaguch 		goto shutdown;
    795  1.1  yamaguch 	default:
    796  1.1  yamaguch 		aprint_error(":unable to get VF interface version\n");
    797  1.1  yamaguch 		goto shutdown;
    798  1.1  yamaguch 	}
    799  1.1  yamaguch 
    800  1.1  yamaguch 	if (iavf_get_vf_resources(sc, aqb) != 0) {
    801  1.1  yamaguch 		aprint_error(": timeout waiting for VF resources\n");
    802  1.1  yamaguch 		goto shutdown;
    803  1.1  yamaguch 	}
    804  1.1  yamaguch 
    805  1.1  yamaguch 	aprint_normal(", VF version %d.%d%s",
    806  1.1  yamaguch 	    sc->sc_major_ver, sc->sc_minor_ver,
    807  1.1  yamaguch 	    (sc->sc_minor_ver > IAVF_VF_MINOR) ? "(minor mismatch)" : "");
    808  1.1  yamaguch 	aprint_normal(", VF %d, VSI %d", sc->sc_vf_id, sc->sc_vsi_id);
    809  1.1  yamaguch 	aprint_normal("\n");
    810  1.1  yamaguch 	aprint_naive("\n");
    811  1.1  yamaguch 
    812  1.1  yamaguch 	aprint_normal_dev(self, "Ethernet address %s\n",
    813  1.1  yamaguch 	    ether_sprintf(sc->sc_enaddr));
    814  1.1  yamaguch 
    815  1.1  yamaguch 	if (iavf_queue_pairs_alloc(sc) != 0) {
    816  1.1  yamaguch 		goto shutdown;
    817  1.1  yamaguch 	}
    818  1.1  yamaguch 
    819  1.1  yamaguch 	if (iavf_setup_interrupts(sc) != 0) {
    820  1.1  yamaguch 		goto free_queue_pairs;
    821  1.1  yamaguch 	}
    822  1.1  yamaguch 
    823  1.1  yamaguch 	if (iavf_config_irq_map(sc, aqb) != 0) {
    824  1.1  yamaguch 		aprint_error(", timed out waiting for IRQ map response\n");
    825  1.1  yamaguch 		goto teardown_intrs;
    826  1.1  yamaguch 	}
    827  1.1  yamaguch 
    828  1.1  yamaguch 	if (iavf_setup_sysctls(sc) != 0) {
    829  1.1  yamaguch 		goto teardown_intrs;
    830  1.1  yamaguch 	}
    831  1.1  yamaguch 
    832  1.1  yamaguch 	if (iavf_setup_stats(sc) != 0) {
    833  1.1  yamaguch 		goto teardown_sysctls;
    834  1.1  yamaguch 	}
    835  1.1  yamaguch 
    836  1.1  yamaguch 	iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
    837  1.1  yamaguch 	aqb = NULL;
    838  1.1  yamaguch 
    839  1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf),
    840  1.1  yamaguch 	    "%s_adminq_cv", device_xname(self));
    841  1.1  yamaguch 	cv_init(&sc->sc_adminq_cv, xnamebuf);
    842  1.1  yamaguch 
    843  1.1  yamaguch 	callout_init(&sc->sc_tick, CALLOUT_MPSAFE);
    844  1.1  yamaguch 	callout_setfunc(&sc->sc_tick, iavf_tick, sc);
    845  1.1  yamaguch 
    846  1.1  yamaguch 	iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc);
    847  1.1  yamaguch 	iavf_work_set(&sc->sc_arq_refill, iavf_arq_refill, sc);
    848  1.1  yamaguch 	iavf_work_set(&sc->sc_wdto_task, iavf_watchdog_timeout, sc);
    849  1.1  yamaguch 	iavf_work_set(&sc->sc_req_queues_task, iavf_post_request_queues, sc);
    850  1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_cfg", device_xname(self));
    851  1.1  yamaguch 	sc->sc_workq = iavf_workq_create(xnamebuf, IAVF_WORKQUEUE_PRI,
    852  1.1  yamaguch 	    IPL_NET, WQ_MPSAFE);
    853  1.1  yamaguch 	if (sc->sc_workq == NULL)
    854  1.1  yamaguch 		goto destroy_cv;
    855  1.1  yamaguch 
    856  1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_txrx", device_xname(self));
    857  1.1  yamaguch 	error = workqueue_create(&sc->sc_workq_txrx, xnamebuf,
    858  1.1  yamaguch 	    iavf_handle_queue_wk, sc, IAVF_WORKQUEUE_PRI, IPL_NET,
    859  1.1  yamaguch 	    WQ_PERCPU|WQ_MPSAFE);
    860  1.1  yamaguch 	if (error != 0) {
    861  1.1  yamaguch 		sc->sc_workq_txrx = NULL;
    862  1.1  yamaguch 		goto teardown_wqs;
    863  1.1  yamaguch 	}
    864  1.1  yamaguch 
    865  1.1  yamaguch 	error = if_initialize(ifp);
    866  1.1  yamaguch 	if (error != 0) {
    867  1.1  yamaguch 		aprint_error_dev(self, "if_initialize failed=%d\n", error);
    868  1.1  yamaguch 		goto teardown_wqs;
    869  1.1  yamaguch 	}
    870  1.1  yamaguch 
    871  1.1  yamaguch 	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
    872  1.1  yamaguch 
    873  1.1  yamaguch 	ifp->if_softc = sc;
    874  1.1  yamaguch 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    875  1.1  yamaguch 	ifp->if_extflags = IFEF_MPSAFE;
    876  1.1  yamaguch 	ifp->if_ioctl = iavf_ioctl;
    877  1.1  yamaguch 	ifp->if_start = iavf_start;
    878  1.1  yamaguch 	ifp->if_transmit = iavf_transmit;
    879  1.1  yamaguch 	ifp->if_watchdog = NULL;
    880  1.1  yamaguch 	ifp->if_init = iavf_init;
    881  1.1  yamaguch 	ifp->if_stop = iavf_stop;
    882  1.1  yamaguch 
    883  1.1  yamaguch 	IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_ndescs);
    884  1.1  yamaguch 	IFQ_SET_READY(&ifp->if_snd);
    885  1.1  yamaguch 	sc->sc_ipq = if_percpuq_create(ifp);
    886  1.1  yamaguch 
    887  1.1  yamaguch 	ifp->if_capabilities |= IAVF_IFCAP_RXCSUM;
    888  1.1  yamaguch 	ifp->if_capabilities |= IAVF_IFCAP_TXCSUM;
    889  1.1  yamaguch 
    890  1.1  yamaguch 	ether_set_vlan_cb(&sc->sc_ec, iavf_vlan_cb);
    891  1.1  yamaguch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
    892  1.1  yamaguch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWFILTER;
    893  1.1  yamaguch 	sc->sc_ec.ec_capenable = sc->sc_ec.ec_capabilities;
    894  1.1  yamaguch 
    895  1.1  yamaguch 	ether_set_ifflags_cb(&sc->sc_ec, iavf_ifflags_cb);
    896  1.1  yamaguch 
    897  1.1  yamaguch 	sc->sc_ec.ec_ifmedia = &sc->sc_media;
    898  1.1  yamaguch 	ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK, iavf_media_change,
    899  1.1  yamaguch 	    iavf_media_status, &sc->sc_cfg_lock);
    900  1.1  yamaguch 
    901  1.1  yamaguch 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
    902  1.1  yamaguch 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
    903  1.1  yamaguch 
    904  1.1  yamaguch 	if_deferred_start_init(ifp, NULL);
    905  1.1  yamaguch 	ether_ifattach(ifp, sc->sc_enaddr);
    906  1.1  yamaguch 
    907  1.1  yamaguch 	sc->sc_txrx_workqueue = true;
    908  1.1  yamaguch 	sc->sc_tx_process_limit = IAVF_TX_PROCESS_LIMIT;
    909  1.1  yamaguch 	sc->sc_rx_process_limit = IAVF_RX_PROCESS_LIMIT;
    910  1.1  yamaguch 	sc->sc_tx_intr_process_limit = IAVF_TX_INTR_PROCESS_LIMIT;
    911  1.1  yamaguch 	sc->sc_rx_intr_process_limit = IAVF_RX_INTR_PROCESS_LIMIT;
    912  1.1  yamaguch 
    913  1.1  yamaguch 	if_register(ifp);
    914  1.1  yamaguch 	if_link_state_change(ifp, sc->sc_link_state);
    915  1.1  yamaguch 	iavf_intr_enable(sc);
    916  1.1  yamaguch 	if (sc->sc_nqps_vsi < sc->sc_nqps_req)
    917  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_req_queues_task);
    918  1.1  yamaguch 	sc->sc_attached = true;
    919  1.1  yamaguch 	return;
    920  1.1  yamaguch 
    921  1.1  yamaguch teardown_wqs:
    922  1.1  yamaguch 	config_finalize_register(self, iavf_finalize_teardown);
    923  1.1  yamaguch destroy_cv:
    924  1.1  yamaguch 	cv_destroy(&sc->sc_adminq_cv);
    925  1.1  yamaguch 	callout_destroy(&sc->sc_tick);
    926  1.1  yamaguch 	iavf_teardown_stats(sc);
    927  1.1  yamaguch teardown_sysctls:
    928  1.1  yamaguch 	iavf_teardown_sysctls(sc);
    929  1.1  yamaguch teardown_intrs:
    930  1.1  yamaguch 	iavf_teardown_interrupts(sc);
    931  1.1  yamaguch free_queue_pairs:
    932  1.1  yamaguch 	iavf_queue_pairs_free(sc);
    933  1.1  yamaguch shutdown:
    934  1.1  yamaguch 	if (aqb != NULL)
    935  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
    936  1.1  yamaguch 	iavf_cleanup_admin_queue(sc);
    937  1.1  yamaguch 	iavf_aqb_clean(&sc->sc_atq_idle, sc->sc_dmat);
    938  1.1  yamaguch 	iavf_aqb_clean(&sc->sc_arq_idle, sc->sc_dmat);
    939  1.1  yamaguch free_arq:
    940  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &sc->sc_arq);
    941  1.1  yamaguch free_atq:
    942  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &sc->sc_atq);
    943  1.1  yamaguch free_mutex:
    944  1.1  yamaguch 	mutex_destroy(&sc->sc_cfg_lock);
    945  1.1  yamaguch 	mutex_destroy(&sc->sc_adminq_lock);
    946  1.1  yamaguch unmap:
    947  1.1  yamaguch 	bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
    948  1.1  yamaguch 	sc->sc_mems = 0;
    949  1.1  yamaguch 	sc->sc_attached = false;
    950  1.1  yamaguch }
    951  1.1  yamaguch 
    952  1.1  yamaguch static int
    953  1.1  yamaguch iavf_detach(device_t self, int flags)
    954  1.1  yamaguch {
    955  1.1  yamaguch 	struct iavf_softc *sc = device_private(self);
    956  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    957  1.1  yamaguch 
    958  1.1  yamaguch 	if (!sc->sc_attached)
    959  1.1  yamaguch 		return 0;
    960  1.1  yamaguch 
    961  1.1  yamaguch 	iavf_stop(ifp, 1);
    962  1.1  yamaguch 	ether_ifdetach(ifp);
    963  1.1  yamaguch 	if_detach(ifp);
    964  1.1  yamaguch 	ifmedia_fini(&sc->sc_media);
    965  1.1  yamaguch 	if_percpuq_destroy(sc->sc_ipq);
    966  1.1  yamaguch 
    967  1.1  yamaguch 	iavf_intr_disable(sc);
    968  1.1  yamaguch 
    969  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
    970  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
    971  1.1  yamaguch 
    972  1.1  yamaguch 	/*
    973  1.1  yamaguch 	 * set a dummy function to halt callout safely
    974  1.1  yamaguch 	 * even if a workqueue entry calls callout_schedule()
    975  1.1  yamaguch 	 */
    976  1.1  yamaguch 	callout_setfunc(&sc->sc_tick, iavf_tick_halt, sc);
    977  1.1  yamaguch 
    978  1.1  yamaguch 	iavf_work_wait(sc->sc_workq, &sc->sc_reset_task);
    979  1.1  yamaguch 	iavf_work_wait(sc->sc_workq, &sc->sc_arq_refill);
    980  1.1  yamaguch 	iavf_work_wait(sc->sc_workq, &sc->sc_wdto_task);
    981  1.1  yamaguch 	iavf_workq_destroy(sc->sc_workq);
    982  1.1  yamaguch 	sc->sc_workq = NULL;
    983  1.1  yamaguch 
    984  1.1  yamaguch 	callout_halt(&sc->sc_tick, NULL);
    985  1.1  yamaguch 	callout_destroy(&sc->sc_tick);
    986  1.1  yamaguch 
    987  1.1  yamaguch 	iavf_cleanup_admin_queue(sc);
    988  1.1  yamaguch 	iavf_aqb_clean(&sc->sc_atq_idle, sc->sc_dmat);
    989  1.1  yamaguch 	iavf_aqb_clean(&sc->sc_arq_idle, sc->sc_dmat);
    990  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &sc->sc_arq);
    991  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &sc->sc_atq);
    992  1.1  yamaguch 	cv_destroy(&sc->sc_adminq_cv);
    993  1.1  yamaguch 
    994  1.1  yamaguch 	iavf_queue_pairs_free(sc);
    995  1.1  yamaguch 	iavf_teardown_interrupts(sc);
    996  1.1  yamaguch 	iavf_teardown_sysctls(sc);
    997  1.1  yamaguch 	iavf_teardown_stats(sc);
    998  1.1  yamaguch 	bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
    999  1.1  yamaguch 
   1000  1.1  yamaguch 	mutex_destroy(&sc->sc_adminq_lock);
   1001  1.1  yamaguch 	mutex_destroy(&sc->sc_cfg_lock);
   1002  1.1  yamaguch 
   1003  1.1  yamaguch 	return 0;
   1004  1.1  yamaguch }
   1005  1.1  yamaguch 
   1006  1.1  yamaguch static int
   1007  1.1  yamaguch iavf_finalize_teardown(device_t self)
   1008  1.1  yamaguch {
   1009  1.1  yamaguch 	struct iavf_softc *sc = device_private(self);
   1010  1.1  yamaguch 
   1011  1.1  yamaguch 	if (sc->sc_workq != NULL) {
   1012  1.1  yamaguch 		iavf_workq_destroy(sc->sc_workq);
   1013  1.1  yamaguch 		sc->sc_workq = NULL;
   1014  1.1  yamaguch 	}
   1015  1.1  yamaguch 
   1016  1.1  yamaguch 	if (sc->sc_workq_txrx != NULL) {
   1017  1.1  yamaguch 		workqueue_destroy(sc->sc_workq_txrx);
   1018  1.1  yamaguch 		sc->sc_workq_txrx = NULL;
   1019  1.1  yamaguch 	}
   1020  1.1  yamaguch 
   1021  1.1  yamaguch 	return 0;
   1022  1.1  yamaguch }
   1023  1.1  yamaguch 
   1024  1.1  yamaguch static int
   1025  1.1  yamaguch iavf_init(struct ifnet *ifp)
   1026  1.1  yamaguch {
   1027  1.1  yamaguch 	struct iavf_softc *sc;
   1028  1.1  yamaguch 	int rv;
   1029  1.1  yamaguch 
   1030  1.1  yamaguch 	sc = ifp->if_softc;
   1031  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1032  1.1  yamaguch 	rv = iavf_init_locked(sc);
   1033  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1034  1.1  yamaguch 
   1035  1.1  yamaguch 	return rv;
   1036  1.1  yamaguch }
   1037  1.1  yamaguch 
   1038  1.1  yamaguch static int
   1039  1.1  yamaguch iavf_init_locked(struct iavf_softc *sc)
   1040  1.1  yamaguch {
   1041  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1042  1.1  yamaguch 	unsigned int i;
   1043  1.1  yamaguch 	int error;
   1044  1.1  yamaguch 
   1045  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1046  1.1  yamaguch 
   1047  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_RUNNING))
   1048  1.1  yamaguch 		iavf_stop_locked(sc);
   1049  1.1  yamaguch 
   1050  1.1  yamaguch 	if (sc->sc_resetting)
   1051  1.1  yamaguch 		return ENXIO;
   1052  1.1  yamaguch 
   1053  1.1  yamaguch 	error = iavf_reinit(sc);
   1054  1.1  yamaguch 	if (error) {
   1055  1.1  yamaguch 		iavf_stop_locked(sc);
   1056  1.1  yamaguch 		return error;
   1057  1.1  yamaguch 	}
   1058  1.1  yamaguch 
   1059  1.1  yamaguch 	SET(ifp->if_flags, IFF_RUNNING);
   1060  1.1  yamaguch 	CLR(ifp->if_flags, IFF_OACTIVE);
   1061  1.1  yamaguch 
   1062  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1063  1.1  yamaguch 		iavf_wr(sc, I40E_VFINT_ITRN1(IAVF_ITR_RX, i), sc->sc_rx_itr);
   1064  1.1  yamaguch 		iavf_wr(sc, I40E_VFINT_ITRN1(IAVF_ITR_TX, i), sc->sc_tx_itr);
   1065  1.1  yamaguch 	}
   1066  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_RX), sc->sc_rx_itr);
   1067  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_TX), sc->sc_tx_itr);
   1068  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_MISC), 0);
   1069  1.1  yamaguch 
   1070  1.1  yamaguch 	error = iavf_iff_locked(sc);
   1071  1.1  yamaguch 	if (error) {
   1072  1.1  yamaguch 		iavf_stop_locked(sc);
   1073  1.1  yamaguch 		return error;
   1074  1.1  yamaguch 	};
   1075  1.1  yamaguch 
   1076  1.1  yamaguch 	/* ETHERCAP_VLAN_HWFILTER can not be disabled */
   1077  1.1  yamaguch 	SET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1078  1.1  yamaguch 
   1079  1.1  yamaguch 	callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL);
   1080  1.1  yamaguch 	return 0;
   1081  1.1  yamaguch }
   1082  1.1  yamaguch 
   1083  1.1  yamaguch static int
   1084  1.1  yamaguch iavf_reinit(struct iavf_softc *sc)
   1085  1.1  yamaguch {
   1086  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   1087  1.1  yamaguch 	struct iavf_tx_ring *txr;
   1088  1.1  yamaguch 	unsigned int i;
   1089  1.1  yamaguch 	uint32_t reg;
   1090  1.1  yamaguch 
   1091  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1092  1.1  yamaguch 
   1093  1.1  yamaguch 	sc->sc_reset_up = true;
   1094  1.1  yamaguch 	sc->sc_nqueue_pairs = MIN(sc->sc_nqps_alloc, sc->sc_nintrs - 1);
   1095  1.1  yamaguch 
   1096  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1097  1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   1098  1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   1099  1.1  yamaguch 
   1100  1.1  yamaguch 		iavf_rxfill(sc, rxr);
   1101  1.1  yamaguch 		txr->txr_watchdog = IAVF_WATCHDOG_STOP;
   1102  1.1  yamaguch 	}
   1103  1.1  yamaguch 
   1104  1.1  yamaguch 	if (iavf_config_vsi_queues(sc) != 0)
   1105  1.1  yamaguch 		return EIO;
   1106  1.1  yamaguch 
   1107  1.1  yamaguch 	if (iavf_config_hena(sc) != 0)
   1108  1.1  yamaguch 		return EIO;
   1109  1.1  yamaguch 
   1110  1.1  yamaguch 	iavf_config_rss_key(sc);
   1111  1.1  yamaguch 	iavf_config_rss_lut(sc);
   1112  1.1  yamaguch 
   1113  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1114  1.1  yamaguch 		iavf_queue_intr_enable(sc, i);
   1115  1.1  yamaguch 	}
   1116  1.1  yamaguch 	/* unmask */
   1117  1.1  yamaguch 	reg = iavf_rd(sc, I40E_VFINT_DYN_CTL01);
   1118  1.1  yamaguch 	reg |= (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT);
   1119  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTL01, reg);
   1120  1.1  yamaguch 
   1121  1.1  yamaguch 	if (iavf_queue_select(sc, IAVF_VC_OP_ENABLE_QUEUES) != 0)
   1122  1.1  yamaguch 		return EIO;
   1123  1.1  yamaguch 
   1124  1.1  yamaguch 	return 0;
   1125  1.1  yamaguch }
   1126  1.1  yamaguch 
   1127  1.1  yamaguch static void
   1128  1.1  yamaguch iavf_stop(struct ifnet *ifp, int disable)
   1129  1.1  yamaguch {
   1130  1.1  yamaguch 	struct iavf_softc *sc;
   1131  1.1  yamaguch 
   1132  1.1  yamaguch 	sc = ifp->if_softc;
   1133  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1134  1.1  yamaguch 	iavf_stop_locked(sc);
   1135  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1136  1.1  yamaguch }
   1137  1.1  yamaguch 
   1138  1.1  yamaguch static void
   1139  1.1  yamaguch iavf_stop_locked(struct iavf_softc *sc)
   1140  1.1  yamaguch {
   1141  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1142  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   1143  1.1  yamaguch 	struct iavf_tx_ring *txr;
   1144  1.1  yamaguch 	uint32_t reg;
   1145  1.1  yamaguch 	unsigned int i;
   1146  1.1  yamaguch 
   1147  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1148  1.1  yamaguch 
   1149  1.1  yamaguch 	CLR(ifp->if_flags, IFF_RUNNING);
   1150  1.1  yamaguch 	sc->sc_reset_up = false;
   1151  1.1  yamaguch 	callout_stop(&sc->sc_tick);
   1152  1.1  yamaguch 
   1153  1.1  yamaguch 	if (!sc->sc_resetting) {
   1154  1.1  yamaguch 		/* disable queues*/
   1155  1.1  yamaguch 		if (iavf_queue_select(sc, IAVF_VC_OP_DISABLE_QUEUES) != 0) {
   1156  1.1  yamaguch 			goto die;
   1157  1.1  yamaguch 		}
   1158  1.1  yamaguch 	}
   1159  1.1  yamaguch 
   1160  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1161  1.1  yamaguch 		iavf_queue_intr_disable(sc, i);
   1162  1.1  yamaguch 	}
   1163  1.1  yamaguch 
   1164  1.1  yamaguch 	/* mask interrupts */
   1165  1.1  yamaguch 	reg = iavf_rd(sc, I40E_VFINT_DYN_CTL01);
   1166  1.1  yamaguch 	reg |= I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK |
   1167  1.1  yamaguch 	    (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT);
   1168  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_DYN_CTL01, reg);
   1169  1.1  yamaguch 
   1170  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1171  1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   1172  1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   1173  1.1  yamaguch 
   1174  1.1  yamaguch 		mutex_enter(&rxr->rxr_lock);
   1175  1.1  yamaguch 		iavf_rxr_clean(sc, rxr);
   1176  1.1  yamaguch 		mutex_exit(&rxr->rxr_lock);
   1177  1.1  yamaguch 
   1178  1.1  yamaguch 		mutex_enter(&txr->txr_lock);
   1179  1.1  yamaguch 		iavf_txr_clean(sc, txr);
   1180  1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   1181  1.1  yamaguch 
   1182  1.1  yamaguch 		workqueue_wait(sc->sc_workq_txrx,
   1183  1.1  yamaguch 		    &sc->sc_qps[i].qp_work);
   1184  1.1  yamaguch 	}
   1185  1.1  yamaguch 
   1186  1.1  yamaguch 	return;
   1187  1.1  yamaguch die:
   1188  1.1  yamaguch 	if (!sc->sc_dead) {
   1189  1.1  yamaguch 		sc->sc_dead = true;
   1190  1.1  yamaguch 		log(LOG_INFO, "%s: Request VF reset\n", ifp->if_xname);
   1191  1.1  yamaguch 
   1192  1.1  yamaguch 		iavf_work_set(&sc->sc_reset_task, iavf_reset_request, sc);
   1193  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_reset_task);
   1194  1.1  yamaguch 	}
   1195  1.1  yamaguch 	log(LOG_CRIT, "%s: failed to shut down rings\n", ifp->if_xname);
   1196  1.1  yamaguch }
   1197  1.1  yamaguch 
   1198  1.1  yamaguch static int
   1199  1.1  yamaguch iavf_watchdog(struct iavf_tx_ring *txr)
   1200  1.1  yamaguch {
   1201  1.1  yamaguch 	struct iavf_softc *sc;
   1202  1.1  yamaguch 
   1203  1.1  yamaguch 	sc = txr->txr_sc;
   1204  1.1  yamaguch 
   1205  1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   1206  1.1  yamaguch 
   1207  1.1  yamaguch 	if (txr->txr_watchdog == IAVF_WATCHDOG_STOP
   1208  1.1  yamaguch 	    || --txr->txr_watchdog > 0) {
   1209  1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   1210  1.1  yamaguch 		return 0;
   1211  1.1  yamaguch 	}
   1212  1.1  yamaguch 
   1213  1.1  yamaguch 	txr->txr_watchdog = IAVF_WATCHDOG_STOP;
   1214  1.1  yamaguch 	txr->txr_watchdogto.ev_count++;
   1215  1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   1216  1.1  yamaguch 
   1217  1.1  yamaguch 	device_printf(sc->sc_dev, "watchdog timeout on queue %d\n",
   1218  1.1  yamaguch 	    txr->txr_qid);
   1219  1.1  yamaguch 	return 1;
   1220  1.1  yamaguch }
   1221  1.1  yamaguch 
   1222  1.1  yamaguch static void
   1223  1.1  yamaguch iavf_watchdog_timeout(void *xsc)
   1224  1.1  yamaguch {
   1225  1.1  yamaguch 	struct iavf_softc *sc;
   1226  1.1  yamaguch 	struct ifnet *ifp;
   1227  1.1  yamaguch 
   1228  1.1  yamaguch 	sc = xsc;
   1229  1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
   1230  1.1  yamaguch 
   1231  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1232  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_RUNNING))
   1233  1.1  yamaguch 		iavf_init_locked(sc);
   1234  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1235  1.1  yamaguch }
   1236  1.1  yamaguch 
   1237  1.1  yamaguch static int
   1238  1.1  yamaguch iavf_media_change(struct ifnet *ifp)
   1239  1.1  yamaguch {
   1240  1.1  yamaguch 	struct iavf_softc *sc;
   1241  1.1  yamaguch 	struct ifmedia *ifm;
   1242  1.1  yamaguch 
   1243  1.1  yamaguch 	sc = ifp->if_softc;
   1244  1.1  yamaguch 	ifm = &sc->sc_media;
   1245  1.1  yamaguch 
   1246  1.1  yamaguch 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
   1247  1.1  yamaguch 		return EINVAL;
   1248  1.1  yamaguch 
   1249  1.1  yamaguch 	switch (IFM_SUBTYPE(ifm->ifm_media)) {
   1250  1.1  yamaguch 	case IFM_AUTO:
   1251  1.1  yamaguch 		break;
   1252  1.1  yamaguch 	default:
   1253  1.1  yamaguch 		return EINVAL;
   1254  1.1  yamaguch 	}
   1255  1.1  yamaguch 
   1256  1.1  yamaguch 	return 0;
   1257  1.1  yamaguch }
   1258  1.1  yamaguch 
   1259  1.1  yamaguch static void
   1260  1.1  yamaguch iavf_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
   1261  1.1  yamaguch {
   1262  1.1  yamaguch 	struct iavf_softc *sc = ifp->if_softc;
   1263  1.1  yamaguch 
   1264  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1265  1.1  yamaguch 
   1266  1.1  yamaguch 	ifmr->ifm_status = sc->sc_media_status;
   1267  1.1  yamaguch 	ifmr->ifm_active = sc->sc_media_active;
   1268  1.1  yamaguch }
   1269  1.1  yamaguch 
   1270  1.1  yamaguch static int
   1271  1.1  yamaguch iavf_ifflags_cb(struct ethercom *ec)
   1272  1.1  yamaguch {
   1273  1.1  yamaguch 	struct ifnet *ifp = &ec->ec_if;
   1274  1.1  yamaguch 	struct iavf_softc *sc = ifp->if_softc;
   1275  1.1  yamaguch 
   1276  1.1  yamaguch 	/* vlan hwfilter can not be disabled */
   1277  1.1  yamaguch 	SET(ec->ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1278  1.1  yamaguch 
   1279  1.1  yamaguch 	return iavf_iff(sc);
   1280  1.1  yamaguch }
   1281  1.1  yamaguch 
   1282  1.1  yamaguch static int
   1283  1.1  yamaguch iavf_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
   1284  1.1  yamaguch {
   1285  1.1  yamaguch 	struct ifnet *ifp = &ec->ec_if;
   1286  1.1  yamaguch 	struct iavf_softc *sc = ifp->if_softc;
   1287  1.1  yamaguch 	int rv;
   1288  1.1  yamaguch 
   1289  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1290  1.1  yamaguch 
   1291  1.1  yamaguch 	if (sc->sc_resetting) {
   1292  1.1  yamaguch 		mutex_exit(&sc->sc_cfg_lock);
   1293  1.1  yamaguch 
   1294  1.1  yamaguch 		/* all vlan id was already removed */
   1295  1.1  yamaguch 		if (!set)
   1296  1.1  yamaguch 			return 0;
   1297  1.1  yamaguch 
   1298  1.1  yamaguch 		return ENXIO;
   1299  1.1  yamaguch 	}
   1300  1.1  yamaguch 
   1301  1.1  yamaguch 	/* ETHERCAP_VLAN_HWFILTER can not be disabled */
   1302  1.1  yamaguch 	SET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1303  1.1  yamaguch 
   1304  1.1  yamaguch 	if (set) {
   1305  1.1  yamaguch 		rv = iavf_config_vlan_id(sc, vid, IAVF_VC_OP_ADD_VLAN);
   1306  1.1  yamaguch 		if (!ISSET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWTAGGING)) {
   1307  1.1  yamaguch 			iavf_config_vlan_stripping(sc,
   1308  1.1  yamaguch 			    sc->sc_ec.ec_capenable);
   1309  1.1  yamaguch 		}
   1310  1.1  yamaguch 	} else {
   1311  1.1  yamaguch 		rv = iavf_config_vlan_id(sc, vid, IAVF_VC_OP_DEL_VLAN);
   1312  1.1  yamaguch 	}
   1313  1.1  yamaguch 
   1314  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1315  1.1  yamaguch 
   1316  1.1  yamaguch 	if (rv != 0)
   1317  1.1  yamaguch 		return EIO;
   1318  1.1  yamaguch 
   1319  1.1  yamaguch 	return 0;
   1320  1.1  yamaguch }
   1321  1.1  yamaguch 
   1322  1.1  yamaguch static int
   1323  1.1  yamaguch iavf_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1324  1.1  yamaguch {
   1325  1.1  yamaguch 	struct ifreq *ifr = (struct ifreq *)data;
   1326  1.1  yamaguch 	struct iavf_softc *sc = (struct iavf_softc *)ifp->if_softc;
   1327  1.1  yamaguch 	const struct sockaddr *sa;
   1328  1.1  yamaguch 	uint8_t addrhi[ETHER_ADDR_LEN], addrlo[ETHER_ADDR_LEN];
   1329  1.1  yamaguch 	int s, error = 0;
   1330  1.1  yamaguch 	unsigned int nmtu;
   1331  1.1  yamaguch 
   1332  1.1  yamaguch 	switch (cmd) {
   1333  1.1  yamaguch 	case SIOCSIFMTU:
   1334  1.1  yamaguch 		nmtu = ifr->ifr_mtu;
   1335  1.1  yamaguch 
   1336  1.1  yamaguch 		if (nmtu < IAVF_MIN_MTU || nmtu > IAVF_MAX_MTU) {
   1337  1.1  yamaguch 			error = EINVAL;
   1338  1.1  yamaguch 			break;
   1339  1.1  yamaguch 		}
   1340  1.1  yamaguch 		if (ifp->if_mtu != nmtu) {
   1341  1.1  yamaguch 			s = splnet();
   1342  1.1  yamaguch 			error = ether_ioctl(ifp, cmd, data);
   1343  1.1  yamaguch 			splx(s);
   1344  1.1  yamaguch 			if (error == ENETRESET)
   1345  1.1  yamaguch 				error = iavf_init(ifp);
   1346  1.1  yamaguch 		}
   1347  1.1  yamaguch 		break;
   1348  1.1  yamaguch 	case SIOCADDMULTI:
   1349  1.1  yamaguch 		sa = ifreq_getaddr(SIOCADDMULTI, ifr);
   1350  1.1  yamaguch 		if (ether_addmulti(sa, &sc->sc_ec) == ENETRESET) {
   1351  1.1  yamaguch 			error = ether_multiaddr(sa, addrlo, addrhi);
   1352  1.1  yamaguch 			if (error != 0)
   1353  1.1  yamaguch 				return error;
   1354  1.1  yamaguch 
   1355  1.1  yamaguch 			error = iavf_add_multi(sc, addrlo, addrhi);
   1356  1.1  yamaguch 			if (error != 0 && error != ENETRESET) {
   1357  1.1  yamaguch 				ether_delmulti(sa, &sc->sc_ec);
   1358  1.1  yamaguch 				error = EIO;
   1359  1.1  yamaguch 			}
   1360  1.1  yamaguch 		}
   1361  1.1  yamaguch 		break;
   1362  1.1  yamaguch 
   1363  1.1  yamaguch 	case SIOCDELMULTI:
   1364  1.1  yamaguch 		sa = ifreq_getaddr(SIOCDELMULTI, ifr);
   1365  1.1  yamaguch 		if (ether_delmulti(sa, &sc->sc_ec) == ENETRESET) {
   1366  1.1  yamaguch 			error = ether_multiaddr(sa, addrlo, addrhi);
   1367  1.1  yamaguch 			if (error != 0)
   1368  1.1  yamaguch 				return error;
   1369  1.1  yamaguch 
   1370  1.1  yamaguch 			error = iavf_del_multi(sc, addrlo, addrhi);
   1371  1.1  yamaguch 		}
   1372  1.1  yamaguch 		break;
   1373  1.1  yamaguch 
   1374  1.1  yamaguch 	default:
   1375  1.1  yamaguch 		s = splnet();
   1376  1.1  yamaguch 		error = ether_ioctl(ifp, cmd, data);
   1377  1.1  yamaguch 		splx(s);
   1378  1.1  yamaguch 	}
   1379  1.1  yamaguch 
   1380  1.1  yamaguch 	if (error == ENETRESET)
   1381  1.1  yamaguch 		error = iavf_iff(sc);
   1382  1.1  yamaguch 
   1383  1.1  yamaguch 	return error;
   1384  1.1  yamaguch }
   1385  1.1  yamaguch 
   1386  1.1  yamaguch static int
   1387  1.1  yamaguch iavf_iff(struct iavf_softc *sc)
   1388  1.1  yamaguch {
   1389  1.1  yamaguch 	int error;
   1390  1.1  yamaguch 
   1391  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1392  1.1  yamaguch 	error = iavf_iff_locked(sc);
   1393  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1394  1.1  yamaguch 
   1395  1.1  yamaguch 	return error;
   1396  1.1  yamaguch }
   1397  1.1  yamaguch 
   1398  1.1  yamaguch static int
   1399  1.1  yamaguch iavf_iff_locked(struct iavf_softc *sc)
   1400  1.1  yamaguch {
   1401  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1402  1.1  yamaguch 	int unicast, multicast;
   1403  1.1  yamaguch 	const uint8_t *enaddr;
   1404  1.1  yamaguch 
   1405  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1406  1.1  yamaguch 
   1407  1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
   1408  1.1  yamaguch 		return 0;
   1409  1.1  yamaguch 
   1410  1.1  yamaguch 	unicast = 0;
   1411  1.1  yamaguch 	multicast = 0;
   1412  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_PROMISC)) {
   1413  1.1  yamaguch 		unicast = 1;
   1414  1.1  yamaguch 		multicast = 1;
   1415  1.1  yamaguch 	} else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) {
   1416  1.1  yamaguch 		multicast = 1;
   1417  1.1  yamaguch 	}
   1418  1.1  yamaguch 
   1419  1.1  yamaguch 	iavf_config_promisc_mode(sc, unicast, multicast);
   1420  1.1  yamaguch 
   1421  1.1  yamaguch 	iavf_config_vlan_stripping(sc, sc->sc_ec.ec_capenable);
   1422  1.1  yamaguch 
   1423  1.1  yamaguch 	enaddr = CLLADDR(ifp->if_sadl);
   1424  1.1  yamaguch 	if (memcmp(enaddr, sc->sc_enaddr_added, ETHER_ADDR_LEN) != 0) {
   1425  1.1  yamaguch 		if (!iavf_is_etheranyaddr(sc->sc_enaddr_added)) {
   1426  1.1  yamaguch 			iavf_eth_addr(sc, sc->sc_enaddr_added,
   1427  1.1  yamaguch 			    IAVF_VC_OP_DEL_ETH_ADDR);
   1428  1.1  yamaguch 		}
   1429  1.1  yamaguch 		memcpy(sc->sc_enaddr_added, enaddr, ETHER_ADDR_LEN);
   1430  1.1  yamaguch 		iavf_eth_addr(sc, enaddr, IAVF_VC_OP_ADD_ETH_ADDR);
   1431  1.1  yamaguch 	}
   1432  1.1  yamaguch 
   1433  1.1  yamaguch 	return 0;
   1434  1.1  yamaguch }
   1435  1.1  yamaguch 
   1436  1.1  yamaguch static const struct iavf_product *
   1437  1.1  yamaguch iavf_lookup(const struct pci_attach_args *pa)
   1438  1.1  yamaguch {
   1439  1.1  yamaguch 	const struct iavf_product *iavfp;
   1440  1.1  yamaguch 
   1441  1.1  yamaguch 	for (iavfp = iavf_products; iavfp->vendor_id != 0; iavfp++) {
   1442  1.1  yamaguch 		if (PCI_VENDOR(pa->pa_id) == iavfp->vendor_id &&
   1443  1.1  yamaguch 		    PCI_PRODUCT(pa->pa_id) == iavfp->product_id)
   1444  1.1  yamaguch 			return iavfp;
   1445  1.1  yamaguch 	}
   1446  1.1  yamaguch 
   1447  1.1  yamaguch 	return NULL;
   1448  1.1  yamaguch }
   1449  1.1  yamaguch 
   1450  1.1  yamaguch static enum i40e_mac_type
   1451  1.1  yamaguch iavf_mactype(pci_product_id_t id)
   1452  1.1  yamaguch {
   1453  1.1  yamaguch 
   1454  1.1  yamaguch 	switch (id) {
   1455  1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_VF:
   1456  1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_VF_HV:
   1457  1.1  yamaguch 		return I40E_MAC_VF;
   1458  1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_VF:
   1459  1.1  yamaguch 		return I40E_MAC_X722_VF;
   1460  1.1  yamaguch 	}
   1461  1.1  yamaguch 
   1462  1.1  yamaguch 	return I40E_MAC_GENERIC;
   1463  1.1  yamaguch }
   1464  1.1  yamaguch 
   1465  1.1  yamaguch static const struct iavf_link_speed *
   1466  1.1  yamaguch iavf_find_link_speed(struct iavf_softc *sc, uint32_t link_speed)
   1467  1.1  yamaguch {
   1468  1.1  yamaguch 	size_t i;
   1469  1.1  yamaguch 
   1470  1.1  yamaguch 	for (i = 0; i < __arraycount(iavf_link_speeds); i++) {
   1471  1.1  yamaguch 		if (link_speed & (1 << i))
   1472  1.1  yamaguch 			return (&iavf_link_speeds[i]);
   1473  1.1  yamaguch 	}
   1474  1.1  yamaguch 
   1475  1.1  yamaguch 	return NULL;
   1476  1.1  yamaguch }
   1477  1.1  yamaguch 
   1478  1.1  yamaguch static void
   1479  1.1  yamaguch iavf_pci_csr_setup(pci_chipset_tag_t pc, pcitag_t tag)
   1480  1.1  yamaguch {
   1481  1.1  yamaguch 	pcireg_t csr;
   1482  1.1  yamaguch 
   1483  1.1  yamaguch 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
   1484  1.1  yamaguch 	csr |= (PCI_COMMAND_MASTER_ENABLE |
   1485  1.1  yamaguch 	    PCI_COMMAND_MEM_ENABLE);
   1486  1.1  yamaguch 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
   1487  1.1  yamaguch }
   1488  1.1  yamaguch 
   1489  1.1  yamaguch static int
   1490  1.1  yamaguch iavf_wait_active(struct iavf_softc *sc)
   1491  1.1  yamaguch {
   1492  1.1  yamaguch 	int tries;
   1493  1.1  yamaguch 	uint32_t reg;
   1494  1.1  yamaguch 
   1495  1.1  yamaguch 	for (tries = 0; tries < 100; tries++) {
   1496  1.1  yamaguch 		reg = iavf_rd(sc, I40E_VFGEN_RSTAT) &
   1497  1.1  yamaguch 		    I40E_VFGEN_RSTAT_VFR_STATE_MASK;
   1498  1.1  yamaguch 		if (reg == IAVF_VFR_VFACTIVE ||
   1499  1.1  yamaguch 		    reg == IAVF_VFR_COMPLETED)
   1500  1.1  yamaguch 			return 0;
   1501  1.1  yamaguch 
   1502  1.1  yamaguch 		delaymsec(10);
   1503  1.1  yamaguch 	}
   1504  1.1  yamaguch 
   1505  1.1  yamaguch 	return -1;
   1506  1.1  yamaguch }
   1507  1.1  yamaguch 
   1508  1.1  yamaguch static bool
   1509  1.1  yamaguch iavf_is_etheranyaddr(const uint8_t *enaddr)
   1510  1.1  yamaguch {
   1511  1.1  yamaguch 	static const uint8_t etheranyaddr[ETHER_ADDR_LEN] = {
   1512  1.1  yamaguch 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   1513  1.1  yamaguch 	};
   1514  1.1  yamaguch 
   1515  1.1  yamaguch 	if (memcmp(enaddr, etheranyaddr, ETHER_ADDR_LEN) != 0)
   1516  1.1  yamaguch 		return false;
   1517  1.1  yamaguch 
   1518  1.1  yamaguch 	return true;
   1519  1.1  yamaguch }
   1520  1.1  yamaguch 
   1521  1.1  yamaguch static void
   1522  1.1  yamaguch iavf_prepare_fakeaddr(struct iavf_softc *sc)
   1523  1.1  yamaguch {
   1524  1.1  yamaguch 	uint64_t rndval;
   1525  1.1  yamaguch 
   1526  1.1  yamaguch 	if (!iavf_is_etheranyaddr(sc->sc_enaddr_fake))
   1527  1.1  yamaguch 		return;
   1528  1.1  yamaguch 
   1529  1.1  yamaguch 	rndval = cprng_strong64();
   1530  1.1  yamaguch 
   1531  1.1  yamaguch 	memcpy(sc->sc_enaddr_fake, &rndval, sizeof(sc->sc_enaddr_fake));
   1532  1.1  yamaguch 	sc->sc_enaddr_fake[0] &= 0xFE;
   1533  1.1  yamaguch 	sc->sc_enaddr_fake[0] |= 0x02;
   1534  1.1  yamaguch }
   1535  1.1  yamaguch 
   1536  1.1  yamaguch static int
   1537  1.1  yamaguch iavf_replace_lla(struct ifnet *ifp, const uint8_t *prev, const uint8_t *next)
   1538  1.1  yamaguch {
   1539  1.1  yamaguch 	union {
   1540  1.1  yamaguch 		struct sockaddr sa;
   1541  1.1  yamaguch 		struct sockaddr_dl sdl;
   1542  1.1  yamaguch 		struct sockaddr_storage ss;
   1543  1.1  yamaguch 	} u;
   1544  1.1  yamaguch 	struct psref psref_prev, psref_next;
   1545  1.1  yamaguch 	struct ifaddr *ifa_prev, *ifa_next;
   1546  1.1  yamaguch 	const struct sockaddr_dl *nsdl;
   1547  1.1  yamaguch 	int s, error;
   1548  1.1  yamaguch 
   1549  1.1  yamaguch 	KASSERT(IFNET_LOCKED(ifp));
   1550  1.1  yamaguch 
   1551  1.1  yamaguch 	error = 0;
   1552  1.1  yamaguch 	ifa_prev = ifa_next = NULL;
   1553  1.1  yamaguch 
   1554  1.1  yamaguch 	if (memcmp(prev, next, ETHER_ADDR_LEN) == 0) {
   1555  1.1  yamaguch 		goto done;
   1556  1.1  yamaguch 	}
   1557  1.1  yamaguch 
   1558  1.1  yamaguch 	if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index,
   1559  1.1  yamaguch 	    ifp->if_type, ifp->if_xname, strlen(ifp->if_xname),
   1560  1.1  yamaguch 	    prev, ETHER_ADDR_LEN) == NULL) {
   1561  1.1  yamaguch 		error = EINVAL;
   1562  1.1  yamaguch 		goto done;
   1563  1.1  yamaguch 	}
   1564  1.1  yamaguch 
   1565  1.1  yamaguch 	s = pserialize_read_enter();
   1566  1.1  yamaguch 	IFADDR_READER_FOREACH(ifa_prev, ifp) {
   1567  1.1  yamaguch 		if (sockaddr_cmp(&u.sa, ifa_prev->ifa_addr) == 0) {
   1568  1.1  yamaguch 			ifa_acquire(ifa_prev, &psref_prev);
   1569  1.1  yamaguch 			break;
   1570  1.1  yamaguch 		}
   1571  1.1  yamaguch 	}
   1572  1.1  yamaguch 	pserialize_read_exit(s);
   1573  1.1  yamaguch 
   1574  1.1  yamaguch 	if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index,
   1575  1.1  yamaguch 	    ifp->if_type, ifp->if_xname, strlen(ifp->if_xname),
   1576  1.1  yamaguch 	    next, ETHER_ADDR_LEN) == NULL) {
   1577  1.1  yamaguch 		error = EINVAL;
   1578  1.1  yamaguch 		goto done;
   1579  1.1  yamaguch 	}
   1580  1.1  yamaguch 
   1581  1.1  yamaguch 	s = pserialize_read_enter();
   1582  1.1  yamaguch 	IFADDR_READER_FOREACH(ifa_next, ifp) {
   1583  1.1  yamaguch 		if (sockaddr_cmp(&u.sa, ifa_next->ifa_addr) == 0) {
   1584  1.1  yamaguch 			ifa_acquire(ifa_next, &psref_next);
   1585  1.1  yamaguch 			break;
   1586  1.1  yamaguch 		}
   1587  1.1  yamaguch 	}
   1588  1.1  yamaguch 	pserialize_read_exit(s);
   1589  1.1  yamaguch 
   1590  1.1  yamaguch 	if (ifa_next == NULL) {
   1591  1.1  yamaguch 		nsdl = &u.sdl;
   1592  1.1  yamaguch 		ifa_next = if_dl_create(ifp, &nsdl);
   1593  1.1  yamaguch 		if (ifa_next == NULL) {
   1594  1.1  yamaguch 			error = ENOMEM;
   1595  1.1  yamaguch 			goto done;
   1596  1.1  yamaguch 		}
   1597  1.1  yamaguch 
   1598  1.1  yamaguch 		s = pserialize_read_enter();
   1599  1.1  yamaguch 		ifa_acquire(ifa_next, &psref_next);
   1600  1.1  yamaguch 		pserialize_read_exit(s);
   1601  1.1  yamaguch 
   1602  1.1  yamaguch 		sockaddr_copy(ifa_next->ifa_addr,
   1603  1.1  yamaguch 		    ifa_next->ifa_addr->sa_len, &u.sa);
   1604  1.1  yamaguch 		ifa_insert(ifp, ifa_next);
   1605  1.1  yamaguch 	} else {
   1606  1.1  yamaguch 		nsdl = NULL;
   1607  1.1  yamaguch 	}
   1608  1.1  yamaguch 
   1609  1.1  yamaguch 	if (ifa_prev != NULL && ifa_prev == ifp->if_dl) {
   1610  1.1  yamaguch 		if_activate_sadl(ifp, ifa_next, nsdl);
   1611  1.1  yamaguch 	}
   1612  1.1  yamaguch 
   1613  1.1  yamaguch 	ifa_release(ifa_next, &psref_next);
   1614  1.1  yamaguch 	ifa_next = NULL;
   1615  1.1  yamaguch 
   1616  1.1  yamaguch 	if (ifa_prev != NULL && ifa_prev != ifp->if_hwdl) {
   1617  1.1  yamaguch 		ifaref(ifa_prev);
   1618  1.1  yamaguch 		ifa_release(ifa_prev, &psref_prev);
   1619  1.1  yamaguch 		ifa_remove(ifp, ifa_prev);
   1620  1.1  yamaguch 		KASSERTMSG(ifa_prev->ifa_refcnt == 1, "ifa_refcnt=%d",
   1621  1.1  yamaguch 		   ifa_prev->ifa_refcnt);
   1622  1.1  yamaguch 		ifafree(ifa_prev);
   1623  1.1  yamaguch 		ifa_prev = NULL;
   1624  1.1  yamaguch 	}
   1625  1.1  yamaguch 
   1626  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_RUNNING))
   1627  1.1  yamaguch 		error = ENETRESET;
   1628  1.1  yamaguch 
   1629  1.1  yamaguch done:
   1630  1.1  yamaguch 	if (ifa_prev != NULL)
   1631  1.1  yamaguch 		ifa_release(ifa_prev, &psref_prev);
   1632  1.1  yamaguch 	if (ifa_next != NULL)
   1633  1.1  yamaguch 		ifa_release(ifa_next, &psref_next);
   1634  1.1  yamaguch 
   1635  1.1  yamaguch 	return error;
   1636  1.1  yamaguch }
   1637  1.1  yamaguch static int
   1638  1.1  yamaguch iavf_add_multi(struct iavf_softc *sc, uint8_t *addrlo, uint8_t *addrhi)
   1639  1.1  yamaguch {
   1640  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1641  1.1  yamaguch 	int rv;
   1642  1.1  yamaguch 
   1643  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_ALLMULTI))
   1644  1.1  yamaguch 		return 0;
   1645  1.1  yamaguch 
   1646  1.1  yamaguch 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) {
   1647  1.1  yamaguch 		iavf_del_all_multi(sc);
   1648  1.1  yamaguch 		SET(ifp->if_flags, IFF_ALLMULTI);
   1649  1.1  yamaguch 		return ENETRESET;
   1650  1.1  yamaguch 	}
   1651  1.1  yamaguch 
   1652  1.1  yamaguch 	rv = iavf_eth_addr(sc, addrlo, IAVF_VC_OP_ADD_ETH_ADDR);
   1653  1.1  yamaguch 
   1654  1.1  yamaguch 	if (rv == ENOSPC) {
   1655  1.1  yamaguch 		iavf_del_all_multi(sc);
   1656  1.1  yamaguch 		SET(ifp->if_flags, IFF_ALLMULTI);
   1657  1.1  yamaguch 		return ENETRESET;
   1658  1.1  yamaguch 	}
   1659  1.1  yamaguch 
   1660  1.1  yamaguch 	return rv;
   1661  1.1  yamaguch }
   1662  1.1  yamaguch 
   1663  1.1  yamaguch static int
   1664  1.1  yamaguch iavf_del_multi(struct iavf_softc *sc, uint8_t *addrlo, uint8_t *addrhi)
   1665  1.1  yamaguch {
   1666  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1667  1.1  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   1668  1.1  yamaguch 	struct ether_multi *enm, *enm_last;
   1669  1.1  yamaguch 	struct ether_multistep step;
   1670  1.1  yamaguch 	int error, rv = 0;
   1671  1.1  yamaguch 
   1672  1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) {
   1673  1.1  yamaguch 		if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
   1674  1.1  yamaguch 			return 0;
   1675  1.1  yamaguch 
   1676  1.1  yamaguch 		iavf_eth_addr(sc, addrlo, IAVF_VC_OP_DEL_ETH_ADDR);
   1677  1.1  yamaguch 		return 0;
   1678  1.1  yamaguch 	}
   1679  1.1  yamaguch 
   1680  1.1  yamaguch 	ETHER_LOCK(ec);
   1681  1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1682  1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1683  1.1  yamaguch 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1684  1.1  yamaguch 		    ETHER_ADDR_LEN) != 0) {
   1685  1.1  yamaguch 			goto out;
   1686  1.1  yamaguch 		}
   1687  1.1  yamaguch 	}
   1688  1.1  yamaguch 
   1689  1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1690  1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1691  1.1  yamaguch 		error = iavf_eth_addr(sc, enm->enm_addrlo,
   1692  1.1  yamaguch 		    IAVF_VC_OP_ADD_ETH_ADDR);
   1693  1.1  yamaguch 		if (error != 0)
   1694  1.1  yamaguch 			break;
   1695  1.1  yamaguch 	}
   1696  1.1  yamaguch 
   1697  1.1  yamaguch 	if (enm != NULL) {
   1698  1.1  yamaguch 		enm_last = enm;
   1699  1.1  yamaguch 		for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1700  1.1  yamaguch 		    ETHER_NEXT_MULTI(step, enm)) {
   1701  1.1  yamaguch 			if (enm == enm_last)
   1702  1.1  yamaguch 				break;
   1703  1.1  yamaguch 
   1704  1.1  yamaguch 			iavf_eth_addr(sc, enm->enm_addrlo,
   1705  1.1  yamaguch 			    IAVF_VC_OP_DEL_ETH_ADDR);
   1706  1.1  yamaguch 		}
   1707  1.1  yamaguch 	} else {
   1708  1.1  yamaguch 		CLR(ifp->if_flags, IFF_ALLMULTI);
   1709  1.1  yamaguch 		rv = ENETRESET;
   1710  1.1  yamaguch 	}
   1711  1.1  yamaguch 
   1712  1.1  yamaguch out:
   1713  1.1  yamaguch 	ETHER_UNLOCK(ec);
   1714  1.1  yamaguch 	return rv;
   1715  1.1  yamaguch }
   1716  1.1  yamaguch 
   1717  1.1  yamaguch static void
   1718  1.1  yamaguch iavf_del_all_multi(struct iavf_softc *sc)
   1719  1.1  yamaguch {
   1720  1.1  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   1721  1.1  yamaguch 	struct ether_multi *enm;
   1722  1.1  yamaguch 	struct ether_multistep step;
   1723  1.1  yamaguch 
   1724  1.1  yamaguch 	ETHER_LOCK(ec);
   1725  1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1726  1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1727  1.1  yamaguch 		iavf_eth_addr(sc, enm->enm_addrlo,
   1728  1.1  yamaguch 		    IAVF_VC_OP_DEL_ETH_ADDR);
   1729  1.1  yamaguch 	}
   1730  1.1  yamaguch 	ETHER_UNLOCK(ec);
   1731  1.1  yamaguch }
   1732  1.1  yamaguch 
   1733  1.1  yamaguch static int
   1734  1.1  yamaguch iavf_setup_interrupts(struct iavf_softc *sc)
   1735  1.1  yamaguch {
   1736  1.1  yamaguch 	struct pci_attach_args *pa;
   1737  1.1  yamaguch 	kcpuset_t *affinity = NULL;
   1738  1.1  yamaguch 	char intrbuf[PCI_INTRSTR_LEN], xnamebuf[32];
   1739  1.1  yamaguch 	char const *intrstr;
   1740  1.1  yamaguch 	int counts[PCI_INTR_TYPE_SIZE];
   1741  1.1  yamaguch 	int error, affinity_to;
   1742  1.1  yamaguch 	unsigned int vector, qid, num;
   1743  1.1  yamaguch 
   1744  1.1  yamaguch 	/* queue pairs + misc interrupt */
   1745  1.1  yamaguch 	num = sc->sc_nqps_alloc + 1;
   1746  1.1  yamaguch 
   1747  1.1  yamaguch 	num = MIN(num, iavf_calc_msix_count(sc));
   1748  1.1  yamaguch 	if (num <= 0) {
   1749  1.1  yamaguch 		return -1;
   1750  1.1  yamaguch 	}
   1751  1.1  yamaguch 
   1752  1.1  yamaguch 	KASSERT(sc->sc_nqps_alloc > 0);
   1753  1.1  yamaguch 	num = MIN(num, sc->sc_nqps_alloc + 1);
   1754  1.1  yamaguch 
   1755  1.1  yamaguch 	pa = &sc->sc_pa;
   1756  1.1  yamaguch 	memset(counts, 0, sizeof(counts));
   1757  1.1  yamaguch 	counts[PCI_INTR_TYPE_MSIX] = num;
   1758  1.1  yamaguch 
   1759  1.1  yamaguch 	error = pci_intr_alloc(pa, &sc->sc_ihp, counts, PCI_INTR_TYPE_MSIX);
   1760  1.1  yamaguch 	if (error != 0) {
   1761  1.1  yamaguch 		IAVF_LOG(sc, LOG_WARNING, "couldn't allocate interrupts\n");
   1762  1.1  yamaguch 		return -1;
   1763  1.1  yamaguch 	}
   1764  1.1  yamaguch 
   1765  1.1  yamaguch 	KASSERT(pci_intr_type(pa->pa_pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX);
   1766  1.1  yamaguch 
   1767  1.1  yamaguch 	if (counts[PCI_INTR_TYPE_MSIX] < 1) {
   1768  1.1  yamaguch 		IAVF_LOG(sc, LOG_ERR, "couldn't allocate interrupts\n");
   1769  1.1  yamaguch 	} else if (counts[PCI_INTR_TYPE_MSIX] != (int)num) {
   1770  1.1  yamaguch 		IAVF_LOG(sc, LOG_DEBUG,
   1771  1.1  yamaguch 		    "request %u intruppts, but allocate %d interrupts\n",
   1772  1.1  yamaguch 		    num, counts[PCI_INTR_TYPE_MSIX]);
   1773  1.1  yamaguch 		num = counts[PCI_INTR_TYPE_MSIX];
   1774  1.1  yamaguch 	}
   1775  1.1  yamaguch 
   1776  1.1  yamaguch 	sc->sc_ihs = kmem_alloc(sizeof(sc->sc_ihs[0]) * num, KM_NOSLEEP);
   1777  1.1  yamaguch 	if (sc->sc_ihs == NULL) {
   1778  1.1  yamaguch 		IAVF_LOG(sc, LOG_ERR,
   1779  1.1  yamaguch 		    "couldn't allocate memory for interrupts\n");
   1780  1.1  yamaguch 		goto fail;
   1781  1.1  yamaguch 	}
   1782  1.1  yamaguch 
   1783  1.1  yamaguch 	/* vector #0 is Misc interrupt */
   1784  1.1  yamaguch 	vector = 0;
   1785  1.1  yamaguch 	pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[vector], PCI_INTR_MPSAFE, true);
   1786  1.1  yamaguch 	intrstr = pci_intr_string(pa->pa_pc, sc->sc_ihp[vector],
   1787  1.1  yamaguch 	    intrbuf, sizeof(intrbuf));
   1788  1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s-Misc",
   1789  1.1  yamaguch 	    device_xname(sc->sc_dev));
   1790  1.1  yamaguch 
   1791  1.1  yamaguch 	sc->sc_ihs[vector] = pci_intr_establish_xname(pa->pa_pc,
   1792  1.1  yamaguch 	    sc->sc_ihp[vector], IPL_NET, iavf_intr, sc, xnamebuf);
   1793  1.1  yamaguch 	if (sc->sc_ihs[vector] == NULL) {
   1794  1.1  yamaguch 		IAVF_LOG(sc, LOG_WARNING,
   1795  1.1  yamaguch 		    "unable to establish interrupt at %s", intrstr);
   1796  1.1  yamaguch 		goto fail;
   1797  1.1  yamaguch 	}
   1798  1.1  yamaguch 
   1799  1.1  yamaguch 	kcpuset_create(&affinity, false);
   1800  1.1  yamaguch 	affinity_to = ((int)num <= ncpu) ? 1 : 0;
   1801  1.1  yamaguch 	qid = 0;
   1802  1.1  yamaguch 	for (vector = 1; vector < num; vector++) {
   1803  1.1  yamaguch 		pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[vector],
   1804  1.1  yamaguch 		    PCI_INTR_MPSAFE, true);
   1805  1.1  yamaguch 		intrstr = pci_intr_string(pa->pa_pc, sc->sc_ihp[vector],
   1806  1.1  yamaguch 		    intrbuf, sizeof(intrbuf));
   1807  1.1  yamaguch 		snprintf(xnamebuf, sizeof(xnamebuf), "%s-TXRX%u",
   1808  1.1  yamaguch 		    device_xname(sc->sc_dev), qid);
   1809  1.1  yamaguch 
   1810  1.1  yamaguch 		sc->sc_ihs[vector] = pci_intr_establish_xname(pa->pa_pc,
   1811  1.1  yamaguch 		    sc->sc_ihp[vector], IPL_NET, iavf_queue_intr,
   1812  1.1  yamaguch 		    (void *)&sc->sc_qps[qid], xnamebuf);
   1813  1.1  yamaguch 		if (sc->sc_ihs[vector] == NULL) {
   1814  1.1  yamaguch 			IAVF_LOG(sc, LOG_WARNING,
   1815  1.1  yamaguch 			    "unable to establish interrupt at %s\n", intrstr);
   1816  1.1  yamaguch 			goto fail;
   1817  1.1  yamaguch 		}
   1818  1.1  yamaguch 
   1819  1.1  yamaguch 		kcpuset_zero(affinity);
   1820  1.1  yamaguch 		kcpuset_set(affinity, affinity_to);
   1821  1.1  yamaguch 		error = interrupt_distribute(sc->sc_ihs[vector],
   1822  1.1  yamaguch 		    affinity, NULL);
   1823  1.1  yamaguch 
   1824  1.1  yamaguch 		if (error == 0) {
   1825  1.1  yamaguch 			IAVF_LOG(sc, LOG_INFO,
   1826  1.1  yamaguch 			    "for TXRX%d interrupt at %s, affinity to %d\n",
   1827  1.1  yamaguch 			    qid, intrstr, affinity_to);
   1828  1.1  yamaguch 		} else {
   1829  1.1  yamaguch 			IAVF_LOG(sc, LOG_INFO,
   1830  1.1  yamaguch 			    "for TXRX%d interrupt at %s\n",
   1831  1.1  yamaguch 			    qid, intrstr);
   1832  1.1  yamaguch 		}
   1833  1.1  yamaguch 
   1834  1.1  yamaguch 		qid++;
   1835  1.1  yamaguch 		affinity_to = (affinity_to + 1) % ncpu;
   1836  1.1  yamaguch 	}
   1837  1.1  yamaguch 
   1838  1.1  yamaguch 	kcpuset_destroy(affinity);
   1839  1.1  yamaguch 
   1840  1.1  yamaguch 	sc->sc_nintrs = num;
   1841  1.1  yamaguch 	return 0;
   1842  1.1  yamaguch 
   1843  1.1  yamaguch fail:
   1844  1.1  yamaguch 	if (affinity != NULL)
   1845  1.1  yamaguch 		kcpuset_destroy(affinity);
   1846  1.1  yamaguch 	for (vector = 0; vector < num; vector++) {
   1847  1.1  yamaguch 		if (sc->sc_ihs[vector] == NULL)
   1848  1.1  yamaguch 			continue;
   1849  1.1  yamaguch 		pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[vector]);
   1850  1.1  yamaguch 	}
   1851  1.1  yamaguch 	kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * num);
   1852  1.1  yamaguch 	pci_intr_release(pa->pa_pc, sc->sc_ihp, num);
   1853  1.1  yamaguch 
   1854  1.1  yamaguch 	return -1;
   1855  1.1  yamaguch }
   1856  1.1  yamaguch 
   1857  1.1  yamaguch static void
   1858  1.1  yamaguch iavf_teardown_interrupts(struct iavf_softc *sc)
   1859  1.1  yamaguch {
   1860  1.1  yamaguch 	struct pci_attach_args *pa;
   1861  1.1  yamaguch 	unsigned int i;
   1862  1.1  yamaguch 
   1863  1.1  yamaguch 	if (sc->sc_ihs == NULL)
   1864  1.1  yamaguch 		return;
   1865  1.1  yamaguch 
   1866  1.1  yamaguch 	pa = &sc->sc_pa;
   1867  1.1  yamaguch 
   1868  1.1  yamaguch 	for (i = 0; i < sc->sc_nintrs; i++) {
   1869  1.1  yamaguch 		pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[i]);
   1870  1.1  yamaguch 	}
   1871  1.1  yamaguch 
   1872  1.1  yamaguch 	kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * sc->sc_nintrs);
   1873  1.1  yamaguch 	sc->sc_ihs = NULL;
   1874  1.1  yamaguch 
   1875  1.1  yamaguch 	pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs);
   1876  1.1  yamaguch 	sc->sc_nintrs = 0;
   1877  1.1  yamaguch }
   1878  1.1  yamaguch 
   1879  1.1  yamaguch static int
   1880  1.1  yamaguch iavf_setup_sysctls(struct iavf_softc *sc)
   1881  1.1  yamaguch {
   1882  1.1  yamaguch 	const char *devname;
   1883  1.1  yamaguch 	struct sysctllog **log;
   1884  1.1  yamaguch 	const struct sysctlnode *rnode, *rxnode, *txnode;
   1885  1.1  yamaguch 	int error;
   1886  1.1  yamaguch 
   1887  1.1  yamaguch 	log = &sc->sc_sysctllog;
   1888  1.1  yamaguch 	devname = device_xname(sc->sc_dev);
   1889  1.1  yamaguch 
   1890  1.1  yamaguch 	error = sysctl_createv(log, 0, NULL, &rnode,
   1891  1.1  yamaguch 	    0, CTLTYPE_NODE, devname,
   1892  1.1  yamaguch 	    SYSCTL_DESCR("iavf information and settings"),
   1893  1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
   1894  1.1  yamaguch 	if (error)
   1895  1.1  yamaguch 		goto out;
   1896  1.1  yamaguch 
   1897  1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, NULL,
   1898  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue",
   1899  1.1  yamaguch 	    SYSCTL_DESCR("Use workqueue for packet processing"),
   1900  1.1  yamaguch 	    NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL);
   1901  1.1  yamaguch 	if (error)
   1902  1.1  yamaguch 		goto out;
   1903  1.1  yamaguch 
   1904  1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, NULL,
   1905  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug_level",
   1906  1.1  yamaguch 	    SYSCTL_DESCR("Debug level"),
   1907  1.1  yamaguch 	    NULL, 0, &sc->sc_debuglevel, 0, CTL_CREATE, CTL_EOL);
   1908  1.1  yamaguch 	if (error)
   1909  1.1  yamaguch 		goto out;
   1910  1.1  yamaguch 
   1911  1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, &rxnode,
   1912  1.1  yamaguch 	    0, CTLTYPE_NODE, "rx",
   1913  1.1  yamaguch 	    SYSCTL_DESCR("iavf information and settings for Rx"),
   1914  1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   1915  1.1  yamaguch 	if (error)
   1916  1.1  yamaguch 		goto out;
   1917  1.1  yamaguch 
   1918  1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   1919  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "itr",
   1920  1.1  yamaguch 	    SYSCTL_DESCR("Interrupt Throttling"),
   1921  1.1  yamaguch 	    iavf_sysctl_itr_handler, 0,
   1922  1.1  yamaguch 	    (void *)sc, 0, CTL_CREATE, CTL_EOL);
   1923  1.1  yamaguch 	if (error)
   1924  1.1  yamaguch 		goto out;
   1925  1.1  yamaguch 
   1926  1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   1927  1.1  yamaguch 	    CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num",
   1928  1.1  yamaguch 	    SYSCTL_DESCR("descriptor size"),
   1929  1.1  yamaguch 	    NULL, 0, &sc->sc_rx_ring_ndescs, 0, CTL_CREATE, CTL_EOL);
   1930  1.1  yamaguch 	if (error)
   1931  1.1  yamaguch 		goto out;
   1932  1.1  yamaguch 
   1933  1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   1934  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   1935  1.1  yamaguch 	    SYSCTL_DESCR("max number of Rx packets"
   1936  1.1  yamaguch 	    " to process for interrupt processing"),
   1937  1.1  yamaguch 	    NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   1938  1.1  yamaguch 	if (error)
   1939  1.1  yamaguch 		goto out;
   1940  1.1  yamaguch 
   1941  1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   1942  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   1943  1.1  yamaguch 	    SYSCTL_DESCR("max number of Rx packets"
   1944  1.1  yamaguch 	    " to process for deferred processing"),
   1945  1.1  yamaguch 	    NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL);
   1946  1.1  yamaguch 	if (error)
   1947  1.1  yamaguch 		goto out;
   1948  1.1  yamaguch 
   1949  1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, &txnode,
   1950  1.1  yamaguch 	    0, CTLTYPE_NODE, "tx",
   1951  1.1  yamaguch 	    SYSCTL_DESCR("iavf information and settings for Tx"),
   1952  1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   1953  1.1  yamaguch 	if (error)
   1954  1.1  yamaguch 		goto out;
   1955  1.1  yamaguch 
   1956  1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   1957  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "itr",
   1958  1.1  yamaguch 	    SYSCTL_DESCR("Interrupt Throttling"),
   1959  1.1  yamaguch 	    iavf_sysctl_itr_handler, 0,
   1960  1.1  yamaguch 	    (void *)sc, 0, CTL_CREATE, CTL_EOL);
   1961  1.1  yamaguch 	if (error)
   1962  1.1  yamaguch 		goto out;
   1963  1.1  yamaguch 
   1964  1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   1965  1.1  yamaguch 	    CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num",
   1966  1.1  yamaguch 	    SYSCTL_DESCR("the number of Tx descriptors"),
   1967  1.1  yamaguch 	    NULL, 0, &sc->sc_tx_ring_ndescs, 0, CTL_CREATE, CTL_EOL);
   1968  1.1  yamaguch 	if (error)
   1969  1.1  yamaguch 		goto out;
   1970  1.1  yamaguch 
   1971  1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   1972  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   1973  1.1  yamaguch 	    SYSCTL_DESCR("max number of Tx packets"
   1974  1.1  yamaguch 	    " to process for interrupt processing"),
   1975  1.1  yamaguch 	    NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   1976  1.1  yamaguch 	if (error)
   1977  1.1  yamaguch 		goto out;
   1978  1.1  yamaguch 
   1979  1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   1980  1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   1981  1.1  yamaguch 	    SYSCTL_DESCR("max number of Tx packets"
   1982  1.1  yamaguch 	    " to process for deferred processing"),
   1983  1.1  yamaguch 	    NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL);
   1984  1.1  yamaguch 	if (error)
   1985  1.1  yamaguch 		goto out;
   1986  1.1  yamaguch out:
   1987  1.1  yamaguch 	return error;
   1988  1.1  yamaguch }
   1989  1.1  yamaguch 
   1990  1.1  yamaguch static void
   1991  1.1  yamaguch iavf_teardown_sysctls(struct iavf_softc *sc)
   1992  1.1  yamaguch {
   1993  1.1  yamaguch 
   1994  1.1  yamaguch 	sysctl_teardown(&sc->sc_sysctllog);
   1995  1.1  yamaguch }
   1996  1.1  yamaguch 
   1997  1.1  yamaguch static int
   1998  1.1  yamaguch iavf_setup_stats(struct iavf_softc *sc)
   1999  1.1  yamaguch {
   2000  1.1  yamaguch 	struct iavf_stat_counters *isc;
   2001  1.1  yamaguch 	const char *dn;
   2002  1.1  yamaguch 
   2003  1.1  yamaguch 	dn = device_xname(sc->sc_dev);
   2004  1.1  yamaguch 	isc = &sc->sc_stat_counters;
   2005  1.1  yamaguch 
   2006  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_bytes, dn, "Rx bytes");
   2007  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_unicast, dn, "Rx unicast");
   2008  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_multicast, dn, "Rx multicast");
   2009  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_broadcast, dn, "Rx broadcast");
   2010  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_discards, dn, "Rx discards");
   2011  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_rx_unknown_protocol,
   2012  1.1  yamaguch 	    dn, "Rx unknown protocol");
   2013  1.1  yamaguch 
   2014  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_bytes, dn, "Tx bytes");
   2015  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_unicast, dn, "Tx unicast");
   2016  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_multicast, dn, "Tx multicast");
   2017  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_broadcast, dn, "Tx broadcast");
   2018  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_discards, dn, "Tx discards");
   2019  1.1  yamaguch 	iavf_evcnt_attach(&isc->isc_tx_errors, dn, "Tx errors");
   2020  1.1  yamaguch 
   2021  1.1  yamaguch 	return 0;
   2022  1.1  yamaguch }
   2023  1.1  yamaguch 
   2024  1.1  yamaguch static void
   2025  1.1  yamaguch iavf_teardown_stats(struct iavf_softc *sc)
   2026  1.1  yamaguch {
   2027  1.1  yamaguch 	struct iavf_stat_counters *isc;
   2028  1.1  yamaguch 
   2029  1.1  yamaguch 	isc = &sc->sc_stat_counters;
   2030  1.1  yamaguch 
   2031  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_bytes);
   2032  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_unicast);
   2033  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_multicast);
   2034  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_broadcast);
   2035  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_discards);
   2036  1.1  yamaguch 	evcnt_detach(&isc->isc_rx_unknown_protocol);
   2037  1.1  yamaguch 
   2038  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_bytes);
   2039  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_unicast);
   2040  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_multicast);
   2041  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_broadcast);
   2042  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_discards);
   2043  1.1  yamaguch 	evcnt_detach(&isc->isc_tx_errors);
   2044  1.1  yamaguch 
   2045  1.1  yamaguch }
   2046  1.1  yamaguch 
   2047  1.1  yamaguch static int
   2048  1.1  yamaguch iavf_init_admin_queue(struct iavf_softc *sc)
   2049  1.1  yamaguch {
   2050  1.1  yamaguch 	uint32_t reg;
   2051  1.1  yamaguch 
   2052  1.1  yamaguch 	sc->sc_atq_cons = 0;
   2053  1.1  yamaguch 	sc->sc_atq_prod = 0;
   2054  1.1  yamaguch 
   2055  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   2056  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   2057  1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2058  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   2059  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   2060  1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2061  1.1  yamaguch 
   2062  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_head, 0);
   2063  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_head, 0);
   2064  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_tail, 0);
   2065  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_tail, 0);
   2066  1.1  yamaguch 
   2067  1.1  yamaguch 	iavf_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE);
   2068  1.1  yamaguch 
   2069  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_bal,
   2070  1.1  yamaguch 	    ixl_dmamem_lo(&sc->sc_atq));
   2071  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_bah,
   2072  1.1  yamaguch 	    ixl_dmamem_hi(&sc->sc_atq));
   2073  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_len,
   2074  1.1  yamaguch 	    sc->sc_aq_regs->atq_len_enable | IAVF_AQ_NUM);
   2075  1.1  yamaguch 
   2076  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_bal,
   2077  1.1  yamaguch 	    ixl_dmamem_lo(&sc->sc_arq));
   2078  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_bah,
   2079  1.1  yamaguch 	    ixl_dmamem_hi(&sc->sc_arq));
   2080  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_len,
   2081  1.1  yamaguch 	    sc->sc_aq_regs->arq_len_enable | IAVF_AQ_NUM);
   2082  1.1  yamaguch 
   2083  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod);
   2084  1.1  yamaguch 
   2085  1.1  yamaguch 	reg = iavf_rd(sc, sc->sc_aq_regs->atq_bal);
   2086  1.1  yamaguch 	if (reg != ixl_dmamem_lo(&sc->sc_atq))
   2087  1.1  yamaguch 		goto fail;
   2088  1.1  yamaguch 
   2089  1.1  yamaguch 	reg = iavf_rd(sc, sc->sc_aq_regs->arq_bal);
   2090  1.1  yamaguch 	if (reg != ixl_dmamem_lo(&sc->sc_arq))
   2091  1.1  yamaguch 		goto fail;
   2092  1.1  yamaguch 
   2093  1.1  yamaguch 	sc->sc_dead = false;
   2094  1.1  yamaguch 	return 0;
   2095  1.1  yamaguch 
   2096  1.1  yamaguch fail:
   2097  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_len, 0);
   2098  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_len, 0);
   2099  1.1  yamaguch 	return -1;
   2100  1.1  yamaguch }
   2101  1.1  yamaguch 
   2102  1.1  yamaguch static void
   2103  1.1  yamaguch iavf_cleanup_admin_queue(struct iavf_softc *sc)
   2104  1.1  yamaguch {
   2105  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   2106  1.1  yamaguch 
   2107  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_head, 0);
   2108  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_head, 0);
   2109  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_tail, 0);
   2110  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_tail, 0);
   2111  1.1  yamaguch 
   2112  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_bal, 0);
   2113  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_bah, 0);
   2114  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_len, 0);
   2115  1.1  yamaguch 
   2116  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_bal, 0);
   2117  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_bah, 0);
   2118  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->arq_len, 0);
   2119  1.1  yamaguch 	iavf_flush(sc);
   2120  1.1  yamaguch 
   2121  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   2122  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   2123  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   2124  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   2125  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   2126  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   2127  1.1  yamaguch 
   2128  1.1  yamaguch 	sc->sc_atq_cons = 0;
   2129  1.1  yamaguch 	sc->sc_atq_prod = 0;
   2130  1.1  yamaguch 	sc->sc_arq_cons = 0;
   2131  1.1  yamaguch 	sc->sc_arq_prod = 0;
   2132  1.1  yamaguch 
   2133  1.1  yamaguch 	memset(IXL_DMA_KVA(&sc->sc_arq), 0, IXL_DMA_LEN(&sc->sc_arq));
   2134  1.1  yamaguch 	memset(IXL_DMA_KVA(&sc->sc_atq), 0, IXL_DMA_LEN(&sc->sc_atq));
   2135  1.1  yamaguch 
   2136  1.1  yamaguch 	while ((aqb = iavf_aqb_get_locked(&sc->sc_arq_live)) != NULL) {
   2137  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size,
   2138  1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   2139  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_arq_idle, aqb);
   2140  1.1  yamaguch 	}
   2141  1.1  yamaguch 
   2142  1.1  yamaguch 	while ((aqb = iavf_aqb_get_locked(&sc->sc_atq_live)) != NULL) {
   2143  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size,
   2144  1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   2145  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   2146  1.1  yamaguch 	}
   2147  1.1  yamaguch }
   2148  1.1  yamaguch 
   2149  1.1  yamaguch static unsigned int
   2150  1.1  yamaguch iavf_calc_msix_count(struct iavf_softc *sc)
   2151  1.1  yamaguch {
   2152  1.1  yamaguch 	struct pci_attach_args *pa;
   2153  1.1  yamaguch 	int count;
   2154  1.1  yamaguch 
   2155  1.1  yamaguch 	pa = &sc->sc_pa;
   2156  1.1  yamaguch 	count = pci_msix_count(pa->pa_pc, pa->pa_tag);
   2157  1.1  yamaguch 	if (count < 0) {
   2158  1.1  yamaguch 		IAVF_LOG(sc, LOG_DEBUG,"MSIX config error\n");
   2159  1.1  yamaguch 		count = 0;
   2160  1.1  yamaguch 	}
   2161  1.1  yamaguch 
   2162  1.1  yamaguch 	return MIN(sc->sc_max_vectors, (unsigned int)count);
   2163  1.1  yamaguch }
   2164  1.1  yamaguch 
   2165  1.1  yamaguch static unsigned int
   2166  1.1  yamaguch iavf_calc_queue_pair_size(struct iavf_softc *sc)
   2167  1.1  yamaguch {
   2168  1.1  yamaguch 	unsigned int nqp, nvec;
   2169  1.1  yamaguch 
   2170  1.1  yamaguch 	nvec = iavf_calc_msix_count(sc);
   2171  1.1  yamaguch 	if (sc->sc_max_vectors > 1) {
   2172  1.1  yamaguch 		/* decrease the number of misc interrupt */
   2173  1.1  yamaguch 		nvec -= 1;
   2174  1.1  yamaguch 	}
   2175  1.1  yamaguch 
   2176  1.1  yamaguch 	nqp = ncpu;
   2177  1.1  yamaguch 	nqp = MIN(nqp, sc->sc_nqps_vsi);
   2178  1.1  yamaguch 	nqp = MIN(nqp, nvec);
   2179  1.1  yamaguch 	nqp = MIN(nqp, (unsigned int)iavf_params.max_qps);
   2180  1.1  yamaguch 
   2181  1.1  yamaguch 	return nqp;
   2182  1.1  yamaguch }
   2183  1.1  yamaguch 
   2184  1.1  yamaguch static struct iavf_tx_ring *
   2185  1.1  yamaguch iavf_txr_alloc(struct iavf_softc *sc, unsigned int qid)
   2186  1.1  yamaguch {
   2187  1.1  yamaguch 	struct iavf_tx_ring *txr;
   2188  1.1  yamaguch 	struct iavf_tx_map *maps;
   2189  1.1  yamaguch 	unsigned int i;
   2190  1.1  yamaguch 	int error;
   2191  1.1  yamaguch 
   2192  1.1  yamaguch 	txr = kmem_zalloc(sizeof(*txr), KM_NOSLEEP);
   2193  1.1  yamaguch 	if (txr == NULL)
   2194  1.1  yamaguch 		return NULL;
   2195  1.1  yamaguch 
   2196  1.1  yamaguch 	maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_tx_ring_ndescs,
   2197  1.1  yamaguch 	    KM_NOSLEEP);
   2198  1.1  yamaguch 	if (maps == NULL)
   2199  1.1  yamaguch 		goto free_txr;
   2200  1.1  yamaguch 
   2201  1.1  yamaguch 	if (iavf_dmamem_alloc(sc->sc_dmat, &txr->txr_mem,
   2202  1.1  yamaguch 	    sizeof(struct ixl_tx_desc) * sc->sc_tx_ring_ndescs,
   2203  1.1  yamaguch 	    IAVF_TX_QUEUE_ALIGN) != 0) {
   2204  1.1  yamaguch 		goto free_maps;
   2205  1.1  yamaguch 	}
   2206  1.1  yamaguch 
   2207  1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2208  1.1  yamaguch 		error = bus_dmamap_create(sc->sc_dmat, IAVF_TX_PKT_MAXSIZE,
   2209  1.1  yamaguch 		    IAVF_TX_PKT_DESCS, IAVF_TX_PKT_MAXSIZE, 0,
   2210  1.1  yamaguch 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &maps[i].txm_map);
   2211  1.1  yamaguch 		if (error)
   2212  1.1  yamaguch 			goto destroy_maps;
   2213  1.1  yamaguch 	}
   2214  1.1  yamaguch 
   2215  1.1  yamaguch 	txr->txr_intrq = pcq_create(sc->sc_tx_ring_ndescs, KM_NOSLEEP);
   2216  1.1  yamaguch 	if (txr->txr_intrq == NULL)
   2217  1.1  yamaguch 		goto destroy_maps;
   2218  1.1  yamaguch 
   2219  1.1  yamaguch 	txr->txr_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
   2220  1.1  yamaguch 	    iavf_deferred_transmit, txr);
   2221  1.1  yamaguch 	if (txr->txr_si == NULL)
   2222  1.1  yamaguch 		goto destroy_pcq;
   2223  1.1  yamaguch 
   2224  1.1  yamaguch 	snprintf(txr->txr_name, sizeof(txr->txr_name), "%s-tx%d",
   2225  1.1  yamaguch 	    device_xname(sc->sc_dev), qid);
   2226  1.1  yamaguch 
   2227  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_defragged,
   2228  1.1  yamaguch 	    txr->txr_name, "m_defrag successed");
   2229  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_defrag_failed,
   2230  1.1  yamaguch 	    txr->txr_name, "m_defrag failed");
   2231  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_pcqdrop,
   2232  1.1  yamaguch 	    txr->txr_name, "Dropped in pcq");
   2233  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_transmitdef,
   2234  1.1  yamaguch 	    txr->txr_name, "Deferred transmit");
   2235  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_watchdogto,
   2236  1.1  yamaguch 	    txr->txr_name, "Watchdog timedout on queue");
   2237  1.1  yamaguch 	iavf_evcnt_attach(&txr->txr_defer,
   2238  1.1  yamaguch 	    txr->txr_name, "Handled queue in softint/workqueue");
   2239  1.1  yamaguch 
   2240  1.1  yamaguch 	evcnt_attach_dynamic(&txr->txr_intr, EVCNT_TYPE_INTR, NULL,
   2241  1.1  yamaguch 	    txr->txr_name, "Interrupt on queue");
   2242  1.1  yamaguch 
   2243  1.1  yamaguch 	txr->txr_qid = qid;
   2244  1.1  yamaguch 	txr->txr_sc = sc;
   2245  1.1  yamaguch 	txr->txr_maps = maps;
   2246  1.1  yamaguch 	txr->txr_prod = txr->txr_cons = 0;
   2247  1.1  yamaguch 	txr->txr_tail = I40E_QTX_TAIL1(qid);
   2248  1.1  yamaguch 	mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET);
   2249  1.1  yamaguch 
   2250  1.1  yamaguch 	return txr;
   2251  1.1  yamaguch destroy_pcq:
   2252  1.1  yamaguch 	pcq_destroy(txr->txr_intrq);
   2253  1.1  yamaguch destroy_maps:
   2254  1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2255  1.1  yamaguch 		if (maps[i].txm_map == NULL)
   2256  1.1  yamaguch 			continue;
   2257  1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, maps[i].txm_map);
   2258  1.1  yamaguch 	}
   2259  1.1  yamaguch 
   2260  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &txr->txr_mem);
   2261  1.1  yamaguch free_maps:
   2262  1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs);
   2263  1.1  yamaguch free_txr:
   2264  1.1  yamaguch 	kmem_free(txr, sizeof(*txr));
   2265  1.1  yamaguch 	return NULL;
   2266  1.1  yamaguch }
   2267  1.1  yamaguch 
   2268  1.1  yamaguch static void
   2269  1.1  yamaguch iavf_txr_free(struct iavf_softc *sc, struct iavf_tx_ring *txr)
   2270  1.1  yamaguch {
   2271  1.1  yamaguch 	struct iavf_tx_map *maps;
   2272  1.1  yamaguch 	unsigned int i;
   2273  1.1  yamaguch 
   2274  1.1  yamaguch 	maps = txr->txr_maps;
   2275  1.1  yamaguch 	if (maps != NULL) {
   2276  1.1  yamaguch 		for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2277  1.1  yamaguch 			if (maps[i].txm_map == NULL)
   2278  1.1  yamaguch 				continue;
   2279  1.1  yamaguch 			bus_dmamap_destroy(sc->sc_dmat, maps[i].txm_map);
   2280  1.1  yamaguch 		}
   2281  1.1  yamaguch 		kmem_free(txr->txr_maps,
   2282  1.1  yamaguch 		    sizeof(maps[0]) * sc->sc_tx_ring_ndescs);
   2283  1.1  yamaguch 		txr->txr_maps = NULL;
   2284  1.1  yamaguch 	}
   2285  1.1  yamaguch 
   2286  1.1  yamaguch 	evcnt_detach(&txr->txr_defragged);
   2287  1.1  yamaguch 	evcnt_detach(&txr->txr_defrag_failed);
   2288  1.1  yamaguch 	evcnt_detach(&txr->txr_pcqdrop);
   2289  1.1  yamaguch 	evcnt_detach(&txr->txr_transmitdef);
   2290  1.1  yamaguch 	evcnt_detach(&txr->txr_watchdogto);
   2291  1.1  yamaguch 	evcnt_detach(&txr->txr_defer);
   2292  1.1  yamaguch 	evcnt_detach(&txr->txr_intr);
   2293  1.1  yamaguch 
   2294  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &txr->txr_mem);
   2295  1.1  yamaguch 	softint_disestablish(txr->txr_si);
   2296  1.1  yamaguch 	pcq_destroy(txr->txr_intrq);
   2297  1.1  yamaguch 	mutex_destroy(&txr->txr_lock);
   2298  1.1  yamaguch 	kmem_free(txr, sizeof(*txr));
   2299  1.1  yamaguch }
   2300  1.1  yamaguch 
   2301  1.1  yamaguch static struct iavf_rx_ring *
   2302  1.1  yamaguch iavf_rxr_alloc(struct iavf_softc *sc, unsigned int qid)
   2303  1.1  yamaguch {
   2304  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   2305  1.1  yamaguch 	struct iavf_rx_map *maps;
   2306  1.1  yamaguch 	unsigned int i;
   2307  1.1  yamaguch 	int error;
   2308  1.1  yamaguch 
   2309  1.1  yamaguch 	rxr = kmem_zalloc(sizeof(*rxr), KM_NOSLEEP);
   2310  1.1  yamaguch 	if (rxr == NULL)
   2311  1.1  yamaguch 		return NULL;
   2312  1.1  yamaguch 
   2313  1.1  yamaguch 	maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_rx_ring_ndescs,
   2314  1.1  yamaguch 	    KM_NOSLEEP);
   2315  1.1  yamaguch 	if (maps == NULL)
   2316  1.1  yamaguch 		goto free_rxr;
   2317  1.1  yamaguch 
   2318  1.1  yamaguch 	if (iavf_dmamem_alloc(sc->sc_dmat, &rxr->rxr_mem,
   2319  1.1  yamaguch 	    sizeof(struct ixl_rx_rd_desc_32) * sc->sc_rx_ring_ndescs,
   2320  1.1  yamaguch 	    IAVF_RX_QUEUE_ALIGN) != 0)
   2321  1.1  yamaguch 		goto free_maps;
   2322  1.1  yamaguch 
   2323  1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2324  1.1  yamaguch 		error = bus_dmamap_create(sc->sc_dmat, IAVF_MCLBYTES,
   2325  1.1  yamaguch 		    1, IAVF_MCLBYTES, 0,
   2326  1.1  yamaguch 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &maps[i].rxm_map);
   2327  1.1  yamaguch 		if (error)
   2328  1.1  yamaguch 			goto destroy_maps;
   2329  1.1  yamaguch 	}
   2330  1.1  yamaguch 
   2331  1.1  yamaguch 	snprintf(rxr->rxr_name, sizeof(rxr->rxr_name), "%s-rx%d",
   2332  1.1  yamaguch 	    device_xname(sc->sc_dev), qid);
   2333  1.1  yamaguch 
   2334  1.1  yamaguch 	iavf_evcnt_attach(&rxr->rxr_mgethdr_failed,
   2335  1.1  yamaguch 	    rxr->rxr_name, "MGETHDR failed");
   2336  1.1  yamaguch 	iavf_evcnt_attach(&rxr->rxr_mgetcl_failed,
   2337  1.1  yamaguch 	    rxr->rxr_name, "MCLGET failed");
   2338  1.1  yamaguch 	iavf_evcnt_attach(&rxr->rxr_mbuf_load_failed,
   2339  1.1  yamaguch 	    rxr->rxr_name, "bus_dmamap_load_mbuf failed");
   2340  1.1  yamaguch 	iavf_evcnt_attach(&rxr->rxr_defer,
   2341  1.1  yamaguch 	    rxr->rxr_name, "Handled queue in softint/workqueue");
   2342  1.1  yamaguch 
   2343  1.1  yamaguch 	evcnt_attach_dynamic(&rxr->rxr_intr, EVCNT_TYPE_INTR, NULL,
   2344  1.1  yamaguch 	    rxr->rxr_name, "Interrupt on queue");
   2345  1.1  yamaguch 
   2346  1.1  yamaguch 	rxr->rxr_qid = qid;
   2347  1.1  yamaguch 	rxr->rxr_sc = sc;
   2348  1.1  yamaguch 	rxr->rxr_cons = rxr->rxr_prod = 0;
   2349  1.1  yamaguch 	rxr->rxr_m_head = NULL;
   2350  1.1  yamaguch 	rxr->rxr_m_tail = &rxr->rxr_m_head;
   2351  1.1  yamaguch 	rxr->rxr_maps = maps;
   2352  1.1  yamaguch 	rxr->rxr_tail = I40E_QRX_TAIL1(qid);
   2353  1.1  yamaguch 	mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET);
   2354  1.1  yamaguch 
   2355  1.1  yamaguch 	return rxr;
   2356  1.1  yamaguch 
   2357  1.1  yamaguch destroy_maps:
   2358  1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2359  1.1  yamaguch 		if (maps[i].rxm_map == NULL)
   2360  1.1  yamaguch 			continue;
   2361  1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, maps[i].rxm_map);
   2362  1.1  yamaguch 	}
   2363  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &rxr->rxr_mem);
   2364  1.1  yamaguch free_maps:
   2365  1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs);
   2366  1.1  yamaguch free_rxr:
   2367  1.1  yamaguch 	kmem_free(rxr, sizeof(*rxr));
   2368  1.1  yamaguch 
   2369  1.1  yamaguch 	return NULL;
   2370  1.1  yamaguch }
   2371  1.1  yamaguch 
   2372  1.1  yamaguch static void
   2373  1.1  yamaguch iavf_rxr_free(struct iavf_softc *sc, struct iavf_rx_ring *rxr)
   2374  1.1  yamaguch {
   2375  1.1  yamaguch 	struct iavf_rx_map *maps;
   2376  1.1  yamaguch 	unsigned int i;
   2377  1.1  yamaguch 
   2378  1.1  yamaguch 	maps = rxr->rxr_maps;
   2379  1.1  yamaguch 	if (maps != NULL) {
   2380  1.1  yamaguch 		for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2381  1.1  yamaguch 			if (maps[i].rxm_map == NULL)
   2382  1.1  yamaguch 				continue;
   2383  1.1  yamaguch 			bus_dmamap_destroy(sc->sc_dmat, maps[i].rxm_map);
   2384  1.1  yamaguch 		}
   2385  1.1  yamaguch 		kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs);
   2386  1.1  yamaguch 		rxr->rxr_maps = NULL;
   2387  1.1  yamaguch 	}
   2388  1.1  yamaguch 
   2389  1.1  yamaguch 	evcnt_detach(&rxr->rxr_mgethdr_failed);
   2390  1.1  yamaguch 	evcnt_detach(&rxr->rxr_mgetcl_failed);
   2391  1.1  yamaguch 	evcnt_detach(&rxr->rxr_mbuf_load_failed);
   2392  1.1  yamaguch 	evcnt_detach(&rxr->rxr_defer);
   2393  1.1  yamaguch 	evcnt_detach(&rxr->rxr_intr);
   2394  1.1  yamaguch 
   2395  1.1  yamaguch 	iavf_dmamem_free(sc->sc_dmat, &rxr->rxr_mem);
   2396  1.1  yamaguch 	mutex_destroy(&rxr->rxr_lock);
   2397  1.1  yamaguch 	kmem_free(rxr, sizeof(*rxr));
   2398  1.1  yamaguch }
   2399  1.1  yamaguch 
   2400  1.1  yamaguch static int
   2401  1.1  yamaguch iavf_queue_pairs_alloc(struct iavf_softc *sc)
   2402  1.1  yamaguch {
   2403  1.1  yamaguch 	struct iavf_queue_pair *qp;
   2404  1.1  yamaguch 	unsigned int i, num;
   2405  1.1  yamaguch 
   2406  1.1  yamaguch 	num = iavf_calc_queue_pair_size(sc);
   2407  1.1  yamaguch 	if (num <= 0) {
   2408  1.1  yamaguch 		return -1;
   2409  1.1  yamaguch 	}
   2410  1.1  yamaguch 
   2411  1.1  yamaguch 	sc->sc_qps = kmem_zalloc(sizeof(sc->sc_qps[0]) * num, KM_NOSLEEP);
   2412  1.1  yamaguch 	if (sc->sc_qps == NULL) {
   2413  1.1  yamaguch 		return -1;
   2414  1.1  yamaguch 	}
   2415  1.1  yamaguch 
   2416  1.1  yamaguch 	for (i = 0; i < num; i++) {
   2417  1.1  yamaguch 		qp = &sc->sc_qps[i];
   2418  1.1  yamaguch 
   2419  1.1  yamaguch 		qp->qp_rxr = iavf_rxr_alloc(sc, i);
   2420  1.1  yamaguch 		qp->qp_txr = iavf_txr_alloc(sc, i);
   2421  1.1  yamaguch 
   2422  1.1  yamaguch 		if (qp->qp_rxr == NULL || qp->qp_txr == NULL)
   2423  1.1  yamaguch 			goto free;
   2424  1.1  yamaguch 
   2425  1.1  yamaguch 		qp->qp_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
   2426  1.1  yamaguch 		    iavf_handle_queue, qp);
   2427  1.1  yamaguch 		if (qp->qp_si == NULL)
   2428  1.1  yamaguch 			goto free;
   2429  1.1  yamaguch 	}
   2430  1.1  yamaguch 
   2431  1.1  yamaguch 	sc->sc_nqps_alloc = num;
   2432  1.1  yamaguch 	return 0;
   2433  1.1  yamaguch free:
   2434  1.1  yamaguch 	for (i = 0; i < num; i++) {
   2435  1.1  yamaguch 		qp = &sc->sc_qps[i];
   2436  1.1  yamaguch 
   2437  1.1  yamaguch 		if (qp->qp_si != NULL)
   2438  1.1  yamaguch 			softint_disestablish(qp->qp_si);
   2439  1.1  yamaguch 		if (qp->qp_rxr != NULL)
   2440  1.1  yamaguch 			iavf_rxr_free(sc, qp->qp_rxr);
   2441  1.1  yamaguch 		if (qp->qp_txr != NULL)
   2442  1.1  yamaguch 			iavf_txr_free(sc, qp->qp_txr);
   2443  1.1  yamaguch 	}
   2444  1.1  yamaguch 
   2445  1.1  yamaguch 	kmem_free(sc->sc_qps, sizeof(sc->sc_qps[0]) * num);
   2446  1.1  yamaguch 	sc->sc_qps = NULL;
   2447  1.1  yamaguch 
   2448  1.1  yamaguch 	return -1;
   2449  1.1  yamaguch }
   2450  1.1  yamaguch 
   2451  1.1  yamaguch static void
   2452  1.1  yamaguch iavf_queue_pairs_free(struct iavf_softc *sc)
   2453  1.1  yamaguch {
   2454  1.1  yamaguch 	struct iavf_queue_pair *qp;
   2455  1.1  yamaguch 	unsigned int i;
   2456  1.1  yamaguch 	size_t sz;
   2457  1.1  yamaguch 
   2458  1.1  yamaguch 	if (sc->sc_qps == NULL)
   2459  1.1  yamaguch 		return;
   2460  1.1  yamaguch 
   2461  1.1  yamaguch 	for (i = 0; i < sc->sc_nqps_alloc; i++) {
   2462  1.1  yamaguch 		qp = &sc->sc_qps[i];
   2463  1.1  yamaguch 
   2464  1.1  yamaguch 		if (qp->qp_si != NULL)
   2465  1.1  yamaguch 			softint_disestablish(qp->qp_si);
   2466  1.1  yamaguch 		if (qp->qp_rxr != NULL)
   2467  1.1  yamaguch 			iavf_rxr_free(sc, qp->qp_rxr);
   2468  1.1  yamaguch 		if (qp->qp_txr != NULL)
   2469  1.1  yamaguch 			iavf_txr_free(sc, qp->qp_txr);
   2470  1.1  yamaguch 	}
   2471  1.1  yamaguch 
   2472  1.1  yamaguch 	sz = sizeof(sc->sc_qps[0]) * sc->sc_nqps_alloc;
   2473  1.1  yamaguch 	kmem_free(sc->sc_qps, sz);
   2474  1.1  yamaguch 	sc->sc_qps = NULL;
   2475  1.1  yamaguch 	sc->sc_nqps_alloc = 0;
   2476  1.1  yamaguch }
   2477  1.1  yamaguch 
   2478  1.1  yamaguch static int
   2479  1.1  yamaguch iavf_rxfill(struct iavf_softc *sc, struct iavf_rx_ring *rxr)
   2480  1.1  yamaguch {
   2481  1.1  yamaguch 	struct ixl_rx_rd_desc_32 *ring, *rxd;
   2482  1.1  yamaguch 	struct iavf_rx_map *rxm;
   2483  1.1  yamaguch 	bus_dmamap_t map;
   2484  1.1  yamaguch 	struct mbuf *m;
   2485  1.1  yamaguch 	unsigned int slots, prod, mask;
   2486  1.1  yamaguch 	int error, post;
   2487  1.1  yamaguch 
   2488  1.1  yamaguch 	slots = ixl_rxr_unrefreshed(rxr->rxr_prod, rxr->rxr_cons,
   2489  1.1  yamaguch 	    sc->sc_rx_ring_ndescs);
   2490  1.1  yamaguch 
   2491  1.1  yamaguch 	if (slots == 0)
   2492  1.1  yamaguch 		return 0;
   2493  1.1  yamaguch 
   2494  1.1  yamaguch 	error = 0;
   2495  1.1  yamaguch 	prod = rxr->rxr_prod;
   2496  1.1  yamaguch 
   2497  1.1  yamaguch 	ring = IXL_DMA_KVA(&rxr->rxr_mem);
   2498  1.1  yamaguch 	mask = sc->sc_rx_ring_ndescs - 1;
   2499  1.1  yamaguch 
   2500  1.1  yamaguch 	do {
   2501  1.1  yamaguch 		rxm = &rxr->rxr_maps[prod];
   2502  1.1  yamaguch 
   2503  1.1  yamaguch 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   2504  1.1  yamaguch 		if (m == NULL) {
   2505  1.1  yamaguch 			rxr->rxr_mgethdr_failed.ev_count++;
   2506  1.1  yamaguch 			error = -1;
   2507  1.1  yamaguch 			break;
   2508  1.1  yamaguch 		}
   2509  1.1  yamaguch 
   2510  1.1  yamaguch 		MCLGET(m, M_DONTWAIT);
   2511  1.1  yamaguch 		if (!ISSET(m->m_flags, M_EXT)) {
   2512  1.1  yamaguch 			rxr->rxr_mgetcl_failed.ev_count++;
   2513  1.1  yamaguch 			error = -1;
   2514  1.1  yamaguch 			m_freem(m);
   2515  1.1  yamaguch 			break;
   2516  1.1  yamaguch 		}
   2517  1.1  yamaguch 
   2518  1.1  yamaguch 		m->m_len = m->m_pkthdr.len = MCLBYTES;
   2519  1.1  yamaguch 		m_adj(m, ETHER_ALIGN);
   2520  1.1  yamaguch 
   2521  1.1  yamaguch 		map = rxm->rxm_map;
   2522  1.1  yamaguch 
   2523  1.1  yamaguch 		if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
   2524  1.1  yamaguch 		    BUS_DMA_READ|BUS_DMA_NOWAIT) != 0) {
   2525  1.1  yamaguch 			rxr->rxr_mbuf_load_failed.ev_count++;
   2526  1.1  yamaguch 			error = -1;
   2527  1.1  yamaguch 			m_freem(m);
   2528  1.1  yamaguch 			break;
   2529  1.1  yamaguch 		}
   2530  1.1  yamaguch 
   2531  1.1  yamaguch 		rxm->rxm_m = m;
   2532  1.1  yamaguch 
   2533  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2534  1.1  yamaguch 		    BUS_DMASYNC_PREREAD);
   2535  1.1  yamaguch 
   2536  1.1  yamaguch 		rxd = &ring[prod];
   2537  1.1  yamaguch 		rxd->paddr = htole64(map->dm_segs[0].ds_addr);
   2538  1.1  yamaguch 		rxd->haddr = htole64(0);
   2539  1.1  yamaguch 
   2540  1.1  yamaguch 		prod++;
   2541  1.1  yamaguch 		prod &= mask;
   2542  1.1  yamaguch 		post = 1;
   2543  1.1  yamaguch 	} while (--slots);
   2544  1.1  yamaguch 
   2545  1.1  yamaguch 	if (post) {
   2546  1.1  yamaguch 		rxr->rxr_prod = prod;
   2547  1.1  yamaguch 		iavf_wr(sc, rxr->rxr_tail, prod);
   2548  1.1  yamaguch 	}
   2549  1.1  yamaguch 
   2550  1.1  yamaguch 	return error;
   2551  1.1  yamaguch }
   2552  1.1  yamaguch 
   2553  1.1  yamaguch static inline void
   2554  1.1  yamaguch iavf_rx_csum(struct mbuf *m, uint64_t qword)
   2555  1.1  yamaguch {
   2556  1.1  yamaguch 	int flags_mask;
   2557  1.1  yamaguch 
   2558  1.1  yamaguch 	if (!ISSET(qword, IXL_RX_DESC_L3L4P)) {
   2559  1.1  yamaguch 		/* No L3 or L4 checksum was calculated */
   2560  1.1  yamaguch 		return;
   2561  1.1  yamaguch 	}
   2562  1.1  yamaguch 
   2563  1.1  yamaguch 	switch (__SHIFTOUT(qword, IXL_RX_DESC_PTYPE_MASK)) {
   2564  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_IPV4FRAG:
   2565  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_IPV4:
   2566  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_SCTPV4:
   2567  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_ICMPV4:
   2568  1.1  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   2569  1.1  yamaguch 		break;
   2570  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_TCPV4:
   2571  1.1  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   2572  1.1  yamaguch 		flags_mask |= M_CSUM_TCPv4 | M_CSUM_TCP_UDP_BAD;
   2573  1.1  yamaguch 		break;
   2574  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_UDPV4:
   2575  1.1  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   2576  1.1  yamaguch 		flags_mask |= M_CSUM_UDPv4 | M_CSUM_TCP_UDP_BAD;
   2577  1.1  yamaguch 		break;
   2578  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_TCPV6:
   2579  1.1  yamaguch 		flags_mask = M_CSUM_TCPv6 | M_CSUM_TCP_UDP_BAD;
   2580  1.1  yamaguch 		break;
   2581  1.1  yamaguch 	case IXL_RX_DESC_PTYPE_UDPV6:
   2582  1.1  yamaguch 		flags_mask = M_CSUM_UDPv6 | M_CSUM_TCP_UDP_BAD;
   2583  1.1  yamaguch 		break;
   2584  1.1  yamaguch 	default:
   2585  1.1  yamaguch 		flags_mask = 0;
   2586  1.1  yamaguch 	}
   2587  1.1  yamaguch 
   2588  1.1  yamaguch 	m->m_pkthdr.csum_flags |= (flags_mask & (M_CSUM_IPv4 |
   2589  1.1  yamaguch 	    M_CSUM_TCPv4 | M_CSUM_TCPv6 | M_CSUM_UDPv4 | M_CSUM_UDPv6));
   2590  1.1  yamaguch 
   2591  1.1  yamaguch 	if (ISSET(qword, IXL_RX_DESC_IPE)) {
   2592  1.1  yamaguch 		m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_IPv4_BAD);
   2593  1.1  yamaguch 	}
   2594  1.1  yamaguch 
   2595  1.1  yamaguch 	if (ISSET(qword, IXL_RX_DESC_L4E)) {
   2596  1.1  yamaguch 		m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_TCP_UDP_BAD);
   2597  1.1  yamaguch 	}
   2598  1.1  yamaguch }
   2599  1.1  yamaguch 
   2600  1.1  yamaguch static int
   2601  1.1  yamaguch iavf_rxeof(struct iavf_softc *sc, struct iavf_rx_ring *rxr, u_int rxlimit,
   2602  1.1  yamaguch     struct evcnt *ecnt)
   2603  1.1  yamaguch {
   2604  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2605  1.1  yamaguch 	struct ixl_rx_wb_desc_32 *ring, *rxd;
   2606  1.1  yamaguch 	struct iavf_rx_map *rxm;
   2607  1.1  yamaguch 	bus_dmamap_t map;
   2608  1.1  yamaguch 	unsigned int cons, prod;
   2609  1.1  yamaguch 	struct mbuf *m;
   2610  1.1  yamaguch 	uint64_t word, word0;
   2611  1.1  yamaguch 	unsigned int len;
   2612  1.1  yamaguch 	unsigned int mask;
   2613  1.1  yamaguch 	int done = 0, more = 0;
   2614  1.1  yamaguch 
   2615  1.1  yamaguch 	KASSERT(mutex_owned(&rxr->rxr_lock));
   2616  1.1  yamaguch 
   2617  1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
   2618  1.1  yamaguch 		return 0;
   2619  1.1  yamaguch 
   2620  1.1  yamaguch 	prod = rxr->rxr_prod;
   2621  1.1  yamaguch 	cons = rxr->rxr_cons;
   2622  1.1  yamaguch 
   2623  1.1  yamaguch 	if (cons == prod)
   2624  1.1  yamaguch 		return 0;
   2625  1.1  yamaguch 
   2626  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem),
   2627  1.1  yamaguch 	    0, IXL_DMA_LEN(&rxr->rxr_mem),
   2628  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   2629  1.1  yamaguch 
   2630  1.1  yamaguch 	ring = IXL_DMA_KVA(&rxr->rxr_mem);
   2631  1.1  yamaguch 	mask = sc->sc_rx_ring_ndescs - 1;
   2632  1.1  yamaguch 
   2633  1.1  yamaguch 	net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
   2634  1.1  yamaguch 
   2635  1.1  yamaguch 	do {
   2636  1.1  yamaguch 		if (rxlimit-- <= 0) {
   2637  1.1  yamaguch 			more = 1;
   2638  1.1  yamaguch 			break;
   2639  1.1  yamaguch 		}
   2640  1.1  yamaguch 
   2641  1.1  yamaguch 		rxd = &ring[cons];
   2642  1.1  yamaguch 
   2643  1.1  yamaguch 		word = le64toh(rxd->qword1);
   2644  1.1  yamaguch 
   2645  1.1  yamaguch 		if (!ISSET(word, IXL_RX_DESC_DD))
   2646  1.1  yamaguch 			break;
   2647  1.1  yamaguch 
   2648  1.1  yamaguch 		rxm = &rxr->rxr_maps[cons];
   2649  1.1  yamaguch 
   2650  1.1  yamaguch 		map = rxm->rxm_map;
   2651  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2652  1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   2653  1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2654  1.1  yamaguch 
   2655  1.1  yamaguch 		m = rxm->rxm_m;
   2656  1.1  yamaguch 		rxm->rxm_m = NULL;
   2657  1.1  yamaguch 
   2658  1.1  yamaguch 		KASSERT(m != NULL);
   2659  1.1  yamaguch 
   2660  1.1  yamaguch 		len = (word & IXL_RX_DESC_PLEN_MASK) >> IXL_RX_DESC_PLEN_SHIFT;
   2661  1.1  yamaguch 		m->m_len = len;
   2662  1.1  yamaguch 		m->m_pkthdr.len = 0;
   2663  1.1  yamaguch 
   2664  1.1  yamaguch 		m->m_next = NULL;
   2665  1.1  yamaguch 		*rxr->rxr_m_tail = m;
   2666  1.1  yamaguch 		rxr->rxr_m_tail = &m->m_next;
   2667  1.1  yamaguch 
   2668  1.1  yamaguch 		m = rxr->rxr_m_head;
   2669  1.1  yamaguch 		m->m_pkthdr.len += len;
   2670  1.1  yamaguch 
   2671  1.1  yamaguch 		if (ISSET(word, IXL_RX_DESC_EOP)) {
   2672  1.1  yamaguch 			word0 = le64toh(rxd->qword0);
   2673  1.1  yamaguch 
   2674  1.1  yamaguch 			if (ISSET(word, IXL_RX_DESC_L2TAG1P)) {
   2675  1.1  yamaguch 				vlan_set_tag(m,
   2676  1.1  yamaguch 				    __SHIFTOUT(word0, IXL_RX_DESC_L2TAG1_MASK));
   2677  1.1  yamaguch 			}
   2678  1.1  yamaguch 
   2679  1.1  yamaguch 			if ((ifp->if_capenable & IAVF_IFCAP_RXCSUM) != 0)
   2680  1.1  yamaguch 				iavf_rx_csum(m, word);
   2681  1.1  yamaguch 
   2682  1.1  yamaguch 			if (!ISSET(word,
   2683  1.1  yamaguch 			    IXL_RX_DESC_RXE | IXL_RX_DESC_OVERSIZE)) {
   2684  1.1  yamaguch 				m_set_rcvif(m, ifp);
   2685  1.1  yamaguch 				if_statinc_ref(nsr, if_ipackets);
   2686  1.1  yamaguch 				if_statadd_ref(nsr, if_ibytes,
   2687  1.1  yamaguch 				    m->m_pkthdr.len);
   2688  1.1  yamaguch 				if_percpuq_enqueue(sc->sc_ipq, m);
   2689  1.1  yamaguch 			} else {
   2690  1.1  yamaguch 				if_statinc_ref(nsr, if_ierrors);
   2691  1.1  yamaguch 				m_freem(m);
   2692  1.1  yamaguch 			}
   2693  1.1  yamaguch 
   2694  1.1  yamaguch 			rxr->rxr_m_head = NULL;
   2695  1.1  yamaguch 			rxr->rxr_m_tail = &rxr->rxr_m_head;
   2696  1.1  yamaguch 		}
   2697  1.1  yamaguch 
   2698  1.1  yamaguch 		cons++;
   2699  1.1  yamaguch 		cons &= mask;
   2700  1.1  yamaguch 
   2701  1.1  yamaguch 		done = 1;
   2702  1.1  yamaguch 	} while (cons != prod);
   2703  1.1  yamaguch 
   2704  1.1  yamaguch 	if (done) {
   2705  1.1  yamaguch 		ecnt->ev_count++;
   2706  1.1  yamaguch 		rxr->rxr_cons = cons;
   2707  1.1  yamaguch 		if (iavf_rxfill(sc, rxr) == -1)
   2708  1.1  yamaguch 			if_statinc_ref(nsr, if_iqdrops);
   2709  1.1  yamaguch 	}
   2710  1.1  yamaguch 
   2711  1.1  yamaguch 	IF_STAT_PUTREF(ifp);
   2712  1.1  yamaguch 
   2713  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem),
   2714  1.1  yamaguch 	    0, IXL_DMA_LEN(&rxr->rxr_mem),
   2715  1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2716  1.1  yamaguch 
   2717  1.1  yamaguch 	return more;
   2718  1.1  yamaguch }
   2719  1.1  yamaguch 
   2720  1.1  yamaguch static void
   2721  1.1  yamaguch iavf_rxr_clean(struct iavf_softc *sc, struct iavf_rx_ring *rxr)
   2722  1.1  yamaguch {
   2723  1.1  yamaguch 	struct iavf_rx_map *maps, *rxm;
   2724  1.1  yamaguch 	bus_dmamap_t map;
   2725  1.1  yamaguch 	unsigned int i;
   2726  1.1  yamaguch 
   2727  1.1  yamaguch 	KASSERT(mutex_owned(&rxr->rxr_lock));
   2728  1.1  yamaguch 
   2729  1.1  yamaguch 	maps = rxr->rxr_maps;
   2730  1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2731  1.1  yamaguch 		rxm = &maps[i];
   2732  1.1  yamaguch 
   2733  1.1  yamaguch 		if (rxm->rxm_m == NULL)
   2734  1.1  yamaguch 			continue;
   2735  1.1  yamaguch 
   2736  1.1  yamaguch 		map = rxm->rxm_map;
   2737  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2738  1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   2739  1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2740  1.1  yamaguch 
   2741  1.1  yamaguch 		m_freem(rxm->rxm_m);
   2742  1.1  yamaguch 		rxm->rxm_m = NULL;
   2743  1.1  yamaguch 	}
   2744  1.1  yamaguch 
   2745  1.1  yamaguch 	m_freem(rxr->rxr_m_head);
   2746  1.1  yamaguch 	rxr->rxr_m_head = NULL;
   2747  1.1  yamaguch 	rxr->rxr_m_tail = &rxr->rxr_m_head;
   2748  1.1  yamaguch 
   2749  1.1  yamaguch 	memset(IXL_DMA_KVA(&rxr->rxr_mem), 0, IXL_DMA_LEN(&rxr->rxr_mem));
   2750  1.1  yamaguch 	rxr->rxr_prod = rxr->rxr_cons = 0;
   2751  1.1  yamaguch }
   2752  1.1  yamaguch 
   2753  1.1  yamaguch static int
   2754  1.1  yamaguch iavf_txeof(struct iavf_softc *sc, struct iavf_tx_ring *txr, u_int txlimit,
   2755  1.1  yamaguch     struct evcnt *ecnt)
   2756  1.1  yamaguch {
   2757  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2758  1.1  yamaguch 	struct ixl_tx_desc *ring, *txd;
   2759  1.1  yamaguch 	struct iavf_tx_map *txm;
   2760  1.1  yamaguch 	struct mbuf *m;
   2761  1.1  yamaguch 	bus_dmamap_t map;
   2762  1.1  yamaguch 	unsigned int cons, prod, last;
   2763  1.1  yamaguch 	unsigned int mask;
   2764  1.1  yamaguch 	uint64_t dtype;
   2765  1.1  yamaguch 	int done = 0, more = 0;
   2766  1.1  yamaguch 
   2767  1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2768  1.1  yamaguch 
   2769  1.1  yamaguch 	prod = txr->txr_prod;
   2770  1.1  yamaguch 	cons = txr->txr_cons;
   2771  1.1  yamaguch 
   2772  1.1  yamaguch 	if (cons == prod)
   2773  1.1  yamaguch 		return 0;
   2774  1.1  yamaguch 
   2775  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2776  1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTREAD);
   2777  1.1  yamaguch 
   2778  1.1  yamaguch 	ring = IXL_DMA_KVA(&txr->txr_mem);
   2779  1.1  yamaguch 	mask = sc->sc_tx_ring_ndescs - 1;
   2780  1.1  yamaguch 
   2781  1.1  yamaguch 	net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
   2782  1.1  yamaguch 
   2783  1.1  yamaguch 	do {
   2784  1.1  yamaguch 		if (txlimit-- <= 0) {
   2785  1.1  yamaguch 			more = 1;
   2786  1.1  yamaguch 			break;
   2787  1.1  yamaguch 		}
   2788  1.1  yamaguch 
   2789  1.1  yamaguch 		txm = &txr->txr_maps[cons];
   2790  1.1  yamaguch 		last = txm->txm_eop;
   2791  1.1  yamaguch 		txd = &ring[last];
   2792  1.1  yamaguch 
   2793  1.1  yamaguch 		dtype = txd->cmd & htole64(IXL_TX_DESC_DTYPE_MASK);
   2794  1.1  yamaguch 		if (dtype != htole64(IXL_TX_DESC_DTYPE_DONE))
   2795  1.1  yamaguch 			break;
   2796  1.1  yamaguch 
   2797  1.1  yamaguch 		map = txm->txm_map;
   2798  1.1  yamaguch 
   2799  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2800  1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   2801  1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2802  1.1  yamaguch 
   2803  1.1  yamaguch 		m = txm->txm_m;
   2804  1.1  yamaguch 		if (m != NULL) {
   2805  1.1  yamaguch 			if_statinc_ref(nsr, if_opackets);
   2806  1.1  yamaguch 			if_statadd_ref(nsr, if_obytes, m->m_pkthdr.len);
   2807  1.1  yamaguch 			if (ISSET(m->m_flags, M_MCAST))
   2808  1.1  yamaguch 				if_statinc_ref(nsr, if_omcasts);
   2809  1.1  yamaguch 			m_freem(m);
   2810  1.1  yamaguch 		}
   2811  1.1  yamaguch 
   2812  1.1  yamaguch 		txm->txm_m = NULL;
   2813  1.1  yamaguch 		txm->txm_eop = -1;
   2814  1.1  yamaguch 
   2815  1.1  yamaguch 		cons = last + 1;
   2816  1.1  yamaguch 		cons &= mask;
   2817  1.1  yamaguch 		done = 1;
   2818  1.1  yamaguch 	} while (cons != prod);
   2819  1.1  yamaguch 
   2820  1.1  yamaguch 	IF_STAT_PUTREF(ifp);
   2821  1.1  yamaguch 
   2822  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2823  1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREREAD);
   2824  1.1  yamaguch 
   2825  1.1  yamaguch 	txr->txr_cons = cons;
   2826  1.1  yamaguch 
   2827  1.1  yamaguch 	if (done) {
   2828  1.1  yamaguch 		ecnt->ev_count++;
   2829  1.1  yamaguch 		softint_schedule(txr->txr_si);
   2830  1.1  yamaguch 		if (txr->txr_qid == 0) {
   2831  1.1  yamaguch 			CLR(ifp->if_flags, IFF_OACTIVE);
   2832  1.1  yamaguch 			if_schedule_deferred_start(ifp);
   2833  1.1  yamaguch 		}
   2834  1.1  yamaguch 	}
   2835  1.1  yamaguch 
   2836  1.1  yamaguch 	if (txr->txr_cons == txr->txr_prod) {
   2837  1.1  yamaguch 		txr->txr_watchdog = IAVF_WATCHDOG_STOP;
   2838  1.1  yamaguch 	}
   2839  1.1  yamaguch 
   2840  1.1  yamaguch 	return more;
   2841  1.1  yamaguch }
   2842  1.1  yamaguch 
   2843  1.1  yamaguch static inline int
   2844  1.1  yamaguch iavf_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf **m0,
   2845  1.1  yamaguch     struct iavf_tx_ring *txr)
   2846  1.1  yamaguch {
   2847  1.1  yamaguch 	struct mbuf *m;
   2848  1.1  yamaguch 	int error;
   2849  1.1  yamaguch 
   2850  1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2851  1.1  yamaguch 
   2852  1.1  yamaguch 	m = *m0;
   2853  1.1  yamaguch 
   2854  1.1  yamaguch 	error = bus_dmamap_load_mbuf(dmat, map, m,
   2855  1.1  yamaguch 	    BUS_DMA_STREAMING|BUS_DMA_WRITE|BUS_DMA_NOWAIT);
   2856  1.1  yamaguch 	if (error != EFBIG)
   2857  1.1  yamaguch 		return error;
   2858  1.1  yamaguch 
   2859  1.1  yamaguch 	m = m_defrag(m, M_DONTWAIT);
   2860  1.1  yamaguch 	if (m != NULL) {
   2861  1.1  yamaguch 		*m0 = m;
   2862  1.1  yamaguch 		txr->txr_defragged.ev_count++;
   2863  1.1  yamaguch 		error = bus_dmamap_load_mbuf(dmat, map, m,
   2864  1.1  yamaguch 		    BUS_DMA_STREAMING|BUS_DMA_WRITE|BUS_DMA_NOWAIT);
   2865  1.1  yamaguch 	} else {
   2866  1.1  yamaguch 		txr->txr_defrag_failed.ev_count++;
   2867  1.1  yamaguch 		error = ENOBUFS;
   2868  1.1  yamaguch 	}
   2869  1.1  yamaguch 
   2870  1.1  yamaguch 	return error;
   2871  1.1  yamaguch }
   2872  1.1  yamaguch 
   2873  1.1  yamaguch static inline int
   2874  1.1  yamaguch iavf_tx_setup_offloads(struct mbuf *m, uint64_t *cmd_txd)
   2875  1.1  yamaguch {
   2876  1.1  yamaguch 	struct ether_header *eh;
   2877  1.1  yamaguch 	size_t len;
   2878  1.1  yamaguch 	uint64_t cmd;
   2879  1.1  yamaguch 
   2880  1.1  yamaguch 	cmd = 0;
   2881  1.1  yamaguch 
   2882  1.1  yamaguch 	eh = mtod(m, struct ether_header *);
   2883  1.1  yamaguch 	switch (htons(eh->ether_type)) {
   2884  1.1  yamaguch 	case ETHERTYPE_IP:
   2885  1.1  yamaguch 	case ETHERTYPE_IPV6:
   2886  1.1  yamaguch 		len = ETHER_HDR_LEN;
   2887  1.1  yamaguch 		break;
   2888  1.1  yamaguch 	case ETHERTYPE_VLAN:
   2889  1.1  yamaguch 		len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
   2890  1.1  yamaguch 		break;
   2891  1.1  yamaguch 	default:
   2892  1.1  yamaguch 		len = 0;
   2893  1.1  yamaguch 	}
   2894  1.1  yamaguch 	cmd |= ((len >> 1) << IXL_TX_DESC_MACLEN_SHIFT);
   2895  1.1  yamaguch 
   2896  1.1  yamaguch 	if (m->m_pkthdr.csum_flags &
   2897  1.1  yamaguch 	    (M_CSUM_TSOv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
   2898  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_IIPT_IPV4;
   2899  1.1  yamaguch 	}
   2900  1.1  yamaguch 	if (m->m_pkthdr.csum_flags & M_CSUM_IPv4) {
   2901  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_IIPT_IPV4_CSUM;
   2902  1.1  yamaguch 	}
   2903  1.1  yamaguch 
   2904  1.1  yamaguch 	if (m->m_pkthdr.csum_flags &
   2905  1.1  yamaguch 	    (M_CSUM_TSOv6 | M_CSUM_TCPv6 | M_CSUM_UDPv6)) {
   2906  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_IIPT_IPV6;
   2907  1.1  yamaguch 	}
   2908  1.1  yamaguch 
   2909  1.1  yamaguch 	switch (cmd & IXL_TX_DESC_CMD_IIPT_MASK) {
   2910  1.1  yamaguch 	case IXL_TX_DESC_CMD_IIPT_IPV4:
   2911  1.1  yamaguch 	case IXL_TX_DESC_CMD_IIPT_IPV4_CSUM:
   2912  1.1  yamaguch 		len = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
   2913  1.1  yamaguch 		break;
   2914  1.1  yamaguch 	case IXL_TX_DESC_CMD_IIPT_IPV6:
   2915  1.1  yamaguch 		len = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data);
   2916  1.1  yamaguch 		break;
   2917  1.1  yamaguch 	default:
   2918  1.1  yamaguch 		len = 0;
   2919  1.1  yamaguch 	}
   2920  1.1  yamaguch 	cmd |= ((len >> 2) << IXL_TX_DESC_IPLEN_SHIFT);
   2921  1.1  yamaguch 
   2922  1.1  yamaguch 	if (m->m_pkthdr.csum_flags &
   2923  1.1  yamaguch 	    (M_CSUM_TSOv4 | M_CSUM_TSOv6 | M_CSUM_TCPv4 | M_CSUM_TCPv6)) {
   2924  1.1  yamaguch 		len = sizeof(struct tcphdr);
   2925  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_L4T_EOFT_TCP;
   2926  1.1  yamaguch 	} else if (m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) {
   2927  1.1  yamaguch 		len = sizeof(struct udphdr);
   2928  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_L4T_EOFT_UDP;
   2929  1.1  yamaguch 	} else {
   2930  1.1  yamaguch 		len = 0;
   2931  1.1  yamaguch 	}
   2932  1.1  yamaguch 	cmd |= ((len >> 2) << IXL_TX_DESC_L4LEN_SHIFT);
   2933  1.1  yamaguch 
   2934  1.1  yamaguch 	*cmd_txd |= cmd;
   2935  1.1  yamaguch 	return 0;
   2936  1.1  yamaguch }
   2937  1.1  yamaguch 
   2938  1.1  yamaguch static void
   2939  1.1  yamaguch iavf_tx_common_locked(struct ifnet *ifp, struct iavf_tx_ring *txr,
   2940  1.1  yamaguch     bool is_transmit)
   2941  1.1  yamaguch {
   2942  1.1  yamaguch 	struct iavf_softc *sc;
   2943  1.1  yamaguch 	struct ixl_tx_desc *ring, *txd;
   2944  1.1  yamaguch 	struct iavf_tx_map *txm;
   2945  1.1  yamaguch 	bus_dmamap_t map;
   2946  1.1  yamaguch 	struct mbuf *m;
   2947  1.1  yamaguch 	unsigned int prod, free, last, i;
   2948  1.1  yamaguch 	unsigned int mask;
   2949  1.1  yamaguch 	uint64_t cmd, cmd_txd;
   2950  1.1  yamaguch 	int post = 0;
   2951  1.1  yamaguch 
   2952  1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2953  1.1  yamaguch 
   2954  1.1  yamaguch 	sc = ifp->if_softc;
   2955  1.1  yamaguch 
   2956  1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_RUNNING)
   2957  1.1  yamaguch 	    || (!is_transmit && ISSET(ifp->if_flags, IFF_OACTIVE))) {
   2958  1.1  yamaguch 		if (!is_transmit)
   2959  1.1  yamaguch 			IFQ_PURGE(&ifp->if_snd);
   2960  1.1  yamaguch 		return;
   2961  1.1  yamaguch 	}
   2962  1.1  yamaguch 
   2963  1.1  yamaguch 	prod = txr->txr_prod;
   2964  1.1  yamaguch 	free = txr->txr_cons;
   2965  1.1  yamaguch 
   2966  1.1  yamaguch 	if (free <= prod)
   2967  1.1  yamaguch 		free += sc->sc_tx_ring_ndescs;
   2968  1.1  yamaguch 	free -= prod;
   2969  1.1  yamaguch 
   2970  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2971  1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTWRITE);
   2972  1.1  yamaguch 
   2973  1.1  yamaguch 	ring = IXL_DMA_KVA(&txr->txr_mem);
   2974  1.1  yamaguch 	mask = sc->sc_tx_ring_ndescs - 1;
   2975  1.1  yamaguch 	last = prod;
   2976  1.1  yamaguch 	cmd = 0;
   2977  1.1  yamaguch 	txd = NULL;
   2978  1.1  yamaguch 
   2979  1.1  yamaguch 	for (;;) {
   2980  1.1  yamaguch 		if (free < IAVF_TX_PKT_DESCS) {
   2981  1.1  yamaguch 			if (!is_transmit)
   2982  1.1  yamaguch 				SET(ifp->if_flags, IFF_OACTIVE);
   2983  1.1  yamaguch 			break;
   2984  1.1  yamaguch 		}
   2985  1.1  yamaguch 
   2986  1.1  yamaguch 		if (is_transmit)
   2987  1.1  yamaguch 			m = pcq_get(txr->txr_intrq);
   2988  1.1  yamaguch 		else
   2989  1.1  yamaguch 			IFQ_DEQUEUE(&ifp->if_snd, m);
   2990  1.1  yamaguch 
   2991  1.1  yamaguch 		if (m == NULL)
   2992  1.1  yamaguch 			break;
   2993  1.1  yamaguch 
   2994  1.1  yamaguch 		txm = &txr->txr_maps[prod];
   2995  1.1  yamaguch 		map = txm->txm_map;
   2996  1.1  yamaguch 
   2997  1.1  yamaguch 		if (iavf_load_mbuf(sc->sc_dmat, map, &m, txr) != 0) {
   2998  1.1  yamaguch 			if_statinc(ifp, if_oerrors);
   2999  1.1  yamaguch 			m_freem(m);
   3000  1.1  yamaguch 			continue;
   3001  1.1  yamaguch 		}
   3002  1.1  yamaguch 
   3003  1.1  yamaguch 		cmd_txd = 0;
   3004  1.1  yamaguch 		if (m->m_pkthdr.csum_flags & IAVF_CSUM_ALL_OFFLOAD) {
   3005  1.1  yamaguch 			iavf_tx_setup_offloads(m, &cmd_txd);
   3006  1.1  yamaguch 		}
   3007  1.1  yamaguch 		if (vlan_has_tag(m)) {
   3008  1.1  yamaguch 			cmd_txd |= IXL_TX_DESC_CMD_IL2TAG1 |
   3009  1.1  yamaguch 			    ((uint64_t)vlan_get_tag(m)
   3010  1.1  yamaguch 			    << IXL_TX_DESC_L2TAG1_SHIFT);
   3011  1.1  yamaguch 		}
   3012  1.1  yamaguch 
   3013  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0,
   3014  1.1  yamaguch 		    map->dm_mapsize, BUS_DMASYNC_PREWRITE);
   3015  1.1  yamaguch 
   3016  1.1  yamaguch 		for (i = 0; i < (unsigned int)map->dm_nsegs; i++) {
   3017  1.1  yamaguch 			txd = &ring[prod];
   3018  1.1  yamaguch 
   3019  1.1  yamaguch 			cmd = (uint64_t)map->dm_segs[i].ds_len <<
   3020  1.1  yamaguch 			    IXL_TX_DESC_BSIZE_SHIFT;
   3021  1.1  yamaguch 			cmd |= IXL_TX_DESC_DTYPE_DATA|IXL_TX_DESC_CMD_ICRC|
   3022  1.1  yamaguch 			    cmd_txd;
   3023  1.1  yamaguch 
   3024  1.1  yamaguch 			txd->addr = htole64(map->dm_segs[i].ds_addr);
   3025  1.1  yamaguch 			txd->cmd = htole64(cmd);
   3026  1.1  yamaguch 
   3027  1.1  yamaguch 			last = prod;
   3028  1.1  yamaguch 			prod++;
   3029  1.1  yamaguch 			prod &= mask;
   3030  1.1  yamaguch 		}
   3031  1.1  yamaguch 
   3032  1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_EOP|IXL_TX_DESC_CMD_RS;
   3033  1.1  yamaguch 		txd->cmd = htole64(cmd);
   3034  1.1  yamaguch 		txm->txm_m = m;
   3035  1.1  yamaguch 		txm->txm_eop = last;
   3036  1.1  yamaguch 
   3037  1.1  yamaguch 		bpf_mtap(ifp, m, BPF_D_OUT);
   3038  1.1  yamaguch 		free -= i;
   3039  1.1  yamaguch 		post = 1;
   3040  1.1  yamaguch 	}
   3041  1.1  yamaguch 
   3042  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   3043  1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREWRITE);
   3044  1.1  yamaguch 
   3045  1.1  yamaguch 	if (post) {
   3046  1.1  yamaguch 		txr->txr_prod = prod;
   3047  1.1  yamaguch 		iavf_wr(sc, txr->txr_tail, prod);
   3048  1.1  yamaguch 		txr->txr_watchdog = IAVF_WATCHDOG_TICKS;
   3049  1.1  yamaguch 	}
   3050  1.1  yamaguch }
   3051  1.1  yamaguch 
   3052  1.1  yamaguch static inline int
   3053  1.1  yamaguch iavf_handle_queue_common(struct iavf_softc *sc, struct iavf_queue_pair *qp,
   3054  1.1  yamaguch     u_int txlimit, struct evcnt *txevcnt,
   3055  1.1  yamaguch     u_int rxlimit, struct evcnt *rxevcnt)
   3056  1.1  yamaguch {
   3057  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3058  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   3059  1.1  yamaguch 	int txmore, rxmore;
   3060  1.1  yamaguch 	int rv;
   3061  1.1  yamaguch 
   3062  1.1  yamaguch 	txr = qp->qp_txr;
   3063  1.1  yamaguch 	rxr = qp->qp_rxr;
   3064  1.1  yamaguch 
   3065  1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   3066  1.1  yamaguch 	txmore = iavf_txeof(sc, txr, txlimit, txevcnt);
   3067  1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   3068  1.1  yamaguch 
   3069  1.1  yamaguch 	mutex_enter(&rxr->rxr_lock);
   3070  1.1  yamaguch 	rxmore = iavf_rxeof(sc, rxr, rxlimit, rxevcnt);
   3071  1.1  yamaguch 	mutex_exit(&rxr->rxr_lock);
   3072  1.1  yamaguch 
   3073  1.1  yamaguch 	rv = txmore | (rxmore << 1);
   3074  1.1  yamaguch 
   3075  1.1  yamaguch 	return rv;
   3076  1.1  yamaguch }
   3077  1.1  yamaguch 
   3078  1.1  yamaguch static void
   3079  1.1  yamaguch iavf_sched_handle_queue(struct iavf_softc *sc, struct iavf_queue_pair *qp)
   3080  1.1  yamaguch {
   3081  1.1  yamaguch 
   3082  1.1  yamaguch 	if (qp->qp_workqueue)
   3083  1.1  yamaguch 		workqueue_enqueue(sc->sc_workq_txrx, &qp->qp_work, NULL);
   3084  1.1  yamaguch 	else
   3085  1.1  yamaguch 		softint_schedule(qp->qp_si);
   3086  1.1  yamaguch }
   3087  1.1  yamaguch 
   3088  1.1  yamaguch static void
   3089  1.1  yamaguch iavf_start(struct ifnet *ifp)
   3090  1.1  yamaguch {
   3091  1.1  yamaguch 	struct iavf_softc *sc;
   3092  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3093  1.1  yamaguch 
   3094  1.1  yamaguch 	sc = ifp->if_softc;
   3095  1.1  yamaguch 	txr = sc->sc_qps[0].qp_txr;
   3096  1.1  yamaguch 
   3097  1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   3098  1.1  yamaguch 	iavf_tx_common_locked(ifp, txr, false);
   3099  1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   3100  1.1  yamaguch 
   3101  1.1  yamaguch }
   3102  1.1  yamaguch 
   3103  1.1  yamaguch static inline unsigned int
   3104  1.1  yamaguch iavf_select_txqueue(struct iavf_softc *sc, struct mbuf *m)
   3105  1.1  yamaguch {
   3106  1.1  yamaguch 	u_int cpuid;
   3107  1.1  yamaguch 
   3108  1.1  yamaguch 	cpuid = cpu_index(curcpu());
   3109  1.1  yamaguch 
   3110  1.1  yamaguch 	return (unsigned int)(cpuid % sc->sc_nqueue_pairs);
   3111  1.1  yamaguch }
   3112  1.1  yamaguch 
   3113  1.1  yamaguch static int
   3114  1.1  yamaguch iavf_transmit(struct ifnet *ifp, struct mbuf *m)
   3115  1.1  yamaguch {
   3116  1.1  yamaguch 	struct iavf_softc *sc;
   3117  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3118  1.1  yamaguch 	unsigned int qid;
   3119  1.1  yamaguch 
   3120  1.1  yamaguch 	sc = ifp->if_softc;
   3121  1.1  yamaguch 	qid = iavf_select_txqueue(sc, m);
   3122  1.1  yamaguch 
   3123  1.1  yamaguch 	txr = sc->sc_qps[qid].qp_txr;
   3124  1.1  yamaguch 
   3125  1.1  yamaguch 	if (__predict_false(!pcq_put(txr->txr_intrq, m))) {
   3126  1.1  yamaguch 		mutex_enter(&txr->txr_lock);
   3127  1.1  yamaguch 		txr->txr_pcqdrop.ev_count++;
   3128  1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   3129  1.1  yamaguch 
   3130  1.1  yamaguch 		m_freem(m);
   3131  1.1  yamaguch 		return ENOBUFS;
   3132  1.1  yamaguch 	}
   3133  1.1  yamaguch 
   3134  1.1  yamaguch 	if (mutex_tryenter(&txr->txr_lock)) {
   3135  1.1  yamaguch 		iavf_tx_common_locked(ifp, txr, true);
   3136  1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   3137  1.1  yamaguch 	} else {
   3138  1.1  yamaguch 		kpreempt_disable();
   3139  1.1  yamaguch 		softint_schedule(txr->txr_si);
   3140  1.1  yamaguch 		kpreempt_enable();
   3141  1.1  yamaguch 	}
   3142  1.1  yamaguch 	return 0;
   3143  1.1  yamaguch }
   3144  1.1  yamaguch 
   3145  1.1  yamaguch static void
   3146  1.1  yamaguch iavf_deferred_transmit(void *xtxr)
   3147  1.1  yamaguch {
   3148  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3149  1.1  yamaguch 	struct iavf_softc *sc;
   3150  1.1  yamaguch 	struct ifnet *ifp;
   3151  1.1  yamaguch 
   3152  1.1  yamaguch 	txr = xtxr;
   3153  1.1  yamaguch 	sc = txr->txr_sc;
   3154  1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
   3155  1.1  yamaguch 
   3156  1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   3157  1.1  yamaguch 	txr->txr_transmitdef.ev_count++;
   3158  1.1  yamaguch 	if (pcq_peek(txr->txr_intrq) != NULL)
   3159  1.1  yamaguch 		iavf_tx_common_locked(ifp, txr, true);
   3160  1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   3161  1.1  yamaguch }
   3162  1.1  yamaguch 
   3163  1.1  yamaguch static void
   3164  1.1  yamaguch iavf_txr_clean(struct iavf_softc *sc, struct iavf_tx_ring *txr)
   3165  1.1  yamaguch {
   3166  1.1  yamaguch 	struct iavf_tx_map *maps, *txm;
   3167  1.1  yamaguch 	bus_dmamap_t map;
   3168  1.1  yamaguch 	unsigned int i;
   3169  1.1  yamaguch 
   3170  1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   3171  1.1  yamaguch 
   3172  1.1  yamaguch 	maps = txr->txr_maps;
   3173  1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   3174  1.1  yamaguch 		txm = &maps[i];
   3175  1.1  yamaguch 
   3176  1.1  yamaguch 		if (txm->txm_m == NULL)
   3177  1.1  yamaguch 			continue;
   3178  1.1  yamaguch 
   3179  1.1  yamaguch 		map = txm->txm_map;
   3180  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   3181  1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   3182  1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   3183  1.1  yamaguch 
   3184  1.1  yamaguch 		m_freem(txm->txm_m);
   3185  1.1  yamaguch 		txm->txm_m = NULL;
   3186  1.1  yamaguch 	}
   3187  1.1  yamaguch 
   3188  1.1  yamaguch 	memset(IXL_DMA_KVA(&txr->txr_mem), 0, IXL_DMA_LEN(&txr->txr_mem));
   3189  1.1  yamaguch 	txr->txr_prod = txr->txr_cons = 0;
   3190  1.1  yamaguch }
   3191  1.1  yamaguch 
   3192  1.1  yamaguch static int
   3193  1.1  yamaguch iavf_intr(void *xsc)
   3194  1.1  yamaguch {
   3195  1.1  yamaguch 	struct iavf_softc *sc = xsc;
   3196  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   3197  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   3198  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3199  1.1  yamaguch 	uint32_t icr;
   3200  1.1  yamaguch 	unsigned int i;
   3201  1.1  yamaguch 
   3202  1.1  yamaguch 	/* read I40E_VFINT_ICR_ENA1 to clear status */
   3203  1.1  yamaguch 	(void)iavf_rd(sc, I40E_VFINT_ICR0_ENA1);
   3204  1.1  yamaguch 
   3205  1.1  yamaguch 	iavf_intr_enable(sc);
   3206  1.1  yamaguch 	icr = iavf_rd(sc, I40E_VFINT_ICR01);
   3207  1.1  yamaguch 
   3208  1.1  yamaguch 	if (icr == IAVF_REG_VFR) {
   3209  1.1  yamaguch 		log(LOG_INFO, "%s: VF reset in progress\n",
   3210  1.1  yamaguch 		    ifp->if_xname);
   3211  1.1  yamaguch 		iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc);
   3212  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_reset_task);
   3213  1.1  yamaguch 		return 1;
   3214  1.1  yamaguch 	}
   3215  1.1  yamaguch 
   3216  1.1  yamaguch 	if (ISSET(icr, I40E_VFINT_ICR01_ADMINQ_MASK)) {
   3217  1.1  yamaguch 		mutex_enter(&sc->sc_adminq_lock);
   3218  1.1  yamaguch 		iavf_atq_done(sc);
   3219  1.1  yamaguch 		iavf_arq(sc);
   3220  1.1  yamaguch 		mutex_exit(&sc->sc_adminq_lock);
   3221  1.1  yamaguch 	}
   3222  1.1  yamaguch 
   3223  1.1  yamaguch 	if (ISSET(icr, I40E_VFINT_ICR01_QUEUE_0_MASK)) {
   3224  1.1  yamaguch 		for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   3225  1.1  yamaguch 			rxr = sc->sc_qps[i].qp_rxr;
   3226  1.1  yamaguch 			txr = sc->sc_qps[i].qp_txr;
   3227  1.1  yamaguch 
   3228  1.1  yamaguch 			mutex_enter(&rxr->rxr_lock);
   3229  1.1  yamaguch 			while (iavf_rxeof(sc, rxr, UINT_MAX,
   3230  1.1  yamaguch 			    &rxr->rxr_intr) != 0) {
   3231  1.1  yamaguch 				/* do nothing */
   3232  1.1  yamaguch 			}
   3233  1.1  yamaguch 			mutex_exit(&rxr->rxr_lock);
   3234  1.1  yamaguch 
   3235  1.1  yamaguch 			mutex_enter(&txr->txr_lock);
   3236  1.1  yamaguch 			while (iavf_txeof(sc, txr, UINT_MAX,
   3237  1.1  yamaguch 			    &txr->txr_intr) != 0) {
   3238  1.1  yamaguch 				/* do nothing */
   3239  1.1  yamaguch 			}
   3240  1.1  yamaguch 			mutex_exit(&txr->txr_lock);
   3241  1.1  yamaguch 		}
   3242  1.1  yamaguch 	}
   3243  1.1  yamaguch 
   3244  1.1  yamaguch 	return 0;
   3245  1.1  yamaguch }
   3246  1.1  yamaguch 
   3247  1.1  yamaguch static int
   3248  1.1  yamaguch iavf_queue_intr(void *xqp)
   3249  1.1  yamaguch {
   3250  1.1  yamaguch 	struct iavf_queue_pair *qp = xqp;
   3251  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3252  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   3253  1.1  yamaguch 	struct iavf_softc *sc;
   3254  1.1  yamaguch 	unsigned int qid;
   3255  1.1  yamaguch 	u_int txlimit, rxlimit;
   3256  1.1  yamaguch 	int more;
   3257  1.1  yamaguch 
   3258  1.1  yamaguch 	txr = qp->qp_txr;
   3259  1.1  yamaguch 	rxr = qp->qp_rxr;
   3260  1.1  yamaguch 	sc = txr->txr_sc;
   3261  1.1  yamaguch 	qid = txr->txr_qid;
   3262  1.1  yamaguch 
   3263  1.1  yamaguch 	txlimit = sc->sc_tx_intr_process_limit;
   3264  1.1  yamaguch 	rxlimit = sc->sc_rx_intr_process_limit;
   3265  1.1  yamaguch 	qp->qp_workqueue = sc->sc_txrx_workqueue;
   3266  1.1  yamaguch 
   3267  1.1  yamaguch 	more = iavf_handle_queue_common(sc, qp,
   3268  1.1  yamaguch 	    txlimit, &txr->txr_intr, rxlimit, &rxr->rxr_intr);
   3269  1.1  yamaguch 
   3270  1.1  yamaguch 	if (more != 0) {
   3271  1.1  yamaguch 		iavf_sched_handle_queue(sc, qp);
   3272  1.1  yamaguch 	} else {
   3273  1.1  yamaguch 		/* for ALTQ */
   3274  1.1  yamaguch 		if (txr->txr_qid == 0)
   3275  1.1  yamaguch 			if_schedule_deferred_start(&sc->sc_ec.ec_if);
   3276  1.1  yamaguch 		softint_schedule(txr->txr_si);
   3277  1.1  yamaguch 
   3278  1.1  yamaguch 		iavf_queue_intr_enable(sc, qid);
   3279  1.1  yamaguch 	}
   3280  1.1  yamaguch 
   3281  1.1  yamaguch 	return 0;
   3282  1.1  yamaguch }
   3283  1.1  yamaguch 
   3284  1.1  yamaguch static void
   3285  1.1  yamaguch iavf_handle_queue_wk(struct work *wk, void *xsc __unused)
   3286  1.1  yamaguch {
   3287  1.1  yamaguch 	struct iavf_queue_pair *qp;
   3288  1.1  yamaguch 
   3289  1.1  yamaguch 	qp = container_of(wk, struct iavf_queue_pair, qp_work);
   3290  1.1  yamaguch 	iavf_handle_queue(qp);
   3291  1.1  yamaguch }
   3292  1.1  yamaguch 
   3293  1.1  yamaguch static void
   3294  1.1  yamaguch iavf_handle_queue(void *xqp)
   3295  1.1  yamaguch {
   3296  1.1  yamaguch 	struct iavf_queue_pair *qp = xqp;
   3297  1.1  yamaguch 	struct iavf_tx_ring *txr;
   3298  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   3299  1.1  yamaguch 	struct iavf_softc *sc;
   3300  1.1  yamaguch 	unsigned int qid;
   3301  1.1  yamaguch 	u_int txlimit, rxlimit;
   3302  1.1  yamaguch 	int more;
   3303  1.1  yamaguch 
   3304  1.1  yamaguch 	txr = qp->qp_txr;
   3305  1.1  yamaguch 	rxr = qp->qp_rxr;
   3306  1.1  yamaguch 	sc = txr->txr_sc;
   3307  1.1  yamaguch 	qid = txr->txr_qid;
   3308  1.1  yamaguch 
   3309  1.1  yamaguch 	txlimit = sc->sc_tx_process_limit;
   3310  1.1  yamaguch 	rxlimit = sc->sc_rx_process_limit;
   3311  1.1  yamaguch 
   3312  1.1  yamaguch 	more = iavf_handle_queue_common(sc, qp,
   3313  1.1  yamaguch 	    txlimit, &txr->txr_defer, rxlimit, &rxr->rxr_defer);
   3314  1.1  yamaguch 
   3315  1.1  yamaguch 	if (more != 0)
   3316  1.1  yamaguch 		iavf_sched_handle_queue(sc, qp);
   3317  1.1  yamaguch 	else
   3318  1.1  yamaguch 		iavf_queue_intr_enable(sc, qid);
   3319  1.1  yamaguch }
   3320  1.1  yamaguch 
   3321  1.1  yamaguch static void
   3322  1.1  yamaguch iavf_tick(void *xsc)
   3323  1.1  yamaguch {
   3324  1.1  yamaguch 	struct iavf_softc *sc;
   3325  1.1  yamaguch 	unsigned int i;
   3326  1.1  yamaguch 	int timedout;
   3327  1.1  yamaguch 
   3328  1.1  yamaguch 	sc = xsc;
   3329  1.1  yamaguch 	timedout = 0;
   3330  1.1  yamaguch 
   3331  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   3332  1.1  yamaguch 
   3333  1.1  yamaguch 	if (sc->sc_resetting) {
   3334  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_reset_task);
   3335  1.1  yamaguch 		mutex_exit(&sc->sc_cfg_lock);
   3336  1.1  yamaguch 		return;
   3337  1.1  yamaguch 	}
   3338  1.1  yamaguch 
   3339  1.1  yamaguch 	iavf_get_stats(sc);
   3340  1.1  yamaguch 
   3341  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   3342  1.1  yamaguch 		timedout |= iavf_watchdog(sc->sc_qps[i].qp_txr);
   3343  1.1  yamaguch 	}
   3344  1.1  yamaguch 
   3345  1.1  yamaguch 	if (timedout != 0) {
   3346  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_wdto_task);
   3347  1.1  yamaguch 	} else {
   3348  1.1  yamaguch 		callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL);
   3349  1.1  yamaguch 	}
   3350  1.1  yamaguch 
   3351  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   3352  1.1  yamaguch }
   3353  1.1  yamaguch 
   3354  1.1  yamaguch static void
   3355  1.1  yamaguch iavf_tick_halt(void *unused __unused)
   3356  1.1  yamaguch {
   3357  1.1  yamaguch 
   3358  1.1  yamaguch 	/* do nothing */
   3359  1.1  yamaguch }
   3360  1.1  yamaguch 
   3361  1.1  yamaguch static void
   3362  1.1  yamaguch iavf_reset_request(void *xsc)
   3363  1.1  yamaguch {
   3364  1.1  yamaguch 	struct iavf_softc *sc = xsc;
   3365  1.1  yamaguch 
   3366  1.1  yamaguch 	iavf_reset_vf(sc);
   3367  1.1  yamaguch 	iavf_reset_start(sc);
   3368  1.1  yamaguch }
   3369  1.1  yamaguch 
   3370  1.1  yamaguch static void
   3371  1.1  yamaguch iavf_reset_start(void *xsc)
   3372  1.1  yamaguch {
   3373  1.1  yamaguch 	struct iavf_softc *sc = xsc;
   3374  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   3375  1.1  yamaguch 
   3376  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   3377  1.1  yamaguch 
   3378  1.1  yamaguch 	if (sc->sc_resetting)
   3379  1.1  yamaguch 		goto do_reset;
   3380  1.1  yamaguch 
   3381  1.1  yamaguch 	sc->sc_resetting = true;
   3382  1.1  yamaguch 	if_link_state_change(ifp, LINK_STATE_DOWN);
   3383  1.1  yamaguch 
   3384  1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
   3385  1.1  yamaguch 		iavf_stop_locked(sc);
   3386  1.1  yamaguch 		sc->sc_reset_up = true;
   3387  1.1  yamaguch 	}
   3388  1.1  yamaguch 
   3389  1.1  yamaguch 	memcpy(sc->sc_enaddr_reset, sc->sc_enaddr, ETHER_ADDR_LEN);
   3390  1.1  yamaguch 
   3391  1.1  yamaguch do_reset:
   3392  1.1  yamaguch 	iavf_work_set(&sc->sc_reset_task, iavf_reset, sc);
   3393  1.1  yamaguch 
   3394  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   3395  1.1  yamaguch 
   3396  1.1  yamaguch 	iavf_reset((void *)sc);
   3397  1.1  yamaguch }
   3398  1.1  yamaguch 
   3399  1.1  yamaguch static void
   3400  1.1  yamaguch iavf_reset(void *xsc)
   3401  1.1  yamaguch {
   3402  1.1  yamaguch 	struct iavf_softc *sc = xsc;
   3403  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   3404  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3405  1.1  yamaguch 	bool realloc_qps, realloc_intrs;
   3406  1.1  yamaguch 
   3407  1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   3408  1.1  yamaguch 
   3409  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   3410  1.1  yamaguch 	iavf_cleanup_admin_queue(sc);
   3411  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   3412  1.1  yamaguch 
   3413  1.1  yamaguch 	sc->sc_major_ver = UINT_MAX;
   3414  1.1  yamaguch 	sc->sc_minor_ver = UINT_MAX;
   3415  1.1  yamaguch 	sc->sc_got_vf_resources = 0;
   3416  1.1  yamaguch 	sc->sc_got_irq_map = 0;
   3417  1.1  yamaguch 
   3418  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   3419  1.1  yamaguch 	if (aqb == NULL)
   3420  1.1  yamaguch 		goto failed;
   3421  1.1  yamaguch 
   3422  1.1  yamaguch 	if (iavf_wait_active(sc) != 0) {
   3423  1.1  yamaguch 		log(LOG_WARNING, "%s: VF reset timed out\n",
   3424  1.1  yamaguch 		    ifp->if_xname);
   3425  1.1  yamaguch 		goto failed;
   3426  1.1  yamaguch 	}
   3427  1.1  yamaguch 
   3428  1.1  yamaguch 	if (!iavf_arq_fill(sc)) {
   3429  1.1  yamaguch 		log(LOG_ERR, "%s: unable to fill arq descriptors\n",
   3430  1.1  yamaguch 		    ifp->if_xname);
   3431  1.1  yamaguch 		goto failed;
   3432  1.1  yamaguch 	}
   3433  1.1  yamaguch 
   3434  1.1  yamaguch 	if (iavf_init_admin_queue(sc) != 0) {
   3435  1.1  yamaguch 		log(LOG_ERR, "%s: unable to initialize admin queue\n",
   3436  1.1  yamaguch 		    ifp->if_xname);
   3437  1.1  yamaguch 		goto failed;
   3438  1.1  yamaguch 	}
   3439  1.1  yamaguch 
   3440  1.1  yamaguch 	if (iavf_get_version(sc, aqb) != 0) {
   3441  1.1  yamaguch 		log(LOG_ERR, "%s: unable to get VF interface version\n",
   3442  1.1  yamaguch 		    ifp->if_xname);
   3443  1.1  yamaguch 		goto failed;
   3444  1.1  yamaguch 	}
   3445  1.1  yamaguch 
   3446  1.1  yamaguch 	if (iavf_get_vf_resources(sc, aqb) != 0) {
   3447  1.1  yamaguch 		log(LOG_ERR, "%s: timed out waiting for VF resources\n",
   3448  1.1  yamaguch 		    ifp->if_xname);
   3449  1.1  yamaguch 		goto failed;
   3450  1.1  yamaguch 	}
   3451  1.1  yamaguch 
   3452  1.1  yamaguch 	if (sc->sc_nqps_alloc < iavf_calc_queue_pair_size(sc)) {
   3453  1.1  yamaguch 		realloc_qps = true;
   3454  1.1  yamaguch 	} else {
   3455  1.1  yamaguch 		realloc_qps = false;
   3456  1.1  yamaguch 	}
   3457  1.1  yamaguch 
   3458  1.1  yamaguch 	if (sc->sc_nintrs < iavf_calc_msix_count(sc)) {
   3459  1.1  yamaguch 		realloc_intrs = true;
   3460  1.1  yamaguch 	} else {
   3461  1.1  yamaguch 		realloc_intrs = false;
   3462  1.1  yamaguch 	}
   3463  1.1  yamaguch 
   3464  1.1  yamaguch 	if (realloc_qps || realloc_intrs)
   3465  1.1  yamaguch 		iavf_teardown_interrupts(sc);
   3466  1.1  yamaguch 
   3467  1.1  yamaguch 	if (realloc_qps) {
   3468  1.1  yamaguch 		iavf_queue_pairs_free(sc);
   3469  1.1  yamaguch 		if (iavf_queue_pairs_alloc(sc) != 0) {
   3470  1.1  yamaguch 			log(LOG_ERR, "%s: failed to allocate queue pairs\n",
   3471  1.1  yamaguch 			    ifp->if_xname);
   3472  1.1  yamaguch 			goto failed;
   3473  1.1  yamaguch 		}
   3474  1.1  yamaguch 	}
   3475  1.1  yamaguch 
   3476  1.1  yamaguch 	if (realloc_qps || realloc_intrs) {
   3477  1.1  yamaguch 		if (iavf_setup_interrupts(sc) != 0) {
   3478  1.1  yamaguch 			sc->sc_nintrs = 0;
   3479  1.1  yamaguch 			log(LOG_ERR, "%s: failed to allocate interrupts\n",
   3480  1.1  yamaguch 			    ifp->if_xname);
   3481  1.1  yamaguch 			goto failed;
   3482  1.1  yamaguch 		}
   3483  1.1  yamaguch 		log(LOG_INFO, "%s: reallocated queues\n", ifp->if_xname);
   3484  1.1  yamaguch 	}
   3485  1.1  yamaguch 
   3486  1.1  yamaguch 	if (iavf_config_irq_map(sc, aqb) != 0) {
   3487  1.1  yamaguch 		log(LOG_ERR, "%s: timed out configuring IRQ map\n",
   3488  1.1  yamaguch 		   ifp->if_xname);
   3489  1.1  yamaguch 		goto failed;
   3490  1.1  yamaguch 	}
   3491  1.1  yamaguch 
   3492  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   3493  1.1  yamaguch 	iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   3494  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   3495  1.1  yamaguch 
   3496  1.1  yamaguch 	iavf_reset_finish(sc);
   3497  1.1  yamaguch 
   3498  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   3499  1.1  yamaguch 	return;
   3500  1.1  yamaguch 
   3501  1.1  yamaguch failed:
   3502  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   3503  1.1  yamaguch 	iavf_cleanup_admin_queue(sc);
   3504  1.1  yamaguch 	if (aqb != NULL) {
   3505  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   3506  1.1  yamaguch 	}
   3507  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   3508  1.1  yamaguch 	callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL);
   3509  1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   3510  1.1  yamaguch }
   3511  1.1  yamaguch 
   3512  1.1  yamaguch static void
   3513  1.1  yamaguch iavf_reset_finish(struct iavf_softc *sc)
   3514  1.1  yamaguch {
   3515  1.1  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   3516  1.1  yamaguch 	struct ether_multi *enm;
   3517  1.1  yamaguch 	struct ether_multistep step;
   3518  1.1  yamaguch 	struct ifnet *ifp = &ec->ec_if;
   3519  1.1  yamaguch 	struct vlanid_list *vlanidp;
   3520  1.1  yamaguch 
   3521  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   3522  1.1  yamaguch 
   3523  1.1  yamaguch 	callout_stop(&sc->sc_tick);
   3524  1.1  yamaguch 
   3525  1.1  yamaguch 	iavf_intr_enable(sc);
   3526  1.1  yamaguch 
   3527  1.1  yamaguch 	if (!iavf_is_etheranyaddr(sc->sc_enaddr_added)) {
   3528  1.1  yamaguch 		iavf_eth_addr(sc, sc->sc_enaddr_added, IAVF_VC_OP_ADD_ETH_ADDR);
   3529  1.1  yamaguch 	}
   3530  1.1  yamaguch 
   3531  1.1  yamaguch 	ETHER_LOCK(ec);
   3532  1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) {
   3533  1.1  yamaguch 		for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   3534  1.1  yamaguch 		    ETHER_NEXT_MULTI(step, enm)) {
   3535  1.1  yamaguch 			iavf_add_multi(sc, enm->enm_addrlo, enm->enm_addrhi);
   3536  1.1  yamaguch 		}
   3537  1.1  yamaguch 	}
   3538  1.1  yamaguch 
   3539  1.1  yamaguch 	SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
   3540  1.1  yamaguch 		ETHER_UNLOCK(ec);
   3541  1.1  yamaguch 		iavf_config_vlan_id(sc, vlanidp->vid, IAVF_VC_OP_ADD_VLAN);
   3542  1.1  yamaguch 		ETHER_LOCK(ec);
   3543  1.1  yamaguch 	}
   3544  1.1  yamaguch 	ETHER_UNLOCK(ec);
   3545  1.1  yamaguch 
   3546  1.1  yamaguch 	if (memcmp(sc->sc_enaddr, sc->sc_enaddr_reset, ETHER_ADDR_LEN) != 0) {
   3547  1.1  yamaguch 		log(LOG_INFO, "%s: Ethernet address changed to %s\n",
   3548  1.1  yamaguch 		    ifp->if_xname, ether_sprintf(sc->sc_enaddr));
   3549  1.1  yamaguch 		IFNET_LOCK(ifp);
   3550  1.1  yamaguch 		kpreempt_disable();
   3551  1.1  yamaguch 		/*XXX we need an API to change ethernet address. */
   3552  1.1  yamaguch 		iavf_replace_lla(ifp, sc->sc_enaddr_reset, sc->sc_enaddr);
   3553  1.1  yamaguch 		kpreempt_enable();
   3554  1.1  yamaguch 		IFNET_UNLOCK(ifp);
   3555  1.1  yamaguch 	}
   3556  1.1  yamaguch 
   3557  1.1  yamaguch 	sc->sc_resetting = false;
   3558  1.1  yamaguch 
   3559  1.1  yamaguch 	if (sc->sc_reset_up) {
   3560  1.1  yamaguch 		iavf_init_locked(sc);
   3561  1.1  yamaguch 	}
   3562  1.1  yamaguch 
   3563  1.1  yamaguch 	if (sc->sc_link_state != LINK_STATE_DOWN) {
   3564  1.1  yamaguch 		if_link_state_change(ifp, sc->sc_link_state);
   3565  1.1  yamaguch 	}
   3566  1.1  yamaguch 
   3567  1.1  yamaguch }
   3568  1.1  yamaguch 
   3569  1.1  yamaguch static int
   3570  1.1  yamaguch iavf_dmamem_alloc(bus_dma_tag_t dmat, struct ixl_dmamem *ixm,
   3571  1.1  yamaguch     bus_size_t size, bus_size_t align)
   3572  1.1  yamaguch {
   3573  1.1  yamaguch 	ixm->ixm_size = size;
   3574  1.1  yamaguch 
   3575  1.1  yamaguch 	if (bus_dmamap_create(dmat, ixm->ixm_size, 1,
   3576  1.1  yamaguch 	    ixm->ixm_size, 0,
   3577  1.1  yamaguch 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
   3578  1.1  yamaguch 	    &ixm->ixm_map) != 0)
   3579  1.1  yamaguch 		return 1;
   3580  1.1  yamaguch 	if (bus_dmamem_alloc(dmat, ixm->ixm_size,
   3581  1.1  yamaguch 	    align, 0, &ixm->ixm_seg, 1, &ixm->ixm_nsegs,
   3582  1.1  yamaguch 	    BUS_DMA_WAITOK) != 0)
   3583  1.1  yamaguch 		goto destroy;
   3584  1.1  yamaguch 	if (bus_dmamem_map(dmat, &ixm->ixm_seg, ixm->ixm_nsegs,
   3585  1.1  yamaguch 	    ixm->ixm_size, &ixm->ixm_kva, BUS_DMA_WAITOK) != 0)
   3586  1.1  yamaguch 		goto free;
   3587  1.1  yamaguch 	if (bus_dmamap_load(dmat, ixm->ixm_map, ixm->ixm_kva,
   3588  1.1  yamaguch 	    ixm->ixm_size, NULL, BUS_DMA_WAITOK) != 0)
   3589  1.1  yamaguch 		goto unmap;
   3590  1.1  yamaguch 
   3591  1.1  yamaguch 	memset(ixm->ixm_kva, 0, ixm->ixm_size);
   3592  1.1  yamaguch 
   3593  1.1  yamaguch 	return 0;
   3594  1.1  yamaguch unmap:
   3595  1.1  yamaguch 	bus_dmamem_unmap(dmat, ixm->ixm_kva, ixm->ixm_size);
   3596  1.1  yamaguch free:
   3597  1.1  yamaguch 	bus_dmamem_free(dmat, &ixm->ixm_seg, 1);
   3598  1.1  yamaguch destroy:
   3599  1.1  yamaguch 	bus_dmamap_destroy(dmat, ixm->ixm_map);
   3600  1.1  yamaguch 	return 1;
   3601  1.1  yamaguch }
   3602  1.1  yamaguch 
   3603  1.1  yamaguch static void
   3604  1.1  yamaguch iavf_dmamem_free(bus_dma_tag_t dmat, struct ixl_dmamem *ixm)
   3605  1.1  yamaguch {
   3606  1.1  yamaguch 
   3607  1.1  yamaguch 	bus_dmamap_unload(dmat, ixm->ixm_map);
   3608  1.1  yamaguch 	bus_dmamem_unmap(dmat, ixm->ixm_kva, ixm->ixm_size);
   3609  1.1  yamaguch 	bus_dmamem_free(dmat, &ixm->ixm_seg, 1);
   3610  1.1  yamaguch 	bus_dmamap_destroy(dmat, ixm->ixm_map);
   3611  1.1  yamaguch }
   3612  1.1  yamaguch 
   3613  1.1  yamaguch static struct ixl_aq_buf *
   3614  1.1  yamaguch iavf_aqb_alloc(bus_dma_tag_t dmat, size_t buflen)
   3615  1.1  yamaguch {
   3616  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3617  1.1  yamaguch 
   3618  1.1  yamaguch 	aqb = kmem_alloc(sizeof(*aqb), KM_NOSLEEP);
   3619  1.1  yamaguch 	if (aqb == NULL)
   3620  1.1  yamaguch 		return NULL;
   3621  1.1  yamaguch 
   3622  1.1  yamaguch 	aqb->aqb_size = buflen;
   3623  1.1  yamaguch 
   3624  1.1  yamaguch 	if (bus_dmamap_create(dmat, aqb->aqb_size, 1,
   3625  1.1  yamaguch 	    aqb->aqb_size, 0,
   3626  1.1  yamaguch 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &aqb->aqb_map) != 0)
   3627  1.1  yamaguch 		goto free;
   3628  1.1  yamaguch 	if (bus_dmamem_alloc(dmat, aqb->aqb_size,
   3629  1.1  yamaguch 	    IAVF_AQ_ALIGN, 0, &aqb->aqb_seg, 1, &aqb->aqb_nsegs,
   3630  1.1  yamaguch 	    BUS_DMA_WAITOK) != 0)
   3631  1.1  yamaguch 		goto destroy;
   3632  1.1  yamaguch 	if (bus_dmamem_map(dmat, &aqb->aqb_seg, aqb->aqb_nsegs,
   3633  1.1  yamaguch 	    aqb->aqb_size, &aqb->aqb_data, BUS_DMA_WAITOK) != 0)
   3634  1.1  yamaguch 		goto dma_free;
   3635  1.1  yamaguch 	if (bus_dmamap_load(dmat, aqb->aqb_map, aqb->aqb_data,
   3636  1.1  yamaguch 	    aqb->aqb_size, NULL, BUS_DMA_WAITOK) != 0)
   3637  1.1  yamaguch 		goto unmap;
   3638  1.1  yamaguch 
   3639  1.1  yamaguch 	return aqb;
   3640  1.1  yamaguch unmap:
   3641  1.1  yamaguch 	bus_dmamem_unmap(dmat, aqb->aqb_data, aqb->aqb_size);
   3642  1.1  yamaguch dma_free:
   3643  1.1  yamaguch 	bus_dmamem_free(dmat, &aqb->aqb_seg, 1);
   3644  1.1  yamaguch destroy:
   3645  1.1  yamaguch 	bus_dmamap_destroy(dmat, aqb->aqb_map);
   3646  1.1  yamaguch free:
   3647  1.1  yamaguch 	kmem_free(aqb, sizeof(*aqb));
   3648  1.1  yamaguch 
   3649  1.1  yamaguch 	return NULL;
   3650  1.1  yamaguch }
   3651  1.1  yamaguch 
   3652  1.1  yamaguch static void
   3653  1.1  yamaguch iavf_aqb_free(bus_dma_tag_t dmat, struct ixl_aq_buf *aqb)
   3654  1.1  yamaguch {
   3655  1.1  yamaguch 
   3656  1.1  yamaguch 	bus_dmamap_unload(dmat, aqb->aqb_map);
   3657  1.1  yamaguch 	bus_dmamem_unmap(dmat, aqb->aqb_data, aqb->aqb_size);
   3658  1.1  yamaguch 	bus_dmamem_free(dmat, &aqb->aqb_seg, 1);
   3659  1.1  yamaguch 	bus_dmamap_destroy(dmat, aqb->aqb_map);
   3660  1.1  yamaguch 	kmem_free(aqb, sizeof(*aqb));
   3661  1.1  yamaguch }
   3662  1.1  yamaguch 
   3663  1.1  yamaguch static struct ixl_aq_buf *
   3664  1.1  yamaguch iavf_aqb_get_locked(struct ixl_aq_bufs *q)
   3665  1.1  yamaguch {
   3666  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3667  1.1  yamaguch 
   3668  1.1  yamaguch 	aqb = SIMPLEQ_FIRST(q);
   3669  1.1  yamaguch 	if (aqb != NULL) {
   3670  1.1  yamaguch 		SIMPLEQ_REMOVE(q, aqb, ixl_aq_buf, aqb_entry);
   3671  1.1  yamaguch 	}
   3672  1.1  yamaguch 
   3673  1.1  yamaguch 	return aqb;
   3674  1.1  yamaguch }
   3675  1.1  yamaguch 
   3676  1.1  yamaguch static struct ixl_aq_buf *
   3677  1.1  yamaguch iavf_aqb_get(struct iavf_softc *sc, struct ixl_aq_bufs *q)
   3678  1.1  yamaguch {
   3679  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3680  1.1  yamaguch 
   3681  1.1  yamaguch 	if (q != NULL) {
   3682  1.1  yamaguch 		mutex_enter(&sc->sc_adminq_lock);
   3683  1.1  yamaguch 		aqb = iavf_aqb_get_locked(q);
   3684  1.1  yamaguch 		mutex_exit(&sc->sc_adminq_lock);
   3685  1.1  yamaguch 	} else {
   3686  1.1  yamaguch 		aqb = NULL;
   3687  1.1  yamaguch 	}
   3688  1.1  yamaguch 
   3689  1.1  yamaguch 	if (aqb == NULL) {
   3690  1.1  yamaguch 		aqb = iavf_aqb_alloc(sc->sc_dmat, IAVF_AQ_BUFLEN);
   3691  1.1  yamaguch 	}
   3692  1.1  yamaguch 
   3693  1.1  yamaguch 	return aqb;
   3694  1.1  yamaguch }
   3695  1.1  yamaguch 
   3696  1.1  yamaguch static void
   3697  1.1  yamaguch iavf_aqb_put_locked(struct ixl_aq_bufs *q, struct ixl_aq_buf *aqb)
   3698  1.1  yamaguch {
   3699  1.1  yamaguch 
   3700  1.1  yamaguch 	SIMPLEQ_INSERT_TAIL(q, aqb, aqb_entry);
   3701  1.1  yamaguch }
   3702  1.1  yamaguch 
   3703  1.1  yamaguch static void
   3704  1.1  yamaguch iavf_aqb_clean(struct ixl_aq_bufs *q, bus_dma_tag_t dmat)
   3705  1.1  yamaguch {
   3706  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3707  1.1  yamaguch 
   3708  1.1  yamaguch 	while ((aqb = SIMPLEQ_FIRST(q)) != NULL) {
   3709  1.1  yamaguch 		SIMPLEQ_REMOVE(q, aqb, ixl_aq_buf, aqb_entry);
   3710  1.1  yamaguch 		iavf_aqb_free(dmat, aqb);
   3711  1.1  yamaguch 	}
   3712  1.1  yamaguch }
   3713  1.1  yamaguch 
   3714  1.1  yamaguch static const char *
   3715  1.1  yamaguch iavf_aq_vc_opcode_str(const struct ixl_aq_desc *iaq)
   3716  1.1  yamaguch {
   3717  1.1  yamaguch 
   3718  1.1  yamaguch 	switch (iavf_aq_vc_get_opcode(iaq)) {
   3719  1.1  yamaguch 	case IAVF_VC_OP_VERSION:
   3720  1.1  yamaguch 		return "GET_VERSION";
   3721  1.1  yamaguch 	case IAVF_VC_OP_RESET_VF:
   3722  1.1  yamaguch 		return "RESET_VF";
   3723  1.1  yamaguch 	case IAVF_VC_OP_GET_VF_RESOURCES:
   3724  1.1  yamaguch 		return "GET_VF_RESOURCES";
   3725  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_TX_QUEUE:
   3726  1.1  yamaguch 		return "CONFIG_TX_QUEUE";
   3727  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_RX_QUEUE:
   3728  1.1  yamaguch 		return "CONFIG_RX_QUEUE";
   3729  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_VSI_QUEUES:
   3730  1.1  yamaguch 		return "CONFIG_VSI_QUEUES";
   3731  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_IRQ_MAP:
   3732  1.1  yamaguch 		return "CONFIG_IRQ_MAP";
   3733  1.1  yamaguch 	case IAVF_VC_OP_ENABLE_QUEUES:
   3734  1.1  yamaguch 		return "ENABLE_QUEUES";
   3735  1.1  yamaguch 	case IAVF_VC_OP_DISABLE_QUEUES:
   3736  1.1  yamaguch 		return "DISABLE_QUEUES";
   3737  1.1  yamaguch 	case IAVF_VC_OP_ADD_ETH_ADDR:
   3738  1.1  yamaguch 		return "ADD_ETH_ADDR";
   3739  1.1  yamaguch 	case IAVF_VC_OP_DEL_ETH_ADDR:
   3740  1.1  yamaguch 		return "DEL_ETH_ADDR";
   3741  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_PROMISC:
   3742  1.1  yamaguch 		return "CONFIG_PROMISC";
   3743  1.1  yamaguch 	case IAVF_VC_OP_GET_STATS:
   3744  1.1  yamaguch 		return "GET_STATS";
   3745  1.1  yamaguch 	case IAVF_VC_OP_EVENT:
   3746  1.1  yamaguch 		return "EVENT";
   3747  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_RSS_KEY:
   3748  1.1  yamaguch 		return "CONFIG_RSS_KEY";
   3749  1.1  yamaguch 	case IAVF_VC_OP_GET_RSS_HENA_CAPS:
   3750  1.1  yamaguch 		return "GET_RS_HENA_CAPS";
   3751  1.1  yamaguch 	case IAVF_VC_OP_SET_RSS_HENA:
   3752  1.1  yamaguch 		return "SET_RSS_HENA";
   3753  1.1  yamaguch 	case IAVF_VC_OP_ENABLE_VLAN_STRIP:
   3754  1.1  yamaguch 		return "ENABLE_VLAN_STRIPPING";
   3755  1.1  yamaguch 	case IAVF_VC_OP_DISABLE_VLAN_STRIP:
   3756  1.1  yamaguch 		return "DISABLE_VLAN_STRIPPING";
   3757  1.1  yamaguch 	case IAVF_VC_OP_REQUEST_QUEUES:
   3758  1.1  yamaguch 		return "REQUEST_QUEUES";
   3759  1.1  yamaguch 	}
   3760  1.1  yamaguch 
   3761  1.1  yamaguch 	return "unknown";
   3762  1.1  yamaguch }
   3763  1.1  yamaguch 
   3764  1.1  yamaguch static void
   3765  1.1  yamaguch iavf_aq_dump(const struct iavf_softc *sc, const struct ixl_aq_desc *iaq,
   3766  1.1  yamaguch     const char *msg)
   3767  1.1  yamaguch {
   3768  1.1  yamaguch 	char	 buf[512];
   3769  1.1  yamaguch 	size_t	 len;
   3770  1.1  yamaguch 
   3771  1.1  yamaguch 	len = sizeof(buf);
   3772  1.1  yamaguch 	buf[--len] = '\0';
   3773  1.1  yamaguch 
   3774  1.1  yamaguch 	device_printf(sc->sc_dev, "%s\n", msg);
   3775  1.1  yamaguch 	snprintb(buf, len, IXL_AQ_FLAGS_FMT, le16toh(iaq->iaq_flags));
   3776  1.1  yamaguch 	device_printf(sc->sc_dev, "flags %s opcode %04x\n",
   3777  1.1  yamaguch 	    buf, le16toh(iaq->iaq_opcode));
   3778  1.1  yamaguch 	device_printf(sc->sc_dev, "datalen %u retval %u\n",
   3779  1.1  yamaguch 	    le16toh(iaq->iaq_datalen), le16toh(iaq->iaq_retval));
   3780  1.1  yamaguch 	device_printf(sc->sc_dev, "vc-opcode %u (%s)\n",
   3781  1.1  yamaguch 	    iavf_aq_vc_get_opcode(iaq),
   3782  1.1  yamaguch 	    iavf_aq_vc_opcode_str(iaq));
   3783  1.1  yamaguch 	device_printf(sc->sc_dev, "vc-retval %u\n",
   3784  1.1  yamaguch 	    iavf_aq_vc_get_retval(iaq));
   3785  1.1  yamaguch 	device_printf(sc->sc_dev, "cookie %016" PRIx64 "\n", iaq->iaq_cookie);
   3786  1.1  yamaguch 	device_printf(sc->sc_dev, "%08x %08x %08x %08x\n",
   3787  1.1  yamaguch 	    le32toh(iaq->iaq_param[0]), le32toh(iaq->iaq_param[1]),
   3788  1.1  yamaguch 	    le32toh(iaq->iaq_param[2]), le32toh(iaq->iaq_param[3]));
   3789  1.1  yamaguch }
   3790  1.1  yamaguch 
   3791  1.1  yamaguch static int
   3792  1.1  yamaguch iavf_arq_fill(struct iavf_softc *sc)
   3793  1.1  yamaguch {
   3794  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3795  1.1  yamaguch 	struct ixl_aq_desc *arq, *iaq;
   3796  1.1  yamaguch 	unsigned int prod = sc->sc_arq_prod;
   3797  1.1  yamaguch 	unsigned int n;
   3798  1.1  yamaguch 	int filled;
   3799  1.1  yamaguch 
   3800  1.1  yamaguch 	n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons,
   3801  1.1  yamaguch 	    IAVF_AQ_NUM);
   3802  1.1  yamaguch 
   3803  1.1  yamaguch 	if (__predict_false(n <= 0))
   3804  1.1  yamaguch 		return 0;
   3805  1.1  yamaguch 
   3806  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   3807  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   3808  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   3809  1.1  yamaguch 
   3810  1.1  yamaguch 	arq = IXL_DMA_KVA(&sc->sc_arq);
   3811  1.1  yamaguch 
   3812  1.1  yamaguch 	do {
   3813  1.1  yamaguch 		iaq = &arq[prod];
   3814  1.1  yamaguch 
   3815  1.1  yamaguch 		if (ixl_aq_has_dva(iaq)) {
   3816  1.1  yamaguch 			/* already filled */
   3817  1.1  yamaguch 			break;
   3818  1.1  yamaguch 		}
   3819  1.1  yamaguch 
   3820  1.1  yamaguch 		aqb = iavf_aqb_get_locked(&sc->sc_arq_idle);
   3821  1.1  yamaguch 		if (aqb == NULL)
   3822  1.1  yamaguch 			break;
   3823  1.1  yamaguch 
   3824  1.1  yamaguch 		memset(aqb->aqb_data, 0, aqb->aqb_size);
   3825  1.1  yamaguch 
   3826  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0,
   3827  1.1  yamaguch 		    aqb->aqb_size, BUS_DMASYNC_PREREAD);
   3828  1.1  yamaguch 
   3829  1.1  yamaguch 		iaq->iaq_flags = htole16(IXL_AQ_BUF |
   3830  1.1  yamaguch 		    (aqb->aqb_size > I40E_AQ_LARGE_BUF ?
   3831  1.1  yamaguch 		    IXL_AQ_LB : 0));
   3832  1.1  yamaguch 		iaq->iaq_opcode = 0;
   3833  1.1  yamaguch 		iaq->iaq_datalen = htole16(aqb->aqb_size);
   3834  1.1  yamaguch 		iaq->iaq_retval = 0;
   3835  1.1  yamaguch 		iaq->iaq_cookie = 0;
   3836  1.1  yamaguch 		iaq->iaq_param[0] = 0;
   3837  1.1  yamaguch 		iaq->iaq_param[1] = 0;
   3838  1.1  yamaguch 		ixl_aq_dva(iaq, IXL_AQB_DVA(aqb));
   3839  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_arq_live, aqb);
   3840  1.1  yamaguch 
   3841  1.1  yamaguch 		prod++;
   3842  1.1  yamaguch 		prod &= IAVF_AQ_MASK;
   3843  1.1  yamaguch 		filled = 1;
   3844  1.1  yamaguch 	} while (--n);
   3845  1.1  yamaguch 
   3846  1.1  yamaguch 	sc->sc_arq_prod = prod;
   3847  1.1  yamaguch 
   3848  1.1  yamaguch 	if (filled) {
   3849  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   3850  1.1  yamaguch 		    0, IXL_DMA_LEN(&sc->sc_arq),
   3851  1.1  yamaguch 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   3852  1.1  yamaguch 		iavf_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod);
   3853  1.1  yamaguch 	}
   3854  1.1  yamaguch 
   3855  1.1  yamaguch 	return filled;
   3856  1.1  yamaguch }
   3857  1.1  yamaguch 
   3858  1.1  yamaguch static int
   3859  1.1  yamaguch iavf_arq_wait(struct iavf_softc *sc, uint32_t opcode)
   3860  1.1  yamaguch {
   3861  1.1  yamaguch 	int error;
   3862  1.1  yamaguch 
   3863  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_adminq_lock));
   3864  1.1  yamaguch 
   3865  1.1  yamaguch 	while ((error = cv_timedwait(&sc->sc_adminq_cv,
   3866  1.1  yamaguch 	    &sc->sc_adminq_lock, mstohz(IAVF_EXEC_TIMEOUT))) == 0) {
   3867  1.1  yamaguch 		if (opcode == sc->sc_arq_opcode)
   3868  1.1  yamaguch 			break;
   3869  1.1  yamaguch 	}
   3870  1.1  yamaguch 
   3871  1.1  yamaguch 	if (error != 0 &&
   3872  1.1  yamaguch 	    atomic_load_relaxed(&sc->sc_debuglevel) >= 2)
   3873  1.1  yamaguch 		device_printf(sc->sc_dev, "cv_timedwait error=%d\n", error);
   3874  1.1  yamaguch 
   3875  1.1  yamaguch 	return error;
   3876  1.1  yamaguch }
   3877  1.1  yamaguch 
   3878  1.1  yamaguch static void
   3879  1.1  yamaguch iavf_arq_refill(void *xsc)
   3880  1.1  yamaguch {
   3881  1.1  yamaguch 	struct iavf_softc *sc = xsc;
   3882  1.1  yamaguch 	struct ixl_aq_bufs aqbs;
   3883  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3884  1.1  yamaguch 	unsigned int n, i;
   3885  1.1  yamaguch 
   3886  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   3887  1.1  yamaguch 	iavf_arq_fill(sc);
   3888  1.1  yamaguch 	n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons,
   3889  1.1  yamaguch 	    IAVF_AQ_NUM);
   3890  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   3891  1.1  yamaguch 
   3892  1.1  yamaguch 	if (n == 0)
   3893  1.1  yamaguch 		return;
   3894  1.1  yamaguch 
   3895  1.1  yamaguch 	if (atomic_load_relaxed(&sc->sc_debuglevel) >= 1)
   3896  1.1  yamaguch 		device_printf(sc->sc_dev, "Allocate %d bufs for arq\n", n);
   3897  1.1  yamaguch 
   3898  1.1  yamaguch 	SIMPLEQ_INIT(&aqbs);
   3899  1.1  yamaguch 	for (i = 0; i < n; i++) {
   3900  1.1  yamaguch 		aqb = iavf_aqb_get(sc, NULL);
   3901  1.1  yamaguch 		if (aqb == NULL)
   3902  1.1  yamaguch 			continue;
   3903  1.1  yamaguch 		SIMPLEQ_INSERT_TAIL(&aqbs, aqb, aqb_entry);
   3904  1.1  yamaguch 	}
   3905  1.1  yamaguch 
   3906  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   3907  1.1  yamaguch 	while ((aqb = SIMPLEQ_FIRST(&aqbs)) != NULL) {
   3908  1.1  yamaguch 		SIMPLEQ_REMOVE(&aqbs, aqb, ixl_aq_buf, aqb_entry);
   3909  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_arq_idle, aqb);
   3910  1.1  yamaguch 	}
   3911  1.1  yamaguch 	iavf_arq_fill(sc);
   3912  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   3913  1.1  yamaguch }
   3914  1.1  yamaguch 
   3915  1.1  yamaguch static uint32_t
   3916  1.1  yamaguch iavf_process_arq(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   3917  1.1  yamaguch     struct ixl_aq_buf *aqb)
   3918  1.1  yamaguch {
   3919  1.1  yamaguch 	uint32_t vc_retval, vc_opcode;
   3920  1.1  yamaguch 	int dbg;
   3921  1.1  yamaguch 
   3922  1.1  yamaguch 	dbg = atomic_load_relaxed(&sc->sc_debuglevel);
   3923  1.1  yamaguch 	if (dbg >= 3)
   3924  1.1  yamaguch 		iavf_aq_dump(sc, iaq, "arq proc");
   3925  1.1  yamaguch 
   3926  1.1  yamaguch 	if (dbg >= 2) {
   3927  1.1  yamaguch 		vc_retval = iavf_aq_vc_get_retval(iaq);
   3928  1.1  yamaguch 		if (vc_retval != IAVF_VC_RC_SUCCESS) {
   3929  1.1  yamaguch 			device_printf(sc->sc_dev, "%s failed=%d(arq)\n",
   3930  1.1  yamaguch 			    iavf_aq_vc_opcode_str(iaq), vc_retval);
   3931  1.1  yamaguch 		}
   3932  1.1  yamaguch 	}
   3933  1.1  yamaguch 
   3934  1.1  yamaguch 	vc_opcode = iavf_aq_vc_get_opcode(iaq);
   3935  1.1  yamaguch 	switch (vc_opcode) {
   3936  1.1  yamaguch 	case IAVF_VC_OP_VERSION:
   3937  1.1  yamaguch 		iavf_process_version(sc, iaq, aqb);
   3938  1.1  yamaguch 		break;
   3939  1.1  yamaguch 	case IAVF_VC_OP_GET_VF_RESOURCES:
   3940  1.1  yamaguch 		iavf_process_vf_resources(sc, iaq, aqb);
   3941  1.1  yamaguch 		break;
   3942  1.1  yamaguch 	case IAVF_VC_OP_CONFIG_IRQ_MAP:
   3943  1.1  yamaguch 		iavf_process_irq_map(sc, iaq);
   3944  1.1  yamaguch 		break;
   3945  1.1  yamaguch 	case IAVF_VC_OP_EVENT:
   3946  1.1  yamaguch 		iavf_process_vc_event(sc, iaq, aqb);
   3947  1.1  yamaguch 		break;
   3948  1.1  yamaguch 	case IAVF_VC_OP_GET_STATS:
   3949  1.1  yamaguch 		iavf_process_stats(sc, iaq, aqb);
   3950  1.1  yamaguch 		break;
   3951  1.1  yamaguch 	case IAVF_VC_OP_REQUEST_QUEUES:
   3952  1.1  yamaguch 		iavf_process_req_queues(sc, iaq, aqb);
   3953  1.1  yamaguch 		break;
   3954  1.1  yamaguch 	}
   3955  1.1  yamaguch 
   3956  1.1  yamaguch 	return vc_opcode;
   3957  1.1  yamaguch }
   3958  1.1  yamaguch 
   3959  1.1  yamaguch static int
   3960  1.1  yamaguch iavf_arq_poll(struct iavf_softc *sc, uint32_t wait_opcode, int retry)
   3961  1.1  yamaguch {
   3962  1.1  yamaguch 	struct ixl_aq_desc *arq, *iaq;
   3963  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3964  1.1  yamaguch 	unsigned int cons = sc->sc_arq_cons;
   3965  1.1  yamaguch 	unsigned int prod;
   3966  1.1  yamaguch 	uint32_t vc_opcode;
   3967  1.1  yamaguch 	bool received;
   3968  1.1  yamaguch 	int i;
   3969  1.1  yamaguch 
   3970  1.1  yamaguch 	for (i = 0, received = false; i < retry && !received; i++) {
   3971  1.1  yamaguch 		prod = iavf_rd(sc, sc->sc_aq_regs->arq_head);
   3972  1.1  yamaguch 		prod &= sc->sc_aq_regs->arq_head_mask;
   3973  1.1  yamaguch 
   3974  1.1  yamaguch 		if (prod == cons) {
   3975  1.1  yamaguch 			delaymsec(1);
   3976  1.1  yamaguch 			continue;
   3977  1.1  yamaguch 		}
   3978  1.1  yamaguch 
   3979  1.1  yamaguch 		if (prod >= IAVF_AQ_NUM) {
   3980  1.1  yamaguch 			return EIO;
   3981  1.1  yamaguch 		}
   3982  1.1  yamaguch 
   3983  1.1  yamaguch 		arq = IXL_DMA_KVA(&sc->sc_arq);
   3984  1.1  yamaguch 
   3985  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   3986  1.1  yamaguch 		    0, IXL_DMA_LEN(&sc->sc_arq),
   3987  1.1  yamaguch 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   3988  1.1  yamaguch 
   3989  1.1  yamaguch 		do {
   3990  1.1  yamaguch 			iaq = &arq[cons];
   3991  1.1  yamaguch 			aqb = iavf_aqb_get_locked(&sc->sc_arq_live);
   3992  1.1  yamaguch 			KASSERT(aqb != NULL);
   3993  1.1  yamaguch 
   3994  1.1  yamaguch 			bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0,
   3995  1.1  yamaguch 			    IAVF_AQ_BUFLEN, BUS_DMASYNC_POSTREAD);
   3996  1.1  yamaguch 
   3997  1.1  yamaguch 			vc_opcode = iavf_process_arq(sc, iaq, aqb);
   3998  1.1  yamaguch 
   3999  1.1  yamaguch 			if (vc_opcode == wait_opcode)
   4000  1.1  yamaguch 				received = true;
   4001  1.1  yamaguch 
   4002  1.1  yamaguch 			memset(iaq, 0, sizeof(*iaq));
   4003  1.1  yamaguch 			iavf_aqb_put_locked(&sc->sc_arq_idle, aqb);
   4004  1.1  yamaguch 
   4005  1.1  yamaguch 			cons++;
   4006  1.1  yamaguch 			cons &= IAVF_AQ_MASK;
   4007  1.1  yamaguch 
   4008  1.1  yamaguch 		} while (cons != prod);
   4009  1.1  yamaguch 
   4010  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   4011  1.1  yamaguch 		    0, IXL_DMA_LEN(&sc->sc_arq),
   4012  1.1  yamaguch 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   4013  1.1  yamaguch 
   4014  1.1  yamaguch 		sc->sc_arq_cons = cons;
   4015  1.1  yamaguch 		iavf_arq_fill(sc);
   4016  1.1  yamaguch 
   4017  1.1  yamaguch 	}
   4018  1.1  yamaguch 
   4019  1.1  yamaguch 	if (!received)
   4020  1.1  yamaguch 		return ETIMEDOUT;
   4021  1.1  yamaguch 
   4022  1.1  yamaguch 	return 0;
   4023  1.1  yamaguch }
   4024  1.1  yamaguch 
   4025  1.1  yamaguch static int
   4026  1.1  yamaguch iavf_arq(struct iavf_softc *sc)
   4027  1.1  yamaguch {
   4028  1.1  yamaguch 	struct ixl_aq_desc *arq, *iaq;
   4029  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4030  1.1  yamaguch 	unsigned int cons = sc->sc_arq_cons;
   4031  1.1  yamaguch 	unsigned int prod;
   4032  1.1  yamaguch 	uint32_t vc_opcode;
   4033  1.1  yamaguch 
   4034  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_adminq_lock));
   4035  1.1  yamaguch 
   4036  1.1  yamaguch 	prod = iavf_rd(sc, sc->sc_aq_regs->arq_head);
   4037  1.1  yamaguch 	prod &= sc->sc_aq_regs->arq_head_mask;
   4038  1.1  yamaguch 
   4039  1.1  yamaguch 	/* broken value at resetting */
   4040  1.1  yamaguch 	if (prod >= IAVF_AQ_NUM) {
   4041  1.1  yamaguch 		iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc);
   4042  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_reset_task);
   4043  1.1  yamaguch 		return 0;
   4044  1.1  yamaguch 	}
   4045  1.1  yamaguch 
   4046  1.1  yamaguch 	if (cons == prod)
   4047  1.1  yamaguch 		return 0;
   4048  1.1  yamaguch 
   4049  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   4050  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   4051  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   4052  1.1  yamaguch 
   4053  1.1  yamaguch 	arq = IXL_DMA_KVA(&sc->sc_arq);
   4054  1.1  yamaguch 
   4055  1.1  yamaguch 	do {
   4056  1.1  yamaguch 		iaq = &arq[cons];
   4057  1.1  yamaguch 		aqb = iavf_aqb_get_locked(&sc->sc_arq_live);
   4058  1.1  yamaguch 
   4059  1.1  yamaguch 		KASSERT(aqb != NULL);
   4060  1.1  yamaguch 
   4061  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, IAVF_AQ_BUFLEN,
   4062  1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   4063  1.1  yamaguch 
   4064  1.1  yamaguch 		vc_opcode = iavf_process_arq(sc, iaq, aqb);
   4065  1.1  yamaguch 
   4066  1.1  yamaguch 		switch (vc_opcode) {
   4067  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_TX_QUEUE:
   4068  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_RX_QUEUE:
   4069  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_VSI_QUEUES:
   4070  1.1  yamaguch 		case IAVF_VC_OP_ENABLE_QUEUES:
   4071  1.1  yamaguch 		case IAVF_VC_OP_DISABLE_QUEUES:
   4072  1.1  yamaguch 		case IAVF_VC_OP_GET_RSS_HENA_CAPS:
   4073  1.1  yamaguch 		case IAVF_VC_OP_SET_RSS_HENA:
   4074  1.1  yamaguch 		case IAVF_VC_OP_ADD_ETH_ADDR:
   4075  1.1  yamaguch 		case IAVF_VC_OP_DEL_ETH_ADDR:
   4076  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_PROMISC:
   4077  1.1  yamaguch 		case IAVF_VC_OP_ADD_VLAN:
   4078  1.1  yamaguch 		case IAVF_VC_OP_DEL_VLAN:
   4079  1.1  yamaguch 		case IAVF_VC_OP_ENABLE_VLAN_STRIP:
   4080  1.1  yamaguch 		case IAVF_VC_OP_DISABLE_VLAN_STRIP:
   4081  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_RSS_KEY:
   4082  1.1  yamaguch 		case IAVF_VC_OP_CONFIG_RSS_LUT:
   4083  1.1  yamaguch 			sc->sc_arq_retval = iavf_aq_vc_get_retval(iaq);
   4084  1.1  yamaguch 			sc->sc_arq_opcode = vc_opcode;
   4085  1.1  yamaguch 			cv_signal(&sc->sc_adminq_cv);
   4086  1.1  yamaguch 			break;
   4087  1.1  yamaguch 		}
   4088  1.1  yamaguch 
   4089  1.1  yamaguch 		memset(iaq, 0, sizeof(*iaq));
   4090  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_arq_idle, aqb);
   4091  1.1  yamaguch 
   4092  1.1  yamaguch 		cons++;
   4093  1.1  yamaguch 		cons &= IAVF_AQ_MASK;
   4094  1.1  yamaguch 	} while (cons != prod);
   4095  1.1  yamaguch 
   4096  1.1  yamaguch 	sc->sc_arq_cons = cons;
   4097  1.1  yamaguch 	iavf_work_add(sc->sc_workq, &sc->sc_arq_refill);
   4098  1.1  yamaguch 
   4099  1.1  yamaguch 	return 1;
   4100  1.1  yamaguch }
   4101  1.1  yamaguch 
   4102  1.1  yamaguch static int
   4103  1.1  yamaguch iavf_atq_post(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4104  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4105  1.1  yamaguch {
   4106  1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   4107  1.1  yamaguch 	unsigned int prod;
   4108  1.1  yamaguch 
   4109  1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   4110  1.1  yamaguch 	prod = sc->sc_atq_prod;
   4111  1.1  yamaguch 	slot = &atq[prod];
   4112  1.1  yamaguch 
   4113  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4114  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE);
   4115  1.1  yamaguch 
   4116  1.1  yamaguch 	*slot = *iaq;
   4117  1.1  yamaguch 	slot->iaq_flags |= htole16(IXL_AQ_SI);
   4118  1.1  yamaguch 	if (aqb != NULL) {
   4119  1.1  yamaguch 		ixl_aq_dva(slot, IXL_AQB_DVA(aqb));
   4120  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb),
   4121  1.1  yamaguch 		    0, IXL_AQB_LEN(aqb), BUS_DMASYNC_PREWRITE);
   4122  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_live, aqb);
   4123  1.1  yamaguch 	} else {
   4124  1.1  yamaguch 		ixl_aq_dva(slot, (bus_addr_t)0);
   4125  1.1  yamaguch 	}
   4126  1.1  yamaguch 
   4127  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4128  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE);
   4129  1.1  yamaguch 
   4130  1.1  yamaguch 	if (atomic_load_relaxed(&sc->sc_debuglevel) >= 3)
   4131  1.1  yamaguch 		iavf_aq_dump(sc, slot, "post");
   4132  1.1  yamaguch 
   4133  1.1  yamaguch 	prod++;
   4134  1.1  yamaguch 	prod &= IAVF_AQ_MASK;
   4135  1.1  yamaguch 	sc->sc_atq_prod = prod;
   4136  1.1  yamaguch 	iavf_wr(sc, sc->sc_aq_regs->atq_tail, prod);
   4137  1.1  yamaguch 	return prod;
   4138  1.1  yamaguch }
   4139  1.1  yamaguch 
   4140  1.1  yamaguch static int
   4141  1.1  yamaguch iavf_atq_poll(struct iavf_softc *sc, unsigned int tm)
   4142  1.1  yamaguch {
   4143  1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   4144  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4145  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4146  1.1  yamaguch 	unsigned int prod;
   4147  1.1  yamaguch 	unsigned int t;
   4148  1.1  yamaguch 	int dbg;
   4149  1.1  yamaguch 
   4150  1.1  yamaguch 	dbg = atomic_load_relaxed(&sc->sc_debuglevel);
   4151  1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   4152  1.1  yamaguch 	prod = sc->sc_atq_prod;
   4153  1.1  yamaguch 	slot = &atq[prod];
   4154  1.1  yamaguch 	t = 0;
   4155  1.1  yamaguch 
   4156  1.1  yamaguch 	while (iavf_rd(sc, sc->sc_aq_regs->atq_head) != prod) {
   4157  1.1  yamaguch 		delaymsec(1);
   4158  1.1  yamaguch 
   4159  1.1  yamaguch 		if (t++ > tm) {
   4160  1.1  yamaguch 			if (dbg >= 2) {
   4161  1.1  yamaguch 				device_printf(sc->sc_dev,
   4162  1.1  yamaguch 				    "atq timedout\n");
   4163  1.1  yamaguch 			}
   4164  1.1  yamaguch 			return ETIMEDOUT;
   4165  1.1  yamaguch 		}
   4166  1.1  yamaguch 	}
   4167  1.1  yamaguch 
   4168  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4169  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTREAD);
   4170  1.1  yamaguch 	iaq = *slot;
   4171  1.1  yamaguch 	memset(slot, 0, sizeof(*slot));
   4172  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4173  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREREAD);
   4174  1.1  yamaguch 
   4175  1.1  yamaguch 	aqb = iavf_aqb_get_locked(&sc->sc_atq_live);
   4176  1.1  yamaguch 	if (aqb != NULL) {
   4177  1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb),
   4178  1.1  yamaguch 		    0, IXL_AQB_LEN(aqb), BUS_DMASYNC_POSTWRITE);
   4179  1.1  yamaguch 		/* no need to do iavf_aqb_put(&sc->sc_atq_idle, aqb) */
   4180  1.1  yamaguch 	}
   4181  1.1  yamaguch 
   4182  1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4183  1.1  yamaguch 		if (dbg >= 2) {
   4184  1.1  yamaguch 			device_printf(sc->sc_dev,
   4185  1.1  yamaguch 			    "atq retcode=0x%04x\n", le16toh(iaq.iaq_retval));
   4186  1.1  yamaguch 		}
   4187  1.1  yamaguch 		return EIO;
   4188  1.1  yamaguch 	}
   4189  1.1  yamaguch 
   4190  1.1  yamaguch 	return 0;
   4191  1.1  yamaguch }
   4192  1.1  yamaguch 
   4193  1.1  yamaguch static void
   4194  1.1  yamaguch iavf_atq_done(struct iavf_softc *sc)
   4195  1.1  yamaguch {
   4196  1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   4197  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4198  1.1  yamaguch 	unsigned int cons;
   4199  1.1  yamaguch 	unsigned int prod;
   4200  1.1  yamaguch 
   4201  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_adminq_lock));
   4202  1.1  yamaguch 
   4203  1.1  yamaguch 	prod = sc->sc_atq_prod;
   4204  1.1  yamaguch 	cons = sc->sc_atq_cons;
   4205  1.1  yamaguch 
   4206  1.1  yamaguch 	if (prod == cons)
   4207  1.1  yamaguch 		return;
   4208  1.1  yamaguch 
   4209  1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   4210  1.1  yamaguch 
   4211  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4212  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   4213  1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   4214  1.1  yamaguch 
   4215  1.1  yamaguch 	do {
   4216  1.1  yamaguch 		slot = &atq[cons];
   4217  1.1  yamaguch 		if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD)))
   4218  1.1  yamaguch 			break;
   4219  1.1  yamaguch 
   4220  1.1  yamaguch 		if (ixl_aq_has_dva(slot) &&
   4221  1.1  yamaguch 		    (aqb = iavf_aqb_get_locked(&sc->sc_atq_live)) != NULL) {
   4222  1.1  yamaguch 			bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb),
   4223  1.1  yamaguch 			    0, IXL_AQB_LEN(aqb), BUS_DMASYNC_POSTWRITE);
   4224  1.1  yamaguch 			iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   4225  1.1  yamaguch 		}
   4226  1.1  yamaguch 
   4227  1.1  yamaguch 		memset(slot, 0, sizeof(*slot));
   4228  1.1  yamaguch 
   4229  1.1  yamaguch 		cons++;
   4230  1.1  yamaguch 		cons &= IAVF_AQ_MASK;
   4231  1.1  yamaguch 	} while (cons != prod);
   4232  1.1  yamaguch 
   4233  1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   4234  1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   4235  1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   4236  1.1  yamaguch 
   4237  1.1  yamaguch 	sc->sc_atq_cons = cons;
   4238  1.1  yamaguch }
   4239  1.1  yamaguch 
   4240  1.1  yamaguch static int
   4241  1.1  yamaguch iavf_adminq_poll(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4242  1.1  yamaguch     struct ixl_aq_buf *aqb, int retry)
   4243  1.1  yamaguch {
   4244  1.1  yamaguch 	int error;
   4245  1.1  yamaguch 
   4246  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4247  1.1  yamaguch 	error = iavf_adminq_poll_locked(sc, iaq, aqb, retry);
   4248  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4249  1.1  yamaguch 
   4250  1.1  yamaguch 	return error;
   4251  1.1  yamaguch }
   4252  1.1  yamaguch 
   4253  1.1  yamaguch static int
   4254  1.1  yamaguch iavf_adminq_poll_locked(struct iavf_softc *sc,
   4255  1.1  yamaguch     struct ixl_aq_desc *iaq, struct ixl_aq_buf *aqb, int retry)
   4256  1.1  yamaguch {
   4257  1.1  yamaguch 	uint32_t opcode;
   4258  1.1  yamaguch 	int error;
   4259  1.1  yamaguch 
   4260  1.1  yamaguch 	KASSERT(!sc->sc_attached || mutex_owned(&sc->sc_adminq_lock));
   4261  1.1  yamaguch 
   4262  1.1  yamaguch 	opcode = iavf_aq_vc_get_opcode(iaq);
   4263  1.1  yamaguch 
   4264  1.1  yamaguch 	iavf_atq_post(sc, iaq, aqb);
   4265  1.1  yamaguch 
   4266  1.1  yamaguch 	error = iavf_atq_poll(sc, retry);
   4267  1.1  yamaguch 	if (error)
   4268  1.1  yamaguch 		return error;
   4269  1.1  yamaguch 
   4270  1.1  yamaguch 	error = iavf_arq_poll(sc, opcode, retry);
   4271  1.1  yamaguch 
   4272  1.1  yamaguch 	if (error != 0 &&
   4273  1.1  yamaguch 	    atomic_load_relaxed(&sc->sc_debuglevel) >= 1) {
   4274  1.1  yamaguch 		device_printf(sc->sc_dev, "%s failed=%d(polling)\n",
   4275  1.1  yamaguch 		    iavf_aq_vc_opcode_str(iaq), error);
   4276  1.1  yamaguch 	}
   4277  1.1  yamaguch 
   4278  1.1  yamaguch 	return error;
   4279  1.1  yamaguch }
   4280  1.1  yamaguch 
   4281  1.1  yamaguch static int
   4282  1.1  yamaguch iavf_adminq_exec(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4283  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4284  1.1  yamaguch {
   4285  1.1  yamaguch 	int error;
   4286  1.1  yamaguch 	uint32_t opcode;
   4287  1.1  yamaguch 
   4288  1.1  yamaguch 	opcode = iavf_aq_vc_get_opcode(iaq);
   4289  1.1  yamaguch 
   4290  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4291  1.1  yamaguch 	iavf_atq_post(sc, iaq, aqb);
   4292  1.1  yamaguch 
   4293  1.1  yamaguch 	error = iavf_arq_wait(sc, opcode);
   4294  1.1  yamaguch 	if (error == 0) {
   4295  1.1  yamaguch 		error = sc->sc_arq_retval;
   4296  1.1  yamaguch 		if (error != IAVF_VC_RC_SUCCESS &&
   4297  1.1  yamaguch 		    atomic_load_relaxed(&sc->sc_debuglevel) >= 1) {
   4298  1.1  yamaguch 			device_printf(sc->sc_dev, "%s failed=%d\n",
   4299  1.1  yamaguch 			    iavf_aq_vc_opcode_str(iaq), error);
   4300  1.1  yamaguch 		}
   4301  1.1  yamaguch 	}
   4302  1.1  yamaguch 
   4303  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4304  1.1  yamaguch 	return error;
   4305  1.1  yamaguch }
   4306  1.1  yamaguch 
   4307  1.1  yamaguch static void
   4308  1.1  yamaguch iavf_process_version(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4309  1.1  yamaguch    struct ixl_aq_buf *aqb)
   4310  1.1  yamaguch {
   4311  1.1  yamaguch 	struct iavf_vc_version_info *ver;
   4312  1.1  yamaguch 
   4313  1.1  yamaguch 	ver = (struct iavf_vc_version_info *)aqb->aqb_data;
   4314  1.1  yamaguch 	sc->sc_major_ver = le32toh(ver->major);
   4315  1.1  yamaguch 	sc->sc_minor_ver = le32toh(ver->minor);
   4316  1.1  yamaguch }
   4317  1.1  yamaguch 
   4318  1.1  yamaguch static void
   4319  1.1  yamaguch iavf_process_vf_resources(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4320  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4321  1.1  yamaguch {
   4322  1.1  yamaguch 	struct iavf_vc_vf_resource *vf_res;
   4323  1.1  yamaguch 	struct iavf_vc_vsi_resource *vsi_res;
   4324  1.1  yamaguch 	uint8_t *enaddr;
   4325  1.1  yamaguch 	int mtu, dbg;
   4326  1.1  yamaguch 	char buf[512];
   4327  1.1  yamaguch 
   4328  1.1  yamaguch 	dbg = atomic_load_relaxed(&sc->sc_debuglevel);
   4329  1.1  yamaguch 	sc->sc_got_vf_resources = 1;
   4330  1.1  yamaguch 
   4331  1.1  yamaguch 	vf_res = aqb->aqb_data;
   4332  1.1  yamaguch 	sc->sc_max_vectors = le16toh(vf_res->max_vectors);
   4333  1.1  yamaguch 	if (le16toh(vf_res->num_vsis) == 0) {
   4334  1.1  yamaguch 		if (dbg >= 1) {
   4335  1.1  yamaguch 			device_printf(sc->sc_dev, "no vsi available\n");
   4336  1.1  yamaguch 		}
   4337  1.1  yamaguch 		return;
   4338  1.1  yamaguch 	}
   4339  1.1  yamaguch 	sc->sc_vf_cap = le32toh(vf_res->offload_flags);
   4340  1.1  yamaguch 	if (dbg >= 2) {
   4341  1.1  yamaguch 		snprintb(buf, sizeof(buf),
   4342  1.1  yamaguch 		    IAVF_VC_OFFLOAD_FMT, sc->sc_vf_cap);
   4343  1.1  yamaguch 		device_printf(sc->sc_dev, "VF cap=%s\n", buf);
   4344  1.1  yamaguch 	}
   4345  1.1  yamaguch 
   4346  1.1  yamaguch 	mtu = le16toh(vf_res->max_mtu);
   4347  1.1  yamaguch 	if (IAVF_MIN_MTU < mtu && mtu < IAVF_MAX_MTU) {
   4348  1.1  yamaguch 		sc->sc_max_mtu = MIN(IAVF_MAX_MTU, mtu);
   4349  1.1  yamaguch 	}
   4350  1.1  yamaguch 
   4351  1.1  yamaguch 	vsi_res = &vf_res->vsi_res[0];
   4352  1.1  yamaguch 	sc->sc_vsi_id = le16toh(vsi_res->vsi_id);
   4353  1.1  yamaguch 	sc->sc_vf_id = le32toh(iaq->iaq_param[0]);
   4354  1.1  yamaguch 	sc->sc_qset_handle = le16toh(vsi_res->qset_handle);
   4355  1.1  yamaguch 	sc->sc_nqps_vsi = le16toh(vsi_res->num_queue_pairs);
   4356  1.1  yamaguch 	if (!iavf_is_etheranyaddr(vsi_res->default_mac)) {
   4357  1.1  yamaguch 		enaddr = vsi_res->default_mac;
   4358  1.1  yamaguch 	} else {
   4359  1.1  yamaguch 		enaddr = sc->sc_enaddr_fake;
   4360  1.1  yamaguch 	}
   4361  1.1  yamaguch 	memcpy(sc->sc_enaddr, enaddr, ETHER_ADDR_LEN);
   4362  1.1  yamaguch }
   4363  1.1  yamaguch 
   4364  1.1  yamaguch static void
   4365  1.1  yamaguch iavf_process_irq_map(struct iavf_softc *sc, struct ixl_aq_desc *iaq)
   4366  1.1  yamaguch {
   4367  1.1  yamaguch 	uint32_t retval;
   4368  1.1  yamaguch 
   4369  1.1  yamaguch 	retval = iavf_aq_vc_get_retval(iaq);
   4370  1.1  yamaguch 	if (retval != IAVF_VC_RC_SUCCESS) {
   4371  1.1  yamaguch 		return;
   4372  1.1  yamaguch 	}
   4373  1.1  yamaguch 
   4374  1.1  yamaguch 	sc->sc_got_irq_map = 1;
   4375  1.1  yamaguch }
   4376  1.1  yamaguch 
   4377  1.1  yamaguch static void
   4378  1.1  yamaguch iavf_process_vc_event(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4379  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4380  1.1  yamaguch {
   4381  1.1  yamaguch 	struct iavf_vc_pf_event *event;
   4382  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   4383  1.1  yamaguch 	const struct iavf_link_speed *speed;
   4384  1.1  yamaguch 	int link;
   4385  1.1  yamaguch 
   4386  1.1  yamaguch 	event = aqb->aqb_data;
   4387  1.1  yamaguch 	switch (event->event) {
   4388  1.1  yamaguch 	case IAVF_VC_EVENT_LINK_CHANGE:
   4389  1.1  yamaguch 		sc->sc_media_status = IFM_AVALID;
   4390  1.1  yamaguch 		sc->sc_media_active = IFM_ETHER;
   4391  1.1  yamaguch 		link = LINK_STATE_DOWN;
   4392  1.1  yamaguch 		if (event->link_status) {
   4393  1.1  yamaguch 			link = LINK_STATE_UP;
   4394  1.1  yamaguch 			sc->sc_media_status |= IFM_ACTIVE;
   4395  1.1  yamaguch 
   4396  1.1  yamaguch 			ifp->if_baudrate = 0;
   4397  1.1  yamaguch 			speed = iavf_find_link_speed(sc, event->link_speed);
   4398  1.1  yamaguch 			if (speed != NULL) {
   4399  1.1  yamaguch 				sc->sc_media_active |= speed->media;
   4400  1.1  yamaguch 				ifp->if_baudrate = speed->baudrate;
   4401  1.1  yamaguch 			}
   4402  1.1  yamaguch 		}
   4403  1.1  yamaguch 
   4404  1.1  yamaguch 		if (sc->sc_link_state != link) {
   4405  1.1  yamaguch 			sc->sc_link_state = link;
   4406  1.1  yamaguch 			if (sc->sc_attached) {
   4407  1.1  yamaguch 				if_link_state_change(ifp, link);
   4408  1.1  yamaguch 			}
   4409  1.1  yamaguch 		}
   4410  1.1  yamaguch 		break;
   4411  1.1  yamaguch 	case IAVF_VC_EVENT_RESET_IMPENDING:
   4412  1.1  yamaguch 		log(LOG_INFO, "%s: Reset warning received from the PF\n",
   4413  1.1  yamaguch 		    ifp->if_xname);
   4414  1.1  yamaguch 		iavf_work_set(&sc->sc_reset_task, iavf_reset_request, sc);
   4415  1.1  yamaguch 		iavf_work_add(sc->sc_workq, &sc->sc_reset_task);
   4416  1.1  yamaguch 		break;
   4417  1.1  yamaguch 	}
   4418  1.1  yamaguch }
   4419  1.1  yamaguch 
   4420  1.1  yamaguch static void
   4421  1.1  yamaguch iavf_process_stats(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4422  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4423  1.1  yamaguch {
   4424  1.1  yamaguch 	struct iavf_stat_counters *isc;
   4425  1.1  yamaguch 	struct i40e_eth_stats *st;
   4426  1.1  yamaguch 
   4427  1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_adminq_lock));
   4428  1.1  yamaguch 
   4429  1.1  yamaguch 	st = aqb->aqb_data;
   4430  1.1  yamaguch 	isc = &sc->sc_stat_counters;
   4431  1.1  yamaguch 
   4432  1.1  yamaguch 	isc->isc_rx_bytes.ev_count = st->rx_bytes;
   4433  1.1  yamaguch 	isc->isc_rx_unicast.ev_count = st->rx_unicast;
   4434  1.1  yamaguch 	isc->isc_rx_multicast.ev_count = st->rx_multicast;
   4435  1.1  yamaguch 	isc->isc_rx_broadcast.ev_count = st->rx_broadcast;
   4436  1.1  yamaguch 	isc->isc_rx_discards.ev_count = st->rx_discards;
   4437  1.1  yamaguch 	isc->isc_rx_unknown_protocol.ev_count = st->rx_unknown_protocol;
   4438  1.1  yamaguch 
   4439  1.1  yamaguch 	isc->isc_tx_bytes.ev_count = st->tx_bytes;
   4440  1.1  yamaguch 	isc->isc_tx_unicast.ev_count = st->tx_unicast;
   4441  1.1  yamaguch 	isc->isc_tx_multicast.ev_count = st->tx_multicast;
   4442  1.1  yamaguch 	isc->isc_tx_broadcast.ev_count = st->tx_broadcast;
   4443  1.1  yamaguch 	isc->isc_tx_discards.ev_count = st->tx_discards;
   4444  1.1  yamaguch 	isc->isc_tx_errors.ev_count = st->tx_errors;
   4445  1.1  yamaguch }
   4446  1.1  yamaguch 
   4447  1.1  yamaguch static void
   4448  1.1  yamaguch iavf_process_req_queues(struct iavf_softc *sc, struct ixl_aq_desc *iaq,
   4449  1.1  yamaguch     struct ixl_aq_buf *aqb)
   4450  1.1  yamaguch {
   4451  1.1  yamaguch 	struct iavf_vc_res_request *req;
   4452  1.1  yamaguch 	struct ifnet *ifp;
   4453  1.1  yamaguch 	uint32_t vc_retval;
   4454  1.1  yamaguch 
   4455  1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
   4456  1.1  yamaguch 	req = aqb->aqb_data;
   4457  1.1  yamaguch 
   4458  1.1  yamaguch 	vc_retval = iavf_aq_vc_get_retval(iaq);
   4459  1.1  yamaguch 	if (vc_retval != IAVF_VC_RC_SUCCESS) {
   4460  1.1  yamaguch 		return;
   4461  1.1  yamaguch 	}
   4462  1.1  yamaguch 
   4463  1.1  yamaguch 	if (sc->sc_nqps_req < req->num_queue_pairs) {
   4464  1.1  yamaguch 		log(LOG_INFO,
   4465  1.1  yamaguch 		    "%s: requested %d queues, but only %d left.\n",
   4466  1.1  yamaguch 		    ifp->if_xname,
   4467  1.1  yamaguch 		    sc->sc_nqps_req, req->num_queue_pairs);
   4468  1.1  yamaguch 	}
   4469  1.1  yamaguch 
   4470  1.1  yamaguch 	if (sc->sc_nqps_vsi < req->num_queue_pairs) {
   4471  1.1  yamaguch 		if (!sc->sc_req_queues_retried) {
   4472  1.1  yamaguch 			/* req->num_queue_pairs indicates max qps */
   4473  1.1  yamaguch 			sc->sc_nqps_req = req->num_queue_pairs;
   4474  1.1  yamaguch 
   4475  1.1  yamaguch 			sc->sc_req_queues_retried = true;
   4476  1.1  yamaguch 			iavf_work_add(sc->sc_workq, &sc->sc_req_queues_task);
   4477  1.1  yamaguch 		}
   4478  1.1  yamaguch 	}
   4479  1.1  yamaguch }
   4480  1.1  yamaguch 
   4481  1.1  yamaguch static int
   4482  1.1  yamaguch iavf_get_version(struct iavf_softc *sc, struct ixl_aq_buf *aqb)
   4483  1.1  yamaguch {
   4484  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4485  1.1  yamaguch 	struct iavf_vc_version_info *ver;
   4486  1.1  yamaguch 	int error;
   4487  1.1  yamaguch 
   4488  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4489  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4490  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4491  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_VERSION);
   4492  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(struct iavf_vc_version_info));
   4493  1.1  yamaguch 
   4494  1.1  yamaguch 	ver = IXL_AQB_KVA(aqb);
   4495  1.1  yamaguch 	ver->major = htole32(IAVF_VF_MAJOR);
   4496  1.1  yamaguch 	ver->minor = htole32(IAVF_VF_MINOR);
   4497  1.1  yamaguch 
   4498  1.1  yamaguch 	sc->sc_major_ver = UINT_MAX;
   4499  1.1  yamaguch 	sc->sc_minor_ver = UINT_MAX;
   4500  1.1  yamaguch 
   4501  1.1  yamaguch 	if (sc->sc_attached) {
   4502  1.1  yamaguch 		error = iavf_adminq_poll(sc, &iaq, aqb, 250);
   4503  1.1  yamaguch 	} else {
   4504  1.1  yamaguch 		error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250);
   4505  1.1  yamaguch 	}
   4506  1.1  yamaguch 
   4507  1.1  yamaguch 	if (error)
   4508  1.1  yamaguch 		return -1;
   4509  1.1  yamaguch 
   4510  1.1  yamaguch 	return 0;
   4511  1.1  yamaguch }
   4512  1.1  yamaguch 
   4513  1.1  yamaguch static int
   4514  1.1  yamaguch iavf_get_vf_resources(struct iavf_softc *sc, struct ixl_aq_buf *aqb)
   4515  1.1  yamaguch {
   4516  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4517  1.1  yamaguch 	uint32_t *cap, cap0;
   4518  1.1  yamaguch 	int error;
   4519  1.1  yamaguch 
   4520  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4521  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4522  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4523  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_GET_VF_RESOURCES);
   4524  1.1  yamaguch 
   4525  1.1  yamaguch 	if (sc->sc_major_ver > 0) {
   4526  1.1  yamaguch 		cap0 = IAVF_VC_OFFLOAD_L2 |
   4527  1.1  yamaguch 		    IAVF_VC_OFFLOAD_VLAN |
   4528  1.1  yamaguch 		    IAVF_VC_OFFLOAD_RSS_PF |
   4529  1.1  yamaguch 		    IAVF_VC_OFFLOAD_REQ_QUEUES;
   4530  1.1  yamaguch 
   4531  1.1  yamaguch 		cap = IXL_AQB_KVA(aqb);
   4532  1.1  yamaguch 		*cap = htole32(cap0);
   4533  1.1  yamaguch 		iaq.iaq_datalen = htole16(sizeof(*cap));
   4534  1.1  yamaguch 	}
   4535  1.1  yamaguch 
   4536  1.1  yamaguch 	sc->sc_got_vf_resources = 0;
   4537  1.1  yamaguch 	if (sc->sc_attached) {
   4538  1.1  yamaguch 		error = iavf_adminq_poll(sc, &iaq, aqb, 250);
   4539  1.1  yamaguch 	} else {
   4540  1.1  yamaguch 		error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250);
   4541  1.1  yamaguch 	}
   4542  1.1  yamaguch 
   4543  1.1  yamaguch 	if (error)
   4544  1.1  yamaguch 		return -1;
   4545  1.1  yamaguch 	return 0;
   4546  1.1  yamaguch }
   4547  1.1  yamaguch 
   4548  1.1  yamaguch static int
   4549  1.1  yamaguch iavf_get_stats(struct iavf_softc *sc)
   4550  1.1  yamaguch {
   4551  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4552  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4553  1.1  yamaguch 	struct iavf_vc_queue_select *qsel;
   4554  1.1  yamaguch 	int error;
   4555  1.1  yamaguch 
   4556  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4557  1.1  yamaguch 	aqb = iavf_aqb_get_locked(&sc->sc_atq_idle);
   4558  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4559  1.1  yamaguch 
   4560  1.1  yamaguch 	if (aqb == NULL)
   4561  1.1  yamaguch 		return ENOMEM;
   4562  1.1  yamaguch 
   4563  1.1  yamaguch 	qsel = IXL_AQB_KVA(aqb);
   4564  1.1  yamaguch 	memset(qsel, 0, sizeof(*qsel));
   4565  1.1  yamaguch 	qsel->vsi_id = htole16(sc->sc_vsi_id);
   4566  1.1  yamaguch 
   4567  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4568  1.1  yamaguch 
   4569  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4570  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4571  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_GET_STATS);
   4572  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*qsel));
   4573  1.1  yamaguch 
   4574  1.1  yamaguch 	if (atomic_load_relaxed(&sc->sc_debuglevel) >= 3) {
   4575  1.1  yamaguch 		device_printf(sc->sc_dev, "post GET_STATS command\n");
   4576  1.1  yamaguch 	}
   4577  1.1  yamaguch 
   4578  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4579  1.1  yamaguch 	error = iavf_atq_post(sc, &iaq, aqb);
   4580  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4581  1.1  yamaguch 
   4582  1.1  yamaguch 	return error;
   4583  1.1  yamaguch }
   4584  1.1  yamaguch 
   4585  1.1  yamaguch static int
   4586  1.1  yamaguch iavf_config_irq_map(struct iavf_softc *sc, struct ixl_aq_buf *aqb)
   4587  1.1  yamaguch {
   4588  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4589  1.1  yamaguch 	struct iavf_vc_vector_map *vec;
   4590  1.1  yamaguch 	struct iavf_vc_irq_map_info *map;
   4591  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   4592  1.1  yamaguch 	struct iavf_tx_ring *txr;
   4593  1.1  yamaguch 	unsigned int num_vec;
   4594  1.1  yamaguch 	int error;
   4595  1.1  yamaguch 
   4596  1.1  yamaguch 	map = IXL_AQB_KVA(aqb);
   4597  1.1  yamaguch 	vec = map->vecmap;
   4598  1.1  yamaguch 	num_vec = 0;
   4599  1.1  yamaguch 
   4600  1.1  yamaguch 	if (sc->sc_nintrs == 1) {
   4601  1.1  yamaguch 		vec[0].vsi_id = htole16(sc->sc_vsi_id);
   4602  1.1  yamaguch 		vec[0].vector_id = htole16(0);
   4603  1.1  yamaguch 		vec[0].rxq_map = htole16(iavf_allqueues(sc));
   4604  1.1  yamaguch 		vec[0].txq_map = htole16(iavf_allqueues(sc));
   4605  1.1  yamaguch 		vec[0].rxitr_idx = htole16(IAVF_NOITR);
   4606  1.1  yamaguch 		vec[0].rxitr_idx = htole16(IAVF_NOITR);
   4607  1.1  yamaguch 		num_vec = 1;
   4608  1.1  yamaguch 	} else if (sc->sc_nintrs > 1) {
   4609  1.1  yamaguch 		KASSERT(sc->sc_nqps_alloc >= (sc->sc_nintrs - 1));
   4610  1.1  yamaguch 		for (; num_vec < (sc->sc_nintrs - 1); num_vec++) {
   4611  1.1  yamaguch 			rxr = sc->sc_qps[num_vec].qp_rxr;
   4612  1.1  yamaguch 			txr = sc->sc_qps[num_vec].qp_txr;
   4613  1.1  yamaguch 
   4614  1.1  yamaguch 			vec[num_vec].vsi_id = htole16(sc->sc_vsi_id);
   4615  1.1  yamaguch 			vec[num_vec].vector_id = htole16(num_vec + 1);
   4616  1.1  yamaguch 			vec[num_vec].rxq_map = htole16(__BIT(rxr->rxr_qid));
   4617  1.1  yamaguch 			vec[num_vec].txq_map = htole16(__BIT(txr->txr_qid));
   4618  1.1  yamaguch 			vec[num_vec].rxitr_idx = htole16(IAVF_ITR_RX);
   4619  1.1  yamaguch 			vec[num_vec].txitr_idx = htole16(IAVF_ITR_TX);
   4620  1.1  yamaguch 		}
   4621  1.1  yamaguch 
   4622  1.1  yamaguch 		vec[num_vec].vsi_id = htole16(sc->sc_vsi_id);
   4623  1.1  yamaguch 		vec[num_vec].vector_id = htole16(0);
   4624  1.1  yamaguch 		vec[num_vec].rxq_map = htole16(0);
   4625  1.1  yamaguch 		vec[num_vec].txq_map = htole16(0);
   4626  1.1  yamaguch 		num_vec++;
   4627  1.1  yamaguch 	}
   4628  1.1  yamaguch 
   4629  1.1  yamaguch 	map->num_vectors = htole16(num_vec);
   4630  1.1  yamaguch 
   4631  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4632  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4633  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4634  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_IRQ_MAP);
   4635  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*map) + sizeof(*vec) * num_vec);
   4636  1.1  yamaguch 
   4637  1.1  yamaguch 	if (sc->sc_attached) {
   4638  1.1  yamaguch 		error = iavf_adminq_poll(sc, &iaq, aqb, 250);
   4639  1.1  yamaguch 	} else {
   4640  1.1  yamaguch 		error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250);
   4641  1.1  yamaguch 	}
   4642  1.1  yamaguch 
   4643  1.1  yamaguch 	if (error)
   4644  1.1  yamaguch 		return -1;
   4645  1.1  yamaguch 
   4646  1.1  yamaguch 	return 0;
   4647  1.1  yamaguch }
   4648  1.1  yamaguch 
   4649  1.1  yamaguch static int
   4650  1.1  yamaguch iavf_config_vsi_queues(struct iavf_softc *sc)
   4651  1.1  yamaguch {
   4652  1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   4653  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4654  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4655  1.1  yamaguch 	struct iavf_vc_queue_config_info *config;
   4656  1.1  yamaguch 	struct iavf_vc_txq_info *txq;
   4657  1.1  yamaguch 	struct iavf_vc_rxq_info *rxq;
   4658  1.1  yamaguch 	struct iavf_rx_ring *rxr;
   4659  1.1  yamaguch 	struct iavf_tx_ring *txr;
   4660  1.1  yamaguch 	uint32_t rxmtu_max;
   4661  1.1  yamaguch 	unsigned int i;
   4662  1.1  yamaguch 	int error;
   4663  1.1  yamaguch 
   4664  1.1  yamaguch 	rxmtu_max = ifp->if_mtu + IAVF_MTU_ETHERLEN;
   4665  1.1  yamaguch 
   4666  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4667  1.1  yamaguch 
   4668  1.1  yamaguch 	if (aqb == NULL)
   4669  1.1  yamaguch 		return -1;
   4670  1.1  yamaguch 
   4671  1.1  yamaguch 	config = IXL_AQB_KVA(aqb);
   4672  1.1  yamaguch 	memset(config, 0, sizeof(*config));
   4673  1.1  yamaguch 	config->vsi_id = htole16(sc->sc_vsi_id);
   4674  1.1  yamaguch 	config->num_queue_pairs = htole16(sc->sc_nqueue_pairs);
   4675  1.1  yamaguch 
   4676  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   4677  1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   4678  1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   4679  1.1  yamaguch 
   4680  1.1  yamaguch 		txq = &config->qpair[i].txq;
   4681  1.1  yamaguch 		txq->vsi_id = htole16(sc->sc_vsi_id);
   4682  1.1  yamaguch 		txq->queue_id = htole16(txr->txr_qid);
   4683  1.1  yamaguch 		txq->ring_len = htole16(sc->sc_tx_ring_ndescs);
   4684  1.1  yamaguch 		txq->headwb_ena = 0;
   4685  1.1  yamaguch 		txq->dma_ring_addr = htole64(IXL_DMA_DVA(&txr->txr_mem));
   4686  1.1  yamaguch 		txq->dma_headwb_addr = 0;
   4687  1.1  yamaguch 
   4688  1.1  yamaguch 		rxq = &config->qpair[i].rxq;
   4689  1.1  yamaguch 		rxq->vsi_id = htole16(sc->sc_vsi_id);
   4690  1.1  yamaguch 		rxq->queue_id = htole16(rxr->rxr_qid);
   4691  1.1  yamaguch 		rxq->ring_len = htole16(sc->sc_rx_ring_ndescs);
   4692  1.1  yamaguch 		rxq->splithdr_ena = 0;
   4693  1.1  yamaguch 		rxq->databuf_size = htole32(IAVF_MCLBYTES);
   4694  1.1  yamaguch 		rxq->max_pkt_size = htole32(rxmtu_max);
   4695  1.1  yamaguch 		rxq->dma_ring_addr = htole64(IXL_DMA_DVA(&rxr->rxr_mem));
   4696  1.1  yamaguch 		rxq->rx_split_pos = 0;
   4697  1.1  yamaguch 	}
   4698  1.1  yamaguch 
   4699  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4700  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4701  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4702  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_VSI_QUEUES);
   4703  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*config) +
   4704  1.1  yamaguch 	    sizeof(config->qpair[0]) * sc->sc_nqueue_pairs);
   4705  1.1  yamaguch 
   4706  1.1  yamaguch 	error = iavf_adminq_exec(sc, &iaq, aqb);
   4707  1.1  yamaguch 	if (error != IAVF_VC_RC_SUCCESS) {
   4708  1.1  yamaguch 		return -1;
   4709  1.1  yamaguch 	}
   4710  1.1  yamaguch 
   4711  1.1  yamaguch 	return 0;
   4712  1.1  yamaguch }
   4713  1.1  yamaguch 
   4714  1.1  yamaguch static int
   4715  1.1  yamaguch iavf_config_hena(struct iavf_softc *sc)
   4716  1.1  yamaguch {
   4717  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4718  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4719  1.1  yamaguch 	uint64_t *caps;
   4720  1.1  yamaguch 	int error;
   4721  1.1  yamaguch 
   4722  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4723  1.1  yamaguch 
   4724  1.1  yamaguch 	if (aqb == NULL)
   4725  1.1  yamaguch 		return -1;
   4726  1.1  yamaguch 
   4727  1.1  yamaguch 	caps = IXL_AQB_KVA(aqb);
   4728  1.1  yamaguch 	if (sc->sc_mac_type == I40E_MAC_X722_VF)
   4729  1.1  yamaguch 		*caps = IXL_RSS_HENA_DEFAULT_XL710;
   4730  1.1  yamaguch 	else
   4731  1.1  yamaguch 		*caps = IXL_RSS_HENA_DEFAULT_X722;
   4732  1.1  yamaguch 
   4733  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4734  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4735  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4736  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_SET_RSS_HENA);
   4737  1.2  jakllsch 	iaq.iaq_datalen = htole16(sizeof(*caps));
   4738  1.1  yamaguch 
   4739  1.1  yamaguch 	error = iavf_adminq_exec(sc, &iaq, aqb);
   4740  1.1  yamaguch 	if (error != IAVF_VC_RC_SUCCESS) {
   4741  1.1  yamaguch 		return -1;
   4742  1.1  yamaguch 	}
   4743  1.1  yamaguch 
   4744  1.1  yamaguch 	return 0;
   4745  1.1  yamaguch }
   4746  1.1  yamaguch 
   4747  1.1  yamaguch static inline void
   4748  1.1  yamaguch iavf_get_default_rss_key(uint8_t *buf, size_t len)
   4749  1.1  yamaguch {
   4750  1.1  yamaguch 	uint8_t rss_seed[RSS_KEYSIZE];
   4751  1.1  yamaguch 	size_t cplen;
   4752  1.1  yamaguch 
   4753  1.1  yamaguch 	cplen = MIN(len, sizeof(rss_seed));
   4754  1.1  yamaguch 	rss_getkey(rss_seed);
   4755  1.1  yamaguch 
   4756  1.1  yamaguch 	memcpy(buf, rss_seed, cplen);
   4757  1.1  yamaguch 	if (cplen < len)
   4758  1.1  yamaguch 		memset(buf + cplen, 0, len - cplen);
   4759  1.1  yamaguch }
   4760  1.1  yamaguch 
   4761  1.1  yamaguch static int
   4762  1.1  yamaguch iavf_config_rss_key(struct iavf_softc *sc)
   4763  1.1  yamaguch {
   4764  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4765  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4766  1.1  yamaguch 	struct iavf_vc_rss_key *rss_key;
   4767  1.1  yamaguch 	size_t key_len;
   4768  1.1  yamaguch 	int rv;
   4769  1.1  yamaguch 
   4770  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4771  1.1  yamaguch 	if (aqb == NULL)
   4772  1.1  yamaguch 		return -1;
   4773  1.1  yamaguch 
   4774  1.1  yamaguch 	rss_key = IXL_AQB_KVA(aqb);
   4775  1.1  yamaguch 	rss_key->vsi_id = htole16(sc->sc_vsi_id);
   4776  1.1  yamaguch 	key_len = IXL_RSS_KEY_SIZE;
   4777  1.1  yamaguch 	iavf_get_default_rss_key(rss_key->key, key_len);
   4778  1.1  yamaguch 	rss_key->key_len = key_len;
   4779  1.1  yamaguch 
   4780  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4781  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4782  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4783  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_RSS_KEY);
   4784  1.2  jakllsch 	iaq.iaq_datalen = htole16(sizeof(*rss_key) - sizeof(rss_key->pad)
   4785  1.1  yamaguch 	    + (sizeof(rss_key->key[0]) * key_len));
   4786  1.1  yamaguch 
   4787  1.1  yamaguch 	rv = iavf_adminq_exec(sc, &iaq, aqb);
   4788  1.1  yamaguch 	if (rv != IAVF_VC_RC_SUCCESS) {
   4789  1.1  yamaguch 		return -1;
   4790  1.1  yamaguch 	}
   4791  1.1  yamaguch 
   4792  1.1  yamaguch 	return 0;
   4793  1.1  yamaguch }
   4794  1.1  yamaguch 
   4795  1.1  yamaguch static int
   4796  1.1  yamaguch iavf_config_rss_lut(struct iavf_softc *sc)
   4797  1.1  yamaguch {
   4798  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4799  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4800  1.1  yamaguch 	struct iavf_vc_rss_lut *rss_lut;
   4801  1.1  yamaguch 	uint8_t *lut, v;
   4802  1.1  yamaguch 	int rv, i;
   4803  1.1  yamaguch 
   4804  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4805  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4806  1.1  yamaguch 
   4807  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4808  1.1  yamaguch 	if (aqb == NULL)
   4809  1.1  yamaguch 		return -1;
   4810  1.1  yamaguch 
   4811  1.1  yamaguch 	rss_lut = IXL_AQB_KVA(aqb);
   4812  1.1  yamaguch 	rss_lut->vsi_id = htole16(sc->sc_vsi_id);
   4813  1.1  yamaguch 	rss_lut->lut_entries = htole16(IXL_RSS_VSI_LUT_SIZE);
   4814  1.1  yamaguch 
   4815  1.1  yamaguch 	lut = rss_lut->lut;
   4816  1.1  yamaguch 	for (i = 0; i < IXL_RSS_VSI_LUT_SIZE; i++)  {
   4817  1.1  yamaguch 		v = i % sc->sc_nqueue_pairs;
   4818  1.1  yamaguch 		v &= IAVF_RSS_VSI_LUT_ENTRY_MASK;
   4819  1.1  yamaguch 		lut[i] = v;
   4820  1.1  yamaguch 	}
   4821  1.1  yamaguch 
   4822  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4823  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4824  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4825  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_RSS_LUT);
   4826  1.2  jakllsch 	iaq.iaq_datalen = htole16(sizeof(*rss_lut) - sizeof(rss_lut->pad)
   4827  1.1  yamaguch 	    + (sizeof(rss_lut->lut[0]) * IXL_RSS_VSI_LUT_SIZE));
   4828  1.1  yamaguch 
   4829  1.1  yamaguch 	rv = iavf_adminq_exec(sc, &iaq, aqb);
   4830  1.1  yamaguch 	if (rv != IAVF_VC_RC_SUCCESS) {
   4831  1.1  yamaguch 		return -1;
   4832  1.1  yamaguch 	}
   4833  1.1  yamaguch 
   4834  1.1  yamaguch 	return 0;
   4835  1.1  yamaguch }
   4836  1.1  yamaguch 
   4837  1.1  yamaguch static int
   4838  1.1  yamaguch iavf_queue_select(struct iavf_softc *sc, int opcode)
   4839  1.1  yamaguch {
   4840  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4841  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4842  1.1  yamaguch 	struct iavf_vc_queue_select *qsel;
   4843  1.1  yamaguch 	int error;
   4844  1.1  yamaguch 
   4845  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4846  1.1  yamaguch 	if (aqb == NULL)
   4847  1.1  yamaguch 		return -1;
   4848  1.1  yamaguch 
   4849  1.1  yamaguch 	qsel = IXL_AQB_KVA(aqb);
   4850  1.1  yamaguch 	qsel->vsi_id = htole16(sc->sc_vsi_id);
   4851  1.1  yamaguch 	qsel->rx_queues = htole32(iavf_allqueues(sc));
   4852  1.1  yamaguch 	qsel->tx_queues = htole32(iavf_allqueues(sc));
   4853  1.1  yamaguch 
   4854  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4855  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4856  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4857  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, opcode);
   4858  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*qsel));
   4859  1.1  yamaguch 
   4860  1.1  yamaguch 	error = iavf_adminq_exec(sc, &iaq, aqb);
   4861  1.1  yamaguch 	if (error != IAVF_VC_RC_SUCCESS) {
   4862  1.1  yamaguch 		return -1;
   4863  1.1  yamaguch 	}
   4864  1.1  yamaguch 
   4865  1.1  yamaguch 	return 0;
   4866  1.1  yamaguch }
   4867  1.1  yamaguch 
   4868  1.1  yamaguch static int
   4869  1.1  yamaguch iavf_request_queues(struct iavf_softc *sc, unsigned int req_num)
   4870  1.1  yamaguch {
   4871  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4872  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4873  1.1  yamaguch 	struct iavf_vc_res_request *req;
   4874  1.1  yamaguch 	int rv;
   4875  1.1  yamaguch 
   4876  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4877  1.1  yamaguch 	if (aqb == NULL)
   4878  1.1  yamaguch 		return ENOMEM;
   4879  1.1  yamaguch 
   4880  1.1  yamaguch 	req = IXL_AQB_KVA(aqb);
   4881  1.1  yamaguch 	req->num_queue_pairs = req_num;
   4882  1.1  yamaguch 
   4883  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4884  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4885  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4886  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_REQUEST_QUEUES);
   4887  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*req));
   4888  1.1  yamaguch 
   4889  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4890  1.1  yamaguch 	rv = iavf_atq_post(sc, &iaq, aqb);
   4891  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4892  1.1  yamaguch 
   4893  1.1  yamaguch 	return rv;
   4894  1.1  yamaguch }
   4895  1.1  yamaguch 
   4896  1.1  yamaguch static int
   4897  1.1  yamaguch iavf_reset_vf(struct iavf_softc *sc)
   4898  1.1  yamaguch {
   4899  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4900  1.1  yamaguch 	int error;
   4901  1.1  yamaguch 
   4902  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4903  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_RD);
   4904  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4905  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_RESET_VF);
   4906  1.1  yamaguch 	iaq.iaq_datalen = htole16(0);
   4907  1.1  yamaguch 
   4908  1.1  yamaguch 	iavf_wr(sc, I40E_VFGEN_RSTAT, IAVF_VFR_INPROGRESS);
   4909  1.1  yamaguch 
   4910  1.1  yamaguch 	mutex_enter(&sc->sc_adminq_lock);
   4911  1.1  yamaguch 	error = iavf_atq_post(sc, &iaq, NULL);
   4912  1.1  yamaguch 	mutex_exit(&sc->sc_adminq_lock);
   4913  1.1  yamaguch 
   4914  1.1  yamaguch 	return error;
   4915  1.1  yamaguch }
   4916  1.1  yamaguch 
   4917  1.1  yamaguch static int
   4918  1.1  yamaguch iavf_eth_addr(struct iavf_softc *sc, const uint8_t *addr, uint32_t opcode)
   4919  1.1  yamaguch {
   4920  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4921  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4922  1.1  yamaguch 	struct iavf_vc_eth_addr_list *addrs;
   4923  1.1  yamaguch 	struct iavf_vc_eth_addr *vcaddr;
   4924  1.1  yamaguch 	int rv;
   4925  1.1  yamaguch 
   4926  1.1  yamaguch 	KASSERT(sc->sc_attached);
   4927  1.1  yamaguch 	KASSERT(opcode == IAVF_VC_OP_ADD_ETH_ADDR ||
   4928  1.1  yamaguch 	    opcode == IAVF_VC_OP_DEL_ETH_ADDR);
   4929  1.1  yamaguch 
   4930  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4931  1.1  yamaguch 	if (aqb == NULL)
   4932  1.1  yamaguch 		return -1;
   4933  1.1  yamaguch 
   4934  1.1  yamaguch 	addrs = IXL_AQB_KVA(aqb);
   4935  1.1  yamaguch 	addrs->vsi_id = htole16(sc->sc_vsi_id);
   4936  1.1  yamaguch 	addrs->num_elements = htole16(1);
   4937  1.1  yamaguch 	vcaddr = addrs->list;
   4938  1.1  yamaguch 	memcpy(vcaddr->addr, addr, ETHER_ADDR_LEN);
   4939  1.1  yamaguch 
   4940  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4941  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4942  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4943  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, opcode);
   4944  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*addrs) + sizeof(*vcaddr));
   4945  1.1  yamaguch 
   4946  1.1  yamaguch 	if (sc->sc_resetting) {
   4947  1.1  yamaguch 		mutex_enter(&sc->sc_adminq_lock);
   4948  1.1  yamaguch 		rv = iavf_adminq_poll_locked(sc, &iaq, aqb, 250);
   4949  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   4950  1.1  yamaguch 		mutex_exit(&sc->sc_adminq_lock);
   4951  1.1  yamaguch 	} else {
   4952  1.1  yamaguch 		rv = iavf_adminq_exec(sc, &iaq, aqb);
   4953  1.1  yamaguch 	}
   4954  1.1  yamaguch 
   4955  1.1  yamaguch 	if (rv != IAVF_VC_RC_SUCCESS) {
   4956  1.1  yamaguch 		return -1;
   4957  1.1  yamaguch 	}
   4958  1.1  yamaguch 
   4959  1.1  yamaguch 	return 0;
   4960  1.1  yamaguch }
   4961  1.1  yamaguch 
   4962  1.1  yamaguch static int
   4963  1.1  yamaguch iavf_config_promisc_mode(struct iavf_softc *sc, int unicast, int multicast)
   4964  1.1  yamaguch {
   4965  1.1  yamaguch 	struct ixl_aq_desc iaq;
   4966  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4967  1.1  yamaguch 	struct iavf_vc_promisc_info *promisc;
   4968  1.1  yamaguch 	int flags;
   4969  1.1  yamaguch 
   4970  1.1  yamaguch 	KASSERT(sc->sc_attached);
   4971  1.1  yamaguch 
   4972  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   4973  1.1  yamaguch 	if (aqb == NULL)
   4974  1.1  yamaguch 		return -1;
   4975  1.1  yamaguch 
   4976  1.1  yamaguch 	flags = 0;
   4977  1.1  yamaguch 	if (unicast)
   4978  1.1  yamaguch 		flags |= IAVF_FLAG_VF_UNICAST_PROMISC;
   4979  1.1  yamaguch 	if (multicast)
   4980  1.1  yamaguch 		flags |= IAVF_FLAG_VF_MULTICAST_PROMISC;
   4981  1.1  yamaguch 
   4982  1.1  yamaguch 	promisc = IXL_AQB_KVA(aqb);
   4983  1.1  yamaguch 	promisc->vsi_id = htole16(sc->sc_vsi_id);
   4984  1.1  yamaguch 	promisc->flags = htole16(flags);
   4985  1.1  yamaguch 
   4986  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4987  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4988  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   4989  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_PROMISC);
   4990  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*promisc));
   4991  1.1  yamaguch 
   4992  1.1  yamaguch 	if (iavf_adminq_exec(sc, &iaq, aqb) != IAVF_VC_RC_SUCCESS) {
   4993  1.1  yamaguch 		return -1;
   4994  1.1  yamaguch 	}
   4995  1.1  yamaguch 
   4996  1.1  yamaguch 	return 0;
   4997  1.1  yamaguch }
   4998  1.1  yamaguch 
   4999  1.1  yamaguch static int
   5000  1.1  yamaguch iavf_config_vlan_stripping(struct iavf_softc *sc, int eccap)
   5001  1.1  yamaguch {
   5002  1.1  yamaguch 	struct ixl_aq_desc iaq;
   5003  1.1  yamaguch 	uint32_t opcode;
   5004  1.1  yamaguch 
   5005  1.1  yamaguch 	opcode = ISSET(eccap, ETHERCAP_VLAN_HWTAGGING) ?
   5006  1.1  yamaguch 	    IAVF_VC_OP_ENABLE_VLAN_STRIP : IAVF_VC_OP_DISABLE_VLAN_STRIP;
   5007  1.1  yamaguch 
   5008  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   5009  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_RD);
   5010  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   5011  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, opcode);
   5012  1.1  yamaguch 	iaq.iaq_datalen = htole16(0);
   5013  1.1  yamaguch 
   5014  1.1  yamaguch 	if (iavf_adminq_exec(sc, &iaq, NULL) != IAVF_VC_RC_SUCCESS) {
   5015  1.1  yamaguch 		return -1;
   5016  1.1  yamaguch 	}
   5017  1.1  yamaguch 
   5018  1.1  yamaguch 	return 0;
   5019  1.1  yamaguch }
   5020  1.1  yamaguch 
   5021  1.1  yamaguch static int
   5022  1.1  yamaguch iavf_config_vlan_id(struct iavf_softc *sc, uint16_t vid, uint32_t opcode)
   5023  1.1  yamaguch {
   5024  1.1  yamaguch 	struct ixl_aq_desc iaq;
   5025  1.1  yamaguch 	struct ixl_aq_buf *aqb;
   5026  1.1  yamaguch 	struct iavf_vc_vlan_filter *vfilter;
   5027  1.1  yamaguch 	int rv;
   5028  1.1  yamaguch 
   5029  1.1  yamaguch 	KASSERT(opcode == IAVF_VC_OP_ADD_VLAN || opcode == IAVF_VC_OP_DEL_VLAN);
   5030  1.1  yamaguch 
   5031  1.1  yamaguch 	aqb = iavf_aqb_get(sc, &sc->sc_atq_idle);
   5032  1.1  yamaguch 
   5033  1.1  yamaguch 	if (aqb == NULL)
   5034  1.1  yamaguch 		return -1;
   5035  1.1  yamaguch 
   5036  1.1  yamaguch 	vfilter = IXL_AQB_KVA(aqb);
   5037  1.1  yamaguch 	vfilter->vsi_id = htole16(sc->sc_vsi_id);
   5038  1.1  yamaguch 	vfilter->num_vlan_id = htole16(1);
   5039  1.1  yamaguch 	vfilter->vlan_id[0] = vid;
   5040  1.1  yamaguch 
   5041  1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   5042  1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   5043  1.1  yamaguch 	iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF);
   5044  1.1  yamaguch 	iavf_aq_vc_set_opcode(&iaq, opcode);
   5045  1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*vfilter) + sizeof(vid));
   5046  1.1  yamaguch 
   5047  1.1  yamaguch 	if (sc->sc_resetting) {
   5048  1.1  yamaguch 		mutex_enter(&sc->sc_adminq_lock);
   5049  1.1  yamaguch 		rv = iavf_adminq_poll_locked(sc, &iaq, aqb, 250);
   5050  1.1  yamaguch 		iavf_aqb_put_locked(&sc->sc_atq_idle, aqb);
   5051  1.1  yamaguch 		mutex_exit(&sc->sc_adminq_lock);
   5052  1.1  yamaguch 	} else {
   5053  1.1  yamaguch 		rv = iavf_adminq_exec(sc, &iaq, aqb);
   5054  1.1  yamaguch 	}
   5055  1.1  yamaguch 
   5056  1.1  yamaguch 	if (rv != IAVF_VC_RC_SUCCESS) {
   5057  1.1  yamaguch 		return -1;
   5058  1.1  yamaguch 	}
   5059  1.1  yamaguch 
   5060  1.1  yamaguch 	return 0;
   5061  1.1  yamaguch }
   5062  1.1  yamaguch 
   5063  1.1  yamaguch static void
   5064  1.1  yamaguch iavf_post_request_queues(void *xsc)
   5065  1.1  yamaguch {
   5066  1.1  yamaguch 	struct iavf_softc *sc;
   5067  1.1  yamaguch 	struct ifnet *ifp;
   5068  1.1  yamaguch 
   5069  1.1  yamaguch 	sc = xsc;
   5070  1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
   5071  1.1  yamaguch 
   5072  1.1  yamaguch 	if (!ISSET(sc->sc_vf_cap, IAVF_VC_OFFLOAD_REQ_QUEUES)) {
   5073  1.1  yamaguch 		log(LOG_DEBUG, "%s: the VF has no REQ_QUEUES capability\n",
   5074  1.1  yamaguch 		    ifp->if_xname);
   5075  1.1  yamaguch 		return;
   5076  1.1  yamaguch 	}
   5077  1.1  yamaguch 
   5078  1.1  yamaguch 	log(LOG_INFO, "%s: try to change the number of queue pairs"
   5079  1.1  yamaguch 	    " (vsi %u, %u allocated, request %u)\n",
   5080  1.1  yamaguch 	    ifp->if_xname,
   5081  1.1  yamaguch 	    sc->sc_nqps_vsi, sc->sc_nqps_alloc, sc->sc_nqps_req);
   5082  1.1  yamaguch 	iavf_request_queues(sc, sc->sc_nqps_req);
   5083  1.1  yamaguch }
   5084  1.1  yamaguch 
   5085  1.1  yamaguch static bool
   5086  1.1  yamaguch iavf_sysctlnode_is_rx(struct sysctlnode *node)
   5087  1.1  yamaguch {
   5088  1.1  yamaguch 
   5089  1.1  yamaguch 	if (strstr(node->sysctl_parent->sysctl_name, "rx") != NULL)
   5090  1.1  yamaguch 		return true;
   5091  1.1  yamaguch 
   5092  1.1  yamaguch 	return false;
   5093  1.1  yamaguch }
   5094  1.1  yamaguch 
   5095  1.1  yamaguch static int
   5096  1.1  yamaguch iavf_sysctl_itr_handler(SYSCTLFN_ARGS)
   5097  1.1  yamaguch {
   5098  1.1  yamaguch 	struct sysctlnode node = *rnode;
   5099  1.1  yamaguch 	struct iavf_softc *sc = (struct iavf_softc *)node.sysctl_data;
   5100  1.1  yamaguch 	uint32_t newitr, *itrptr;
   5101  1.1  yamaguch 	unsigned int i;
   5102  1.1  yamaguch 	int itr, error;
   5103  1.1  yamaguch 
   5104  1.1  yamaguch 	if (iavf_sysctlnode_is_rx(&node)) {
   5105  1.1  yamaguch 		itrptr = &sc->sc_rx_itr;
   5106  1.1  yamaguch 		itr = IAVF_ITR_RX;
   5107  1.1  yamaguch 	} else {
   5108  1.1  yamaguch 		itrptr = &sc->sc_tx_itr;
   5109  1.1  yamaguch 		itr = IAVF_ITR_TX;
   5110  1.1  yamaguch 	}
   5111  1.1  yamaguch 
   5112  1.1  yamaguch 	newitr = *itrptr;
   5113  1.1  yamaguch 	node.sysctl_data = &newitr;
   5114  1.1  yamaguch 	node.sysctl_size = sizeof(newitr);
   5115  1.1  yamaguch 
   5116  1.1  yamaguch 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
   5117  1.1  yamaguch 	if (error || newp == NULL)
   5118  1.1  yamaguch 		return error;
   5119  1.1  yamaguch 
   5120  1.1  yamaguch 	if (newitr > 0x07FF)
   5121  1.1  yamaguch 		return EINVAL;
   5122  1.1  yamaguch 
   5123  1.1  yamaguch 	*itrptr = newitr;
   5124  1.1  yamaguch 
   5125  1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   5126  1.1  yamaguch 		iavf_wr(sc, I40E_VFINT_ITRN1(itr, i), *itrptr);
   5127  1.1  yamaguch 	}
   5128  1.1  yamaguch 	iavf_wr(sc, I40E_VFINT_ITR01(itr), *itrptr);
   5129  1.1  yamaguch 
   5130  1.1  yamaguch 	return 0;
   5131  1.1  yamaguch }
   5132  1.1  yamaguch 
   5133  1.1  yamaguch static void
   5134  1.1  yamaguch iavf_workq_work(struct work *wk, void *context)
   5135  1.1  yamaguch {
   5136  1.1  yamaguch 	struct iavf_work *work;
   5137  1.1  yamaguch 
   5138  1.1  yamaguch 	work = container_of(wk, struct iavf_work, ixw_cookie);
   5139  1.1  yamaguch 
   5140  1.1  yamaguch 	atomic_swap_uint(&work->ixw_added, 0);
   5141  1.1  yamaguch 	work->ixw_func(work->ixw_arg);
   5142  1.1  yamaguch }
   5143  1.1  yamaguch 
   5144  1.1  yamaguch static struct workqueue *
   5145  1.1  yamaguch iavf_workq_create(const char *name, pri_t prio, int ipl, int flags)
   5146  1.1  yamaguch {
   5147  1.1  yamaguch 	struct workqueue *wq;
   5148  1.1  yamaguch 	int error;
   5149  1.1  yamaguch 
   5150  1.1  yamaguch 	error = workqueue_create(&wq, name, iavf_workq_work, NULL,
   5151  1.1  yamaguch 	    prio, ipl, flags);
   5152  1.1  yamaguch 
   5153  1.1  yamaguch 	if (error)
   5154  1.1  yamaguch 		return NULL;
   5155  1.1  yamaguch 
   5156  1.1  yamaguch 	return wq;
   5157  1.1  yamaguch }
   5158  1.1  yamaguch 
   5159  1.1  yamaguch static void
   5160  1.1  yamaguch iavf_workq_destroy(struct workqueue *wq)
   5161  1.1  yamaguch {
   5162  1.1  yamaguch 
   5163  1.1  yamaguch 	workqueue_destroy(wq);
   5164  1.1  yamaguch }
   5165  1.1  yamaguch 
   5166  1.1  yamaguch static int
   5167  1.1  yamaguch iavf_work_set(struct iavf_work *work, void (*func)(void *), void *arg)
   5168  1.1  yamaguch {
   5169  1.1  yamaguch 
   5170  1.1  yamaguch 	if (work->ixw_added != 0)
   5171  1.1  yamaguch 		return -1;
   5172  1.1  yamaguch 
   5173  1.1  yamaguch 	memset(work, 0, sizeof(*work));
   5174  1.1  yamaguch 	work->ixw_func = func;
   5175  1.1  yamaguch 	work->ixw_arg = arg;
   5176  1.1  yamaguch 
   5177  1.1  yamaguch 	return 0;
   5178  1.1  yamaguch }
   5179  1.1  yamaguch 
   5180  1.1  yamaguch static void
   5181  1.1  yamaguch iavf_work_add(struct workqueue *wq, struct iavf_work *work)
   5182  1.1  yamaguch {
   5183  1.1  yamaguch 	if (atomic_cas_uint(&work->ixw_added, 0, 1) != 0)
   5184  1.1  yamaguch 		return;
   5185  1.1  yamaguch 
   5186  1.1  yamaguch 	kpreempt_disable();
   5187  1.1  yamaguch 	workqueue_enqueue(wq, &work->ixw_cookie, NULL);
   5188  1.1  yamaguch 	kpreempt_enable();
   5189  1.1  yamaguch }
   5190  1.1  yamaguch 
   5191  1.1  yamaguch static void
   5192  1.1  yamaguch iavf_work_wait(struct workqueue *wq, struct iavf_work *work)
   5193  1.1  yamaguch {
   5194  1.1  yamaguch 
   5195  1.1  yamaguch 	workqueue_wait(wq, &work->ixw_cookie);
   5196  1.1  yamaguch }
   5197  1.1  yamaguch 
   5198  1.1  yamaguch static void
   5199  1.1  yamaguch iavf_evcnt_attach(struct evcnt *ec,
   5200  1.1  yamaguch     const char *n0, const char *n1)
   5201  1.1  yamaguch {
   5202  1.1  yamaguch 
   5203  1.1  yamaguch 	evcnt_attach_dynamic(ec, EVCNT_TYPE_MISC,
   5204  1.1  yamaguch 	    NULL, n0, n1);
   5205  1.1  yamaguch }
   5206  1.1  yamaguch 
   5207  1.1  yamaguch MODULE(MODULE_CLASS_DRIVER, if_iavf, "pci");
   5208  1.1  yamaguch 
   5209  1.1  yamaguch #ifdef _MODULE
   5210  1.1  yamaguch #include "ioconf.c"
   5211  1.1  yamaguch #endif
   5212  1.1  yamaguch 
   5213  1.1  yamaguch #ifdef _MODULE
   5214  1.1  yamaguch static void
   5215  1.1  yamaguch iavf_parse_modprop(prop_dictionary_t dict)
   5216  1.1  yamaguch {
   5217  1.1  yamaguch 	prop_object_t obj;
   5218  1.1  yamaguch 	int64_t val;
   5219  1.1  yamaguch 	uint32_t n;
   5220  1.1  yamaguch 
   5221  1.1  yamaguch 	if (dict == NULL)
   5222  1.1  yamaguch 		return;
   5223  1.1  yamaguch 
   5224  1.1  yamaguch 	obj = prop_dictionary_get(dict, "debug_level");
   5225  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5226  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5227  1.1  yamaguch 
   5228  1.1  yamaguch 		if (val > 0) {
   5229  1.1  yamaguch 			iavf_params.debug = val;
   5230  1.1  yamaguch 			printf("iavf: debug level=%d\n", iavf_params.debug);
   5231  1.1  yamaguch 		}
   5232  1.1  yamaguch 	}
   5233  1.1  yamaguch 
   5234  1.1  yamaguch 	obj = prop_dictionary_get(dict, "max_qps");
   5235  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5236  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5237  1.1  yamaguch 
   5238  1.1  yamaguch 		if (val < 1 || I40E_MAX_VF_QUEUES) {
   5239  1.1  yamaguch 			printf("iavf: invalid queue size(1 <= n <= %d)",
   5240  1.1  yamaguch 			    I40E_MAX_VF_QUEUES);
   5241  1.1  yamaguch 		} else {
   5242  1.1  yamaguch 			iavf_params.max_qps = val;
   5243  1.1  yamaguch 			printf("iavf: request queue pair = %u\n",
   5244  1.1  yamaguch 			    iavf_params.max_qps);
   5245  1.1  yamaguch 		}
   5246  1.1  yamaguch 	}
   5247  1.1  yamaguch 
   5248  1.1  yamaguch 	obj = prop_dictionary_get(dict, "tx_itr");
   5249  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5250  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5251  1.1  yamaguch 		if (val > 0x07FF) {
   5252  1.1  yamaguch 			printf("iavf: TX ITR too big (%" PRId64 " <= %d)",
   5253  1.1  yamaguch 			    val, 0x7FF);
   5254  1.1  yamaguch 		} else {
   5255  1.1  yamaguch 			iavf_params.tx_itr = val;
   5256  1.1  yamaguch 			printf("iavf: TX ITR = 0x%" PRIx32,
   5257  1.1  yamaguch 			    iavf_params.tx_itr);
   5258  1.1  yamaguch 		}
   5259  1.1  yamaguch 	}
   5260  1.1  yamaguch 
   5261  1.1  yamaguch 	obj = prop_dictionary_get(dict, "rx_itr");
   5262  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5263  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5264  1.1  yamaguch 		if (val > 0x07FF) {
   5265  1.1  yamaguch 			printf("iavf: RX ITR too big (%" PRId64 " <= %d)",
   5266  1.1  yamaguch 			    val, 0x7FF);
   5267  1.1  yamaguch 		} else {
   5268  1.1  yamaguch 			iavf_params.rx_itr = val;
   5269  1.1  yamaguch 			printf("iavf: RX ITR = 0x%" PRIx32,
   5270  1.1  yamaguch 			    iavf_params.rx_itr);
   5271  1.1  yamaguch 		}
   5272  1.1  yamaguch 	}
   5273  1.1  yamaguch 
   5274  1.1  yamaguch 	obj = prop_dictionary_get(dict, "tx_ndescs");
   5275  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5276  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5277  1.1  yamaguch 		n = 1U << (fls32(val) - 1);
   5278  1.1  yamaguch 		if (val != (int64_t) n) {
   5279  1.1  yamaguch 			printf("iavf: TX desc invlaid size"
   5280  1.1  yamaguch 			    "(%" PRId64 " != %" PRIu32 ")\n", val, n);
   5281  1.1  yamaguch 		} else if (val > (8192 - 32)) {
   5282  1.1  yamaguch 			printf("iavf: Tx desc too big (%" PRId64 " > %d)",
   5283  1.1  yamaguch 			    val, (8192 - 32));
   5284  1.1  yamaguch 		} else {
   5285  1.1  yamaguch 			iavf_params.tx_ndescs = val;
   5286  1.1  yamaguch 			printf("iavf: TX descriptors = 0x%04x",
   5287  1.1  yamaguch 			    iavf_params.tx_ndescs);
   5288  1.1  yamaguch 		}
   5289  1.1  yamaguch 	}
   5290  1.1  yamaguch 
   5291  1.1  yamaguch 	obj = prop_dictionary_get(dict, "rx_ndescs");
   5292  1.1  yamaguch 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   5293  1.1  yamaguch 		val = prop_number_signed_value((prop_number_t)obj);
   5294  1.1  yamaguch 		n = 1U << (fls32(val) - 1);
   5295  1.1  yamaguch 		if (val != (int64_t) n) {
   5296  1.1  yamaguch 			printf("iavf: RX desc invlaid size"
   5297  1.1  yamaguch 			    "(%" PRId64 " != %" PRIu32 ")\n", val, n);
   5298  1.1  yamaguch 		} else if (val > (8192 - 32)) {
   5299  1.1  yamaguch 			printf("iavf: Rx desc too big (%" PRId64 " > %d)",
   5300  1.1  yamaguch 			    val, (8192 - 32));
   5301  1.1  yamaguch 		} else {
   5302  1.1  yamaguch 			iavf_params.rx_ndescs = val;
   5303  1.1  yamaguch 			printf("iavf: RX descriptors = 0x%04x",
   5304  1.1  yamaguch 			    iavf_params.rx_ndescs);
   5305  1.1  yamaguch 		}
   5306  1.1  yamaguch 	}
   5307  1.1  yamaguch }
   5308  1.1  yamaguch #endif
   5309  1.1  yamaguch 
   5310  1.1  yamaguch static int
   5311  1.1  yamaguch if_iavf_modcmd(modcmd_t cmd, void *opaque)
   5312  1.1  yamaguch {
   5313  1.1  yamaguch 	int error = 0;
   5314  1.1  yamaguch 
   5315  1.1  yamaguch #ifdef _MODULE
   5316  1.1  yamaguch 	switch (cmd) {
   5317  1.1  yamaguch 	case MODULE_CMD_INIT:
   5318  1.1  yamaguch 		iavf_parse_modprop((prop_dictionary_t)opaque);
   5319  1.1  yamaguch 		error = config_init_component(cfdriver_ioconf_if_iavf,
   5320  1.1  yamaguch 		    cfattach_ioconf_if_iavf, cfdata_ioconf_if_iavf);
   5321  1.1  yamaguch 		break;
   5322  1.1  yamaguch 	case MODULE_CMD_FINI:
   5323  1.1  yamaguch 		error = config_fini_component(cfdriver_ioconf_if_iavf,
   5324  1.1  yamaguch 		    cfattach_ioconf_if_iavf, cfdata_ioconf_if_iavf);
   5325  1.1  yamaguch 		break;
   5326  1.1  yamaguch 	default:
   5327  1.1  yamaguch 		error = ENOTTY;
   5328  1.1  yamaguch 		break;
   5329  1.1  yamaguch 	}
   5330  1.1  yamaguch #endif
   5331  1.1  yamaguch 
   5332  1.1  yamaguch 	return error;
   5333  1.1  yamaguch }
   5334