Home | History | Annotate | Line # | Download | only in pci
if_ixl.c revision 1.16.2.1
      1  1.16.2.1        ad /*	$NetBSD: if_ixl.c,v 1.16.2.1 2020/01/17 21:47:31 ad 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  *
     37       1.1  yamaguch  * Permission to use, copy, modify, and distribute this software for any
     38       1.1  yamaguch  * purpose with or without fee is hereby granted, provided that the above
     39       1.1  yamaguch  * copyright notice and this permission notice appear in all copies.
     40       1.1  yamaguch  *
     41       1.1  yamaguch  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     42       1.1  yamaguch  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     43       1.1  yamaguch  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     44       1.1  yamaguch  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     45       1.1  yamaguch  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     46       1.1  yamaguch  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     47       1.1  yamaguch  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     48       1.1  yamaguch  */
     49       1.1  yamaguch 
     50       1.1  yamaguch /*
     51       1.1  yamaguch  * Copyright (c) 2019 Internet Initiative Japan, Inc.
     52       1.1  yamaguch  * All rights reserved.
     53       1.1  yamaguch  *
     54       1.1  yamaguch  * Redistribution and use in source and binary forms, with or without
     55       1.1  yamaguch  * modification, are permitted provided that the following conditions
     56       1.1  yamaguch  * are met:
     57       1.1  yamaguch  * 1. Redistributions of source code must retain the above copyright
     58       1.1  yamaguch  *    notice, this list of conditions and the following disclaimer.
     59       1.1  yamaguch  * 2. Redistributions in binary form must reproduce the above copyright
     60       1.1  yamaguch  *    notice, this list of conditions and the following disclaimer in the
     61       1.1  yamaguch  *    documentation and/or other materials provided with the distribution.
     62       1.1  yamaguch  *
     63       1.1  yamaguch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     64       1.1  yamaguch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     65       1.1  yamaguch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     66       1.1  yamaguch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     67       1.1  yamaguch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     68       1.1  yamaguch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     69       1.1  yamaguch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     70       1.1  yamaguch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     71       1.1  yamaguch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     72       1.1  yamaguch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     73       1.1  yamaguch  * POSSIBILITY OF SUCH DAMAGE.
     74       1.1  yamaguch  */
     75       1.1  yamaguch 
     76       1.1  yamaguch #include <sys/cdefs.h>
     77       1.1  yamaguch 
     78       1.1  yamaguch #ifdef _KERNEL_OPT
     79       1.1  yamaguch #include "opt_net_mpsafe.h"
     80  1.16.2.1        ad #include "opt_if_ixl.h"
     81       1.1  yamaguch #endif
     82       1.1  yamaguch 
     83       1.1  yamaguch #include <sys/param.h>
     84       1.1  yamaguch #include <sys/types.h>
     85       1.1  yamaguch 
     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/malloc.h>
     92       1.1  yamaguch #include <sys/module.h>
     93       1.1  yamaguch #include <sys/mutex.h>
     94       1.1  yamaguch #include <sys/pcq.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 <sys/bus.h>
     99       1.1  yamaguch 
    100       1.1  yamaguch #include <net/bpf.h>
    101       1.1  yamaguch #include <net/if.h>
    102       1.1  yamaguch #include <net/if_dl.h>
    103       1.1  yamaguch #include <net/if_media.h>
    104       1.1  yamaguch #include <net/if_ether.h>
    105       1.1  yamaguch #include <net/rss_config.h>
    106       1.1  yamaguch 
    107       1.1  yamaguch #include <dev/pci/pcivar.h>
    108       1.1  yamaguch #include <dev/pci/pcidevs.h>
    109       1.1  yamaguch 
    110       1.1  yamaguch #include <dev/pci/if_ixlreg.h>
    111       1.1  yamaguch #include <dev/pci/if_ixlvar.h>
    112       1.1  yamaguch 
    113  1.16.2.1        ad #include <prop/proplib.h>
    114  1.16.2.1        ad 
    115       1.1  yamaguch struct ixl_softc; /* defined */
    116       1.1  yamaguch 
    117       1.1  yamaguch #define I40E_PF_RESET_WAIT_COUNT	200
    118       1.1  yamaguch #define I40E_AQ_LARGE_BUF		512
    119       1.1  yamaguch 
    120       1.1  yamaguch /* bitfields for Tx queue mapping in QTX_CTL */
    121       1.1  yamaguch #define I40E_QTX_CTL_VF_QUEUE		0x0
    122       1.1  yamaguch #define I40E_QTX_CTL_VM_QUEUE		0x1
    123       1.1  yamaguch #define I40E_QTX_CTL_PF_QUEUE		0x2
    124       1.1  yamaguch 
    125       1.1  yamaguch #define I40E_QUEUE_TYPE_EOL		0x7ff
    126       1.1  yamaguch #define I40E_INTR_NOTX_QUEUE		0
    127       1.1  yamaguch 
    128       1.1  yamaguch #define I40E_QUEUE_TYPE_RX		0x0
    129       1.1  yamaguch #define I40E_QUEUE_TYPE_TX		0x1
    130       1.1  yamaguch #define I40E_QUEUE_TYPE_PE_CEQ		0x2
    131       1.1  yamaguch #define I40E_QUEUE_TYPE_UNKNOWN		0x3
    132       1.1  yamaguch 
    133       1.1  yamaguch #define I40E_ITR_INDEX_RX		0x0
    134       1.1  yamaguch #define I40E_ITR_INDEX_TX		0x1
    135       1.1  yamaguch #define I40E_ITR_INDEX_OTHER		0x2
    136       1.1  yamaguch #define I40E_ITR_INDEX_NONE		0x3
    137       1.1  yamaguch 
    138       1.1  yamaguch #define I40E_INTR_NOTX_QUEUE		0
    139       1.1  yamaguch #define I40E_INTR_NOTX_INTR		0
    140       1.1  yamaguch #define I40E_INTR_NOTX_RX_QUEUE		0
    141       1.1  yamaguch #define I40E_INTR_NOTX_TX_QUEUE		1
    142       1.1  yamaguch #define I40E_INTR_NOTX_RX_MASK		I40E_PFINT_ICR0_QUEUE_0_MASK
    143       1.1  yamaguch #define I40E_INTR_NOTX_TX_MASK		I40E_PFINT_ICR0_QUEUE_1_MASK
    144       1.1  yamaguch 
    145       1.1  yamaguch #define BIT_ULL(a)	(1ULL << (a))
    146       1.1  yamaguch #define IXL_RSS_HENA_DEFAULT_BASE			\
    147       1.1  yamaguch 	(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |	\
    148       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP) |	\
    149       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) |	\
    150       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |	\
    151       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4) |	\
    152       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |	\
    153       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP) |	\
    154       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) |	\
    155       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |	\
    156       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6) |	\
    157       1.1  yamaguch 	 BIT_ULL(I40E_FILTER_PCTYPE_L2_PAYLOAD))
    158       1.1  yamaguch #define IXL_RSS_HENA_DEFAULT_XL710	IXL_RSS_HENA_DEFAULT_BASE
    159       1.1  yamaguch #define IXL_RSS_HENA_DEFAULT_X722	(IXL_RSS_HENA_DEFAULT_XL710 |	\
    160       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |		\
    161       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) |		\
    162       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |		\
    163       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) |		\
    164       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK) |	\
    165       1.1  yamaguch 	BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK))
    166       1.1  yamaguch #define I40E_HASH_LUT_SIZE_128		0
    167       1.1  yamaguch #define IXL_RSS_KEY_SIZE_REG		13
    168       1.1  yamaguch 
    169       1.1  yamaguch #define IXL_ICR0_CRIT_ERR_MASK			\
    170       1.1  yamaguch 	(I40E_PFINT_ICR0_PCI_EXCEPTION_MASK |	\
    171       1.1  yamaguch 	I40E_PFINT_ICR0_ECC_ERR_MASK |		\
    172       1.1  yamaguch 	I40E_PFINT_ICR0_PE_CRITERR_MASK)
    173       1.1  yamaguch 
    174       1.1  yamaguch #define IXL_TX_PKT_DESCS		8
    175       1.1  yamaguch #define IXL_TX_QUEUE_ALIGN		128
    176       1.1  yamaguch #define IXL_RX_QUEUE_ALIGN		128
    177       1.1  yamaguch 
    178       1.1  yamaguch #define IXL_HARDMTU			9712 /* 9726 - ETHER_HDR_LEN */
    179       1.1  yamaguch 
    180       1.1  yamaguch #define IXL_PCIREG			PCI_MAPREG_START
    181       1.1  yamaguch 
    182       1.1  yamaguch #define IXL_ITR0			0x0
    183       1.1  yamaguch #define IXL_ITR1			0x1
    184       1.1  yamaguch #define IXL_ITR2			0x2
    185       1.1  yamaguch #define IXL_NOITR			0x3
    186       1.1  yamaguch 
    187       1.1  yamaguch #define IXL_AQ_NUM			256
    188       1.1  yamaguch #define IXL_AQ_MASK			(IXL_AQ_NUM - 1)
    189       1.1  yamaguch #define IXL_AQ_ALIGN			64 /* lol */
    190       1.1  yamaguch #define IXL_AQ_BUFLEN			4096
    191       1.1  yamaguch 
    192       1.1  yamaguch #define IXL_HMC_ROUNDUP			512
    193       1.1  yamaguch #define IXL_HMC_PGSIZE			4096
    194       1.1  yamaguch #define IXL_HMC_DVASZ			sizeof(uint64_t)
    195       1.1  yamaguch #define IXL_HMC_PGS			(IXL_HMC_PGSIZE / IXL_HMC_DVASZ)
    196       1.1  yamaguch #define IXL_HMC_L2SZ			(IXL_HMC_PGSIZE * IXL_HMC_PGS)
    197       1.1  yamaguch #define IXL_HMC_PDVALID			1ULL
    198       1.1  yamaguch 
    199       1.1  yamaguch #define IXL_ATQ_EXEC_TIMEOUT		(10 * hz)
    200       1.1  yamaguch 
    201  1.16.2.1        ad #define IXL_SRRD_SRCTL_ATTEMPTS		100000
    202  1.16.2.1        ad 
    203       1.1  yamaguch struct ixl_aq_regs {
    204       1.1  yamaguch 	bus_size_t		atq_tail;
    205       1.1  yamaguch 	bus_size_t		atq_head;
    206       1.1  yamaguch 	bus_size_t		atq_len;
    207       1.1  yamaguch 	bus_size_t		atq_bal;
    208       1.1  yamaguch 	bus_size_t		atq_bah;
    209       1.1  yamaguch 
    210       1.1  yamaguch 	bus_size_t		arq_tail;
    211       1.1  yamaguch 	bus_size_t		arq_head;
    212       1.1  yamaguch 	bus_size_t		arq_len;
    213       1.1  yamaguch 	bus_size_t		arq_bal;
    214       1.1  yamaguch 	bus_size_t		arq_bah;
    215       1.1  yamaguch 
    216       1.1  yamaguch 	uint32_t		atq_len_enable;
    217       1.1  yamaguch 	uint32_t		atq_tail_mask;
    218       1.1  yamaguch 	uint32_t		atq_head_mask;
    219       1.1  yamaguch 
    220       1.1  yamaguch 	uint32_t		arq_len_enable;
    221       1.1  yamaguch 	uint32_t		arq_tail_mask;
    222       1.1  yamaguch 	uint32_t		arq_head_mask;
    223       1.1  yamaguch };
    224       1.1  yamaguch 
    225       1.1  yamaguch struct ixl_phy_type {
    226       1.1  yamaguch 	uint64_t	phy_type;
    227       1.1  yamaguch 	uint64_t	ifm_type;
    228       1.1  yamaguch };
    229       1.1  yamaguch 
    230       1.1  yamaguch struct ixl_speed_type {
    231       1.1  yamaguch 	uint8_t		dev_speed;
    232       1.1  yamaguch 	uint64_t	net_speed;
    233       1.1  yamaguch };
    234       1.1  yamaguch 
    235       1.1  yamaguch struct ixl_aq_buf {
    236       1.1  yamaguch 	SIMPLEQ_ENTRY(ixl_aq_buf)
    237       1.1  yamaguch 				 aqb_entry;
    238       1.1  yamaguch 	void			*aqb_data;
    239       1.1  yamaguch 	bus_dmamap_t		 aqb_map;
    240       1.1  yamaguch 	bus_dma_segment_t	 aqb_seg;
    241       1.1  yamaguch 	size_t			 aqb_size;
    242       1.1  yamaguch 	int			 aqb_nsegs;
    243       1.1  yamaguch };
    244       1.1  yamaguch SIMPLEQ_HEAD(ixl_aq_bufs, ixl_aq_buf);
    245       1.1  yamaguch 
    246       1.1  yamaguch struct ixl_dmamem {
    247       1.1  yamaguch 	bus_dmamap_t		 ixm_map;
    248       1.1  yamaguch 	bus_dma_segment_t	 ixm_seg;
    249       1.1  yamaguch 	int			 ixm_nsegs;
    250       1.1  yamaguch 	size_t			 ixm_size;
    251       1.1  yamaguch 	void			*ixm_kva;
    252       1.1  yamaguch };
    253       1.1  yamaguch 
    254       1.1  yamaguch #define IXL_DMA_MAP(_ixm)	((_ixm)->ixm_map)
    255       1.1  yamaguch #define IXL_DMA_DVA(_ixm)	((_ixm)->ixm_map->dm_segs[0].ds_addr)
    256       1.1  yamaguch #define IXL_DMA_KVA(_ixm)	((void *)(_ixm)->ixm_kva)
    257       1.1  yamaguch #define IXL_DMA_LEN(_ixm)	((_ixm)->ixm_size)
    258       1.1  yamaguch 
    259       1.1  yamaguch struct ixl_hmc_entry {
    260       1.1  yamaguch 	uint64_t		 hmc_base;
    261       1.1  yamaguch 	uint32_t		 hmc_count;
    262       1.1  yamaguch 	uint64_t		 hmc_size;
    263       1.1  yamaguch };
    264       1.1  yamaguch 
    265       1.1  yamaguch enum  ixl_hmc_types {
    266       1.1  yamaguch 	IXL_HMC_LAN_TX = 0,
    267       1.1  yamaguch 	IXL_HMC_LAN_RX,
    268       1.1  yamaguch 	IXL_HMC_FCOE_CTX,
    269       1.1  yamaguch 	IXL_HMC_FCOE_FILTER,
    270       1.1  yamaguch 	IXL_HMC_COUNT
    271       1.1  yamaguch };
    272       1.1  yamaguch 
    273       1.1  yamaguch struct ixl_hmc_pack {
    274       1.1  yamaguch 	uint16_t		offset;
    275       1.1  yamaguch 	uint16_t		width;
    276       1.1  yamaguch 	uint16_t		lsb;
    277       1.1  yamaguch };
    278       1.1  yamaguch 
    279       1.1  yamaguch /*
    280       1.1  yamaguch  * these hmc objects have weird sizes and alignments, so these are abstract
    281       1.1  yamaguch  * representations of them that are nice for c to populate.
    282       1.1  yamaguch  *
    283       1.1  yamaguch  * the packing code relies on little-endian values being stored in the fields,
    284       1.1  yamaguch  * no high bits in the fields being set, and the fields must be packed in the
    285       1.1  yamaguch  * same order as they are in the ctx structure.
    286       1.1  yamaguch  */
    287       1.1  yamaguch 
    288       1.1  yamaguch struct ixl_hmc_rxq {
    289       1.1  yamaguch 	uint16_t		 head;
    290       1.1  yamaguch 	uint8_t			 cpuid;
    291       1.1  yamaguch 	uint64_t		 base;
    292       1.1  yamaguch #define IXL_HMC_RXQ_BASE_UNIT		128
    293       1.1  yamaguch 	uint16_t		 qlen;
    294       1.1  yamaguch 	uint16_t		 dbuff;
    295       1.1  yamaguch #define IXL_HMC_RXQ_DBUFF_UNIT		128
    296       1.1  yamaguch 	uint8_t			 hbuff;
    297       1.1  yamaguch #define IXL_HMC_RXQ_HBUFF_UNIT		64
    298       1.1  yamaguch 	uint8_t			 dtype;
    299       1.1  yamaguch #define IXL_HMC_RXQ_DTYPE_NOSPLIT	0x0
    300       1.1  yamaguch #define IXL_HMC_RXQ_DTYPE_HSPLIT	0x1
    301       1.1  yamaguch #define IXL_HMC_RXQ_DTYPE_SPLIT_ALWAYS	0x2
    302       1.1  yamaguch 	uint8_t			 dsize;
    303       1.1  yamaguch #define IXL_HMC_RXQ_DSIZE_16		0
    304       1.1  yamaguch #define IXL_HMC_RXQ_DSIZE_32		1
    305       1.1  yamaguch 	uint8_t			 crcstrip;
    306       1.1  yamaguch 	uint8_t			 fc_ena;
    307       1.1  yamaguch 	uint8_t			 l2sel;
    308       1.1  yamaguch 	uint8_t			 hsplit_0;
    309       1.1  yamaguch 	uint8_t			 hsplit_1;
    310       1.1  yamaguch 	uint8_t			 showiv;
    311       1.1  yamaguch 	uint16_t		 rxmax;
    312       1.1  yamaguch 	uint8_t			 tphrdesc_ena;
    313       1.1  yamaguch 	uint8_t			 tphwdesc_ena;
    314       1.1  yamaguch 	uint8_t			 tphdata_ena;
    315       1.1  yamaguch 	uint8_t			 tphhead_ena;
    316       1.1  yamaguch 	uint8_t			 lrxqthresh;
    317       1.1  yamaguch 	uint8_t			 prefena;
    318       1.1  yamaguch };
    319       1.1  yamaguch 
    320       1.1  yamaguch static const struct ixl_hmc_pack ixl_hmc_pack_rxq[] = {
    321       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, head),		13,	0 },
    322       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, cpuid),		8,	13 },
    323       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, base),		57,	32 },
    324       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, qlen),		13,	89 },
    325       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, dbuff),		7,	102 },
    326       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, hbuff),		5,	109 },
    327       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, dtype),		2,	114 },
    328       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, dsize),		1,	116 },
    329       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, crcstrip),	1,	117 },
    330       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, fc_ena),		1,	118 },
    331       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, l2sel),		1,	119 },
    332       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, hsplit_0),	4,	120 },
    333       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, hsplit_1),	2,	124 },
    334       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, showiv),		1,	127 },
    335       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, rxmax),		14,	174 },
    336       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, tphrdesc_ena),	1,	193 },
    337       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, tphwdesc_ena),	1,	194 },
    338       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, tphdata_ena),	1,	195 },
    339       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, tphhead_ena),	1,	196 },
    340       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, lrxqthresh),	3,	198 },
    341       1.1  yamaguch 	{ offsetof(struct ixl_hmc_rxq, prefena),	1,	201 },
    342       1.1  yamaguch };
    343       1.1  yamaguch 
    344       1.1  yamaguch #define IXL_HMC_RXQ_MINSIZE (201 + 1)
    345       1.1  yamaguch 
    346       1.1  yamaguch struct ixl_hmc_txq {
    347       1.1  yamaguch 	uint16_t		head;
    348       1.1  yamaguch 	uint8_t			new_context;
    349       1.1  yamaguch 	uint64_t		base;
    350       1.1  yamaguch #define IXL_HMC_TXQ_BASE_UNIT		128
    351       1.1  yamaguch 	uint8_t			fc_ena;
    352       1.1  yamaguch 	uint8_t			timesync_ena;
    353       1.1  yamaguch 	uint8_t			fd_ena;
    354       1.1  yamaguch 	uint8_t			alt_vlan_ena;
    355       1.1  yamaguch 	uint16_t		thead_wb;
    356       1.1  yamaguch 	uint8_t			cpuid;
    357       1.1  yamaguch 	uint8_t			head_wb_ena;
    358       1.1  yamaguch #define IXL_HMC_TXQ_DESC_WB		0
    359       1.1  yamaguch #define IXL_HMC_TXQ_HEAD_WB		1
    360       1.1  yamaguch 	uint16_t		qlen;
    361       1.1  yamaguch 	uint8_t			tphrdesc_ena;
    362       1.1  yamaguch 	uint8_t			tphrpacket_ena;
    363       1.1  yamaguch 	uint8_t			tphwdesc_ena;
    364       1.1  yamaguch 	uint64_t		head_wb_addr;
    365       1.1  yamaguch 	uint32_t		crc;
    366       1.1  yamaguch 	uint16_t		rdylist;
    367       1.1  yamaguch 	uint8_t			rdylist_act;
    368       1.1  yamaguch };
    369       1.1  yamaguch 
    370       1.1  yamaguch static const struct ixl_hmc_pack ixl_hmc_pack_txq[] = {
    371       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, head),		13,	0 },
    372       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, new_context),	1,	30 },
    373       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, base),		57,	32 },
    374       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, fc_ena),		1,	89 },
    375       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, timesync_ena),	1,	90 },
    376       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, fd_ena),		1,	91 },
    377       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, alt_vlan_ena),	1,	92 },
    378       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, cpuid),		8,	96 },
    379       1.1  yamaguch /* line 1 */
    380       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, thead_wb),	13,	0 + 128 },
    381       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, head_wb_ena),	1,	32 + 128 },
    382       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, qlen),		13,	33 + 128 },
    383       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, tphrdesc_ena),	1,	46 + 128 },
    384       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, tphrpacket_ena),	1,	47 + 128 },
    385       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, tphwdesc_ena),	1,	48 + 128 },
    386       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, head_wb_addr),	64,	64 + 128 },
    387       1.1  yamaguch /* line 7 */
    388       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, crc),		32,	0 + (7*128) },
    389       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, rdylist),	10,	84 + (7*128) },
    390       1.1  yamaguch 	{ offsetof(struct ixl_hmc_txq, rdylist_act),	1,	94 + (7*128) },
    391       1.1  yamaguch };
    392       1.1  yamaguch 
    393       1.1  yamaguch #define IXL_HMC_TXQ_MINSIZE (94 + (7*128) + 1)
    394       1.1  yamaguch 
    395       1.1  yamaguch struct ixl_work {
    396       1.1  yamaguch 	struct work	 ixw_cookie;
    397       1.1  yamaguch 	void		(*ixw_func)(void *);
    398       1.1  yamaguch 	void		*ixw_arg;
    399       1.1  yamaguch 	unsigned int	 ixw_added;
    400       1.1  yamaguch };
    401       1.1  yamaguch #define IXL_WORKQUEUE_PRI	PRI_SOFTNET
    402       1.1  yamaguch 
    403       1.1  yamaguch struct ixl_tx_map {
    404       1.1  yamaguch 	struct mbuf		*txm_m;
    405       1.1  yamaguch 	bus_dmamap_t		 txm_map;
    406       1.1  yamaguch 	unsigned int		 txm_eop;
    407       1.1  yamaguch };
    408       1.1  yamaguch 
    409       1.1  yamaguch struct ixl_tx_ring {
    410       1.1  yamaguch 	kmutex_t		 txr_lock;
    411       1.1  yamaguch 	struct ixl_softc	*txr_sc;
    412       1.1  yamaguch 
    413       1.1  yamaguch 	unsigned int		 txr_prod;
    414       1.1  yamaguch 	unsigned int		 txr_cons;
    415       1.1  yamaguch 
    416       1.1  yamaguch 	struct ixl_tx_map	*txr_maps;
    417       1.1  yamaguch 	struct ixl_dmamem	 txr_mem;
    418       1.1  yamaguch 
    419       1.1  yamaguch 	bus_size_t		 txr_tail;
    420       1.1  yamaguch 	unsigned int		 txr_qid;
    421       1.1  yamaguch 	pcq_t			*txr_intrq;
    422       1.1  yamaguch 	void			*txr_si;
    423       1.1  yamaguch 
    424       1.1  yamaguch 	uint64_t		 txr_oerrors;	/* if_oerrors */
    425       1.1  yamaguch 	uint64_t		 txr_opackets;	/* if_opackets */
    426       1.1  yamaguch 	uint64_t		 txr_obytes;	/* if_obytes */
    427       1.1  yamaguch 	uint64_t		 txr_omcasts;	/* if_omcasts */
    428       1.1  yamaguch 
    429       1.1  yamaguch 	struct evcnt		 txr_defragged;
    430       1.1  yamaguch 	struct evcnt		 txr_defrag_failed;
    431       1.1  yamaguch 	struct evcnt		 txr_pcqdrop;
    432       1.1  yamaguch 	struct evcnt		 txr_transmitdef;
    433       1.1  yamaguch 	struct evcnt		 txr_intr;
    434       1.1  yamaguch 	struct evcnt		 txr_defer;
    435       1.1  yamaguch };
    436       1.1  yamaguch 
    437       1.1  yamaguch struct ixl_rx_map {
    438       1.1  yamaguch 	struct mbuf		*rxm_m;
    439       1.1  yamaguch 	bus_dmamap_t		 rxm_map;
    440       1.1  yamaguch };
    441       1.1  yamaguch 
    442       1.1  yamaguch struct ixl_rx_ring {
    443       1.1  yamaguch 	kmutex_t		 rxr_lock;
    444       1.1  yamaguch 
    445       1.1  yamaguch 	unsigned int		 rxr_prod;
    446       1.1  yamaguch 	unsigned int		 rxr_cons;
    447       1.1  yamaguch 
    448       1.1  yamaguch 	struct ixl_rx_map	*rxr_maps;
    449       1.1  yamaguch 	struct ixl_dmamem	 rxr_mem;
    450       1.1  yamaguch 
    451       1.1  yamaguch 	struct mbuf		*rxr_m_head;
    452       1.1  yamaguch 	struct mbuf		**rxr_m_tail;
    453       1.1  yamaguch 
    454       1.1  yamaguch 	bus_size_t		 rxr_tail;
    455       1.1  yamaguch 	unsigned int		 rxr_qid;
    456       1.1  yamaguch 
    457       1.1  yamaguch 	uint64_t		 rxr_ipackets;	/* if_ipackets */
    458       1.1  yamaguch 	uint64_t		 rxr_ibytes;	/* if_ibytes */
    459       1.1  yamaguch 	uint64_t		 rxr_iqdrops;	/* iqdrops */
    460       1.1  yamaguch 	uint64_t		 rxr_ierrors;	/* if_ierrors */
    461       1.1  yamaguch 
    462       1.1  yamaguch 	struct evcnt		 rxr_mgethdr_failed;
    463       1.1  yamaguch 	struct evcnt		 rxr_mgetcl_failed;
    464       1.1  yamaguch 	struct evcnt		 rxr_mbuf_load_failed;
    465       1.1  yamaguch 	struct evcnt		 rxr_intr;
    466       1.1  yamaguch 	struct evcnt		 rxr_defer;
    467       1.1  yamaguch };
    468       1.1  yamaguch 
    469       1.1  yamaguch struct ixl_queue_pair {
    470       1.1  yamaguch 	struct ixl_softc	*qp_sc;
    471       1.1  yamaguch 	struct ixl_tx_ring	*qp_txr;
    472       1.1  yamaguch 	struct ixl_rx_ring	*qp_rxr;
    473       1.1  yamaguch 
    474       1.1  yamaguch 	char			 qp_name[16];
    475       1.1  yamaguch 
    476       1.1  yamaguch 	void			*qp_si;
    477       1.1  yamaguch 	struct ixl_work		 qp_task;
    478       1.1  yamaguch 	bool			 qp_workqueue;
    479       1.1  yamaguch };
    480       1.1  yamaguch 
    481       1.1  yamaguch struct ixl_atq {
    482       1.1  yamaguch 	struct ixl_aq_desc	 iatq_desc;
    483       1.4  yamaguch 	void			(*iatq_fn)(struct ixl_softc *,
    484       1.4  yamaguch 				    const struct ixl_aq_desc *);
    485       1.1  yamaguch };
    486       1.1  yamaguch SIMPLEQ_HEAD(ixl_atq_list, ixl_atq);
    487       1.1  yamaguch 
    488       1.1  yamaguch struct ixl_product {
    489       1.1  yamaguch 	unsigned int	 vendor_id;
    490       1.1  yamaguch 	unsigned int	 product_id;
    491       1.1  yamaguch };
    492       1.1  yamaguch 
    493  1.16.2.1        ad struct ixl_stats_counters {
    494  1.16.2.1        ad 	bool		 isc_has_offset;
    495  1.16.2.1        ad 	struct evcnt	 isc_crc_errors;
    496  1.16.2.1        ad 	uint64_t	 isc_crc_errors_offset;
    497  1.16.2.1        ad 	struct evcnt	 isc_illegal_bytes;
    498  1.16.2.1        ad 	uint64_t	 isc_illegal_bytes_offset;
    499  1.16.2.1        ad 	struct evcnt	 isc_rx_bytes;
    500  1.16.2.1        ad 	uint64_t	 isc_rx_bytes_offset;
    501  1.16.2.1        ad 	struct evcnt	 isc_rx_discards;
    502  1.16.2.1        ad 	uint64_t	 isc_rx_discards_offset;
    503  1.16.2.1        ad 	struct evcnt	 isc_rx_unicast;
    504  1.16.2.1        ad 	uint64_t	 isc_rx_unicast_offset;
    505  1.16.2.1        ad 	struct evcnt	 isc_rx_multicast;
    506  1.16.2.1        ad 	uint64_t	 isc_rx_multicast_offset;
    507  1.16.2.1        ad 	struct evcnt	 isc_rx_broadcast;
    508  1.16.2.1        ad 	uint64_t	 isc_rx_broadcast_offset;
    509  1.16.2.1        ad 	struct evcnt	 isc_rx_size_64;
    510  1.16.2.1        ad 	uint64_t	 isc_rx_size_64_offset;
    511  1.16.2.1        ad 	struct evcnt	 isc_rx_size_127;
    512  1.16.2.1        ad 	uint64_t	 isc_rx_size_127_offset;
    513  1.16.2.1        ad 	struct evcnt	 isc_rx_size_255;
    514  1.16.2.1        ad 	uint64_t	 isc_rx_size_255_offset;
    515  1.16.2.1        ad 	struct evcnt	 isc_rx_size_511;
    516  1.16.2.1        ad 	uint64_t	 isc_rx_size_511_offset;
    517  1.16.2.1        ad 	struct evcnt	 isc_rx_size_1023;
    518  1.16.2.1        ad 	uint64_t	 isc_rx_size_1023_offset;
    519  1.16.2.1        ad 	struct evcnt	 isc_rx_size_1522;
    520  1.16.2.1        ad 	uint64_t	 isc_rx_size_1522_offset;
    521  1.16.2.1        ad 	struct evcnt	 isc_rx_size_big;
    522  1.16.2.1        ad 	uint64_t	 isc_rx_size_big_offset;
    523  1.16.2.1        ad 	struct evcnt	 isc_rx_undersize;
    524  1.16.2.1        ad 	uint64_t	 isc_rx_undersize_offset;
    525  1.16.2.1        ad 	struct evcnt	 isc_rx_oversize;
    526  1.16.2.1        ad 	uint64_t	 isc_rx_oversize_offset;
    527  1.16.2.1        ad 	struct evcnt	 isc_rx_fragments;
    528  1.16.2.1        ad 	uint64_t	 isc_rx_fragments_offset;
    529  1.16.2.1        ad 	struct evcnt	 isc_rx_jabber;
    530  1.16.2.1        ad 	uint64_t	 isc_rx_jabber_offset;
    531  1.16.2.1        ad 	struct evcnt	 isc_tx_bytes;
    532  1.16.2.1        ad 	uint64_t	 isc_tx_bytes_offset;
    533  1.16.2.1        ad 	struct evcnt	 isc_tx_dropped_link_down;
    534  1.16.2.1        ad 	uint64_t	 isc_tx_dropped_link_down_offset;
    535  1.16.2.1        ad 	struct evcnt	 isc_tx_unicast;
    536  1.16.2.1        ad 	uint64_t	 isc_tx_unicast_offset;
    537  1.16.2.1        ad 	struct evcnt	 isc_tx_multicast;
    538  1.16.2.1        ad 	uint64_t	 isc_tx_multicast_offset;
    539  1.16.2.1        ad 	struct evcnt	 isc_tx_broadcast;
    540  1.16.2.1        ad 	uint64_t	 isc_tx_broadcast_offset;
    541  1.16.2.1        ad 	struct evcnt	 isc_tx_size_64;
    542  1.16.2.1        ad 	uint64_t	 isc_tx_size_64_offset;
    543  1.16.2.1        ad 	struct evcnt	 isc_tx_size_127;
    544  1.16.2.1        ad 	uint64_t	 isc_tx_size_127_offset;
    545  1.16.2.1        ad 	struct evcnt	 isc_tx_size_255;
    546  1.16.2.1        ad 	uint64_t	 isc_tx_size_255_offset;
    547  1.16.2.1        ad 	struct evcnt	 isc_tx_size_511;
    548  1.16.2.1        ad 	uint64_t	 isc_tx_size_511_offset;
    549  1.16.2.1        ad 	struct evcnt	 isc_tx_size_1023;
    550  1.16.2.1        ad 	uint64_t	 isc_tx_size_1023_offset;
    551  1.16.2.1        ad 	struct evcnt	 isc_tx_size_1522;
    552  1.16.2.1        ad 	uint64_t	 isc_tx_size_1522_offset;
    553  1.16.2.1        ad 	struct evcnt	 isc_tx_size_big;
    554  1.16.2.1        ad 	uint64_t	 isc_tx_size_big_offset;
    555  1.16.2.1        ad 	struct evcnt	 isc_mac_local_faults;
    556  1.16.2.1        ad 	uint64_t	 isc_mac_local_faults_offset;
    557  1.16.2.1        ad 	struct evcnt	 isc_mac_remote_faults;
    558  1.16.2.1        ad 	uint64_t	 isc_mac_remote_faults_offset;
    559  1.16.2.1        ad 	struct evcnt	 isc_link_xon_rx;
    560  1.16.2.1        ad 	uint64_t	 isc_link_xon_rx_offset;
    561  1.16.2.1        ad 	struct evcnt	 isc_link_xon_tx;
    562  1.16.2.1        ad 	uint64_t	 isc_link_xon_tx_offset;
    563  1.16.2.1        ad 	struct evcnt	 isc_link_xoff_rx;
    564  1.16.2.1        ad 	uint64_t	 isc_link_xoff_rx_offset;
    565  1.16.2.1        ad 	struct evcnt	 isc_link_xoff_tx;
    566  1.16.2.1        ad 	uint64_t	 isc_link_xoff_tx_offset;
    567  1.16.2.1        ad 	struct evcnt	 isc_vsi_rx_discards;
    568  1.16.2.1        ad 	uint64_t	 isc_vsi_rx_discards_offset;
    569  1.16.2.1        ad 	struct evcnt	 isc_vsi_rx_bytes;
    570  1.16.2.1        ad 	uint64_t	 isc_vsi_rx_bytes_offset;
    571  1.16.2.1        ad 	struct evcnt	 isc_vsi_rx_unicast;
    572  1.16.2.1        ad 	uint64_t	 isc_vsi_rx_unicast_offset;
    573  1.16.2.1        ad 	struct evcnt	 isc_vsi_rx_multicast;
    574  1.16.2.1        ad 	uint64_t	 isc_vsi_rx_multicast_offset;
    575  1.16.2.1        ad 	struct evcnt	 isc_vsi_rx_broadcast;
    576  1.16.2.1        ad 	uint64_t	 isc_vsi_rx_broadcast_offset;
    577  1.16.2.1        ad 	struct evcnt	 isc_vsi_tx_errors;
    578  1.16.2.1        ad 	uint64_t	 isc_vsi_tx_errors_offset;
    579  1.16.2.1        ad 	struct evcnt	 isc_vsi_tx_bytes;
    580  1.16.2.1        ad 	uint64_t	 isc_vsi_tx_bytes_offset;
    581  1.16.2.1        ad 	struct evcnt	 isc_vsi_tx_unicast;
    582  1.16.2.1        ad 	uint64_t	 isc_vsi_tx_unicast_offset;
    583  1.16.2.1        ad 	struct evcnt	 isc_vsi_tx_multicast;
    584  1.16.2.1        ad 	uint64_t	 isc_vsi_tx_multicast_offset;
    585  1.16.2.1        ad 	struct evcnt	 isc_vsi_tx_broadcast;
    586  1.16.2.1        ad 	uint64_t	 isc_vsi_tx_broadcast_offset;
    587  1.16.2.1        ad };
    588  1.16.2.1        ad 
    589       1.1  yamaguch /*
    590       1.1  yamaguch  * Locking notes:
    591       1.1  yamaguch  * + a field in ixl_tx_ring is protected by txr_lock (a spin mutex), and
    592       1.1  yamaguch  *   a field in ixl_rx_ring is protected by rxr_lock (a spin mutex).
    593       1.1  yamaguch  *    - more than one lock of them cannot be held at once.
    594       1.1  yamaguch  * + a field named sc_atq_* in ixl_softc is protected by sc_atq_lock
    595       1.1  yamaguch  *   (a spin mutex).
    596       1.1  yamaguch  *    - the lock cannot held with txr_lock or rxr_lock.
    597       1.1  yamaguch  * + a field named sc_arq_* is not protected by any lock.
    598       1.1  yamaguch  *    - operations for sc_arq_* is done in one context related to
    599       1.1  yamaguch  *      sc_arq_task.
    600       1.1  yamaguch  * + other fields in ixl_softc is protected by sc_cfg_lock
    601       1.1  yamaguch  *   (an adaptive mutex)
    602       1.1  yamaguch  *    - It must be held before another lock is held, and It can be
    603       1.1  yamaguch  *      released after the other lock is released.
    604       1.1  yamaguch  * */
    605       1.1  yamaguch 
    606       1.1  yamaguch struct ixl_softc {
    607       1.1  yamaguch 	device_t		 sc_dev;
    608       1.1  yamaguch 	struct ethercom		 sc_ec;
    609       1.1  yamaguch 	bool			 sc_attached;
    610       1.1  yamaguch 	bool			 sc_dead;
    611  1.16.2.1        ad 	uint32_t		 sc_port;
    612       1.1  yamaguch 	struct sysctllog	*sc_sysctllog;
    613       1.1  yamaguch 	struct workqueue	*sc_workq;
    614       1.1  yamaguch 	struct workqueue	*sc_workq_txrx;
    615  1.16.2.1        ad 	int			 sc_stats_intval;
    616  1.16.2.1        ad 	callout_t		 sc_stats_callout;
    617  1.16.2.1        ad 	struct ixl_work		 sc_stats_task;
    618  1.16.2.1        ad 	struct ixl_stats_counters
    619  1.16.2.1        ad 				 sc_stats_counters;
    620       1.1  yamaguch 	uint8_t			 sc_enaddr[ETHER_ADDR_LEN];
    621       1.1  yamaguch 	struct ifmedia		 sc_media;
    622       1.1  yamaguch 	uint64_t		 sc_media_status;
    623       1.1  yamaguch 	uint64_t		 sc_media_active;
    624       1.1  yamaguch 	kmutex_t		 sc_cfg_lock;
    625       1.1  yamaguch 	enum i40e_mac_type	 sc_mac_type;
    626       1.1  yamaguch 	uint32_t		 sc_rss_table_size;
    627       1.1  yamaguch 	uint32_t		 sc_rss_table_entry_width;
    628       1.1  yamaguch 	bool			 sc_txrx_workqueue;
    629       1.1  yamaguch 	u_int			 sc_tx_process_limit;
    630       1.1  yamaguch 	u_int			 sc_rx_process_limit;
    631       1.1  yamaguch 	u_int			 sc_tx_intr_process_limit;
    632       1.1  yamaguch 	u_int			 sc_rx_intr_process_limit;
    633       1.1  yamaguch 
    634      1.11  yamaguch 	int			 sc_cur_ec_capenable;
    635      1.11  yamaguch 
    636       1.1  yamaguch 	struct pci_attach_args	 sc_pa;
    637       1.1  yamaguch 	pci_intr_handle_t	*sc_ihp;
    638       1.1  yamaguch 	void			**sc_ihs;
    639       1.1  yamaguch 	unsigned int		 sc_nintrs;
    640       1.1  yamaguch 
    641       1.1  yamaguch 	bus_dma_tag_t		 sc_dmat;
    642       1.1  yamaguch 	bus_space_tag_t		 sc_memt;
    643       1.1  yamaguch 	bus_space_handle_t	 sc_memh;
    644       1.1  yamaguch 	bus_size_t		 sc_mems;
    645       1.1  yamaguch 
    646       1.1  yamaguch 	uint8_t			 sc_pf_id;
    647       1.1  yamaguch 	uint16_t		 sc_uplink_seid;	/* le */
    648       1.1  yamaguch 	uint16_t		 sc_downlink_seid;	/* le */
    649       1.1  yamaguch 	uint16_t		 sc_vsi_number;		/* le */
    650  1.16.2.1        ad 	uint16_t		 sc_vsi_stat_counter_idx;
    651       1.1  yamaguch 	uint16_t		 sc_seid;
    652       1.1  yamaguch 	unsigned int		 sc_base_queue;
    653       1.1  yamaguch 
    654       1.1  yamaguch 	pci_intr_type_t		 sc_intrtype;
    655       1.1  yamaguch 	unsigned int		 sc_msix_vector_queue;
    656       1.1  yamaguch 
    657       1.1  yamaguch 	struct ixl_dmamem	 sc_scratch;
    658  1.16.2.1        ad 	struct ixl_dmamem	 sc_aqbuf;
    659       1.1  yamaguch 
    660       1.1  yamaguch 	const struct ixl_aq_regs *
    661       1.1  yamaguch 				 sc_aq_regs;
    662  1.16.2.1        ad 	uint32_t		 sc_aq_flags;
    663  1.16.2.1        ad #define IXL_SC_AQ_FLAG_RXCTL	__BIT(0)
    664  1.16.2.1        ad #define IXL_SC_AQ_FLAG_NVMLOCK	__BIT(1)
    665  1.16.2.1        ad #define IXL_SC_AQ_FLAG_NVMREAD	__BIT(2)
    666       1.1  yamaguch 
    667       1.1  yamaguch 	kmutex_t		 sc_atq_lock;
    668       1.1  yamaguch 	kcondvar_t		 sc_atq_cv;
    669       1.1  yamaguch 	struct ixl_dmamem	 sc_atq;
    670       1.1  yamaguch 	unsigned int		 sc_atq_prod;
    671       1.1  yamaguch 	unsigned int		 sc_atq_cons;
    672       1.1  yamaguch 
    673       1.1  yamaguch 	struct ixl_dmamem	 sc_arq;
    674       1.1  yamaguch 	struct ixl_work		 sc_arq_task;
    675       1.1  yamaguch 	struct ixl_aq_bufs	 sc_arq_idle;
    676       1.1  yamaguch 	struct ixl_aq_buf	*sc_arq_live[IXL_AQ_NUM];
    677       1.1  yamaguch 	unsigned int		 sc_arq_prod;
    678       1.1  yamaguch 	unsigned int		 sc_arq_cons;
    679       1.1  yamaguch 
    680       1.1  yamaguch 	struct ixl_work		 sc_link_state_task;
    681       1.1  yamaguch 	struct ixl_atq		 sc_link_state_atq;
    682       1.1  yamaguch 
    683       1.1  yamaguch 	struct ixl_dmamem	 sc_hmc_sd;
    684       1.1  yamaguch 	struct ixl_dmamem	 sc_hmc_pd;
    685       1.1  yamaguch 	struct ixl_hmc_entry	 sc_hmc_entries[IXL_HMC_COUNT];
    686       1.1  yamaguch 
    687       1.1  yamaguch 	unsigned int		 sc_tx_ring_ndescs;
    688       1.1  yamaguch 	unsigned int		 sc_rx_ring_ndescs;
    689       1.1  yamaguch 	unsigned int		 sc_nqueue_pairs;
    690       1.1  yamaguch 	unsigned int		 sc_nqueue_pairs_max;
    691       1.1  yamaguch 	unsigned int		 sc_nqueue_pairs_device;
    692       1.1  yamaguch 	struct ixl_queue_pair	*sc_qps;
    693       1.1  yamaguch 
    694       1.1  yamaguch 	struct evcnt		 sc_event_atq;
    695       1.1  yamaguch 	struct evcnt		 sc_event_link;
    696       1.1  yamaguch 	struct evcnt		 sc_event_ecc_err;
    697       1.1  yamaguch 	struct evcnt		 sc_event_pci_exception;
    698       1.1  yamaguch 	struct evcnt		 sc_event_crit_err;
    699       1.1  yamaguch };
    700       1.1  yamaguch 
    701       1.1  yamaguch #define IXL_TXRX_PROCESS_UNLIMIT	UINT_MAX
    702       1.1  yamaguch #define IXL_TX_PROCESS_LIMIT		256
    703       1.1  yamaguch #define IXL_RX_PROCESS_LIMIT		256
    704       1.1  yamaguch #define IXL_TX_INTR_PROCESS_LIMIT	256
    705       1.1  yamaguch #define IXL_RX_INTR_PROCESS_LIMIT	0U
    706       1.1  yamaguch 
    707      1.14  yamaguch #define IXL_IFCAP_RXCSUM	(IFCAP_CSUM_IPv4_Rx|	\
    708      1.14  yamaguch 				 IFCAP_CSUM_TCPv4_Rx|	\
    709      1.14  yamaguch 				 IFCAP_CSUM_UDPv4_Rx|	\
    710      1.14  yamaguch 				 IFCAP_CSUM_TCPv6_Rx|	\
    711      1.14  yamaguch 				 IFCAP_CSUM_UDPv6_Rx)
    712      1.14  yamaguch 
    713       1.1  yamaguch #define delaymsec(_x)	DELAY(1000 * (_x))
    714       1.1  yamaguch #ifdef IXL_DEBUG
    715      1.13  yamaguch #define DDPRINTF(sc, fmt, args...)			\
    716      1.13  yamaguch do {							\
    717      1.13  yamaguch 	if ((sc) != NULL) {				\
    718      1.13  yamaguch 		device_printf(				\
    719      1.13  yamaguch 		    ((struct ixl_softc *)(sc))->sc_dev,	\
    720      1.13  yamaguch 		    "");				\
    721      1.13  yamaguch 	}						\
    722      1.13  yamaguch 	printf("%s:\t" fmt, __func__, ##args);		\
    723       1.1  yamaguch } while (0)
    724       1.1  yamaguch #else
    725       1.1  yamaguch #define DDPRINTF(sc, fmt, args...)	__nothing
    726       1.1  yamaguch #endif
    727  1.16.2.1        ad #ifndef IXL_STATS_INTERVAL_MSEC
    728  1.16.2.1        ad #define IXL_STATS_INTERVAL_MSEC	10000
    729  1.16.2.1        ad #endif
    730  1.16.2.1        ad #ifndef IXL_QUEUE_NUM
    731  1.16.2.1        ad #define IXL_QUEUE_NUM		0
    732  1.16.2.1        ad #endif
    733  1.16.2.1        ad 
    734  1.16.2.1        ad static bool		 ixl_param_nomsix = false;
    735  1.16.2.1        ad static int		 ixl_param_stats_interval = IXL_STATS_INTERVAL_MSEC;
    736  1.16.2.1        ad static int		 ixl_param_nqps_limit = IXL_QUEUE_NUM;
    737  1.16.2.1        ad static unsigned int	 ixl_param_tx_ndescs = 1024;
    738  1.16.2.1        ad static unsigned int	 ixl_param_rx_ndescs = 1024;
    739       1.1  yamaguch 
    740       1.1  yamaguch static enum i40e_mac_type
    741       1.1  yamaguch     ixl_mactype(pci_product_id_t);
    742       1.1  yamaguch static void	ixl_clear_hw(struct ixl_softc *);
    743       1.1  yamaguch static int	ixl_pf_reset(struct ixl_softc *);
    744       1.1  yamaguch 
    745       1.1  yamaguch static int	ixl_dmamem_alloc(struct ixl_softc *, struct ixl_dmamem *,
    746       1.1  yamaguch 		    bus_size_t, bus_size_t);
    747       1.1  yamaguch static void	ixl_dmamem_free(struct ixl_softc *, struct ixl_dmamem *);
    748       1.1  yamaguch 
    749       1.1  yamaguch static int	ixl_arq_fill(struct ixl_softc *);
    750       1.1  yamaguch static void	ixl_arq_unfill(struct ixl_softc *);
    751       1.1  yamaguch 
    752       1.1  yamaguch static int	ixl_atq_poll(struct ixl_softc *, struct ixl_aq_desc *,
    753       1.1  yamaguch 		    unsigned int);
    754       1.4  yamaguch static void	ixl_atq_set(struct ixl_atq *,
    755       1.4  yamaguch 		    void (*)(struct ixl_softc *, const struct ixl_aq_desc *));
    756       1.1  yamaguch static int	ixl_atq_post(struct ixl_softc *, struct ixl_atq *);
    757       1.1  yamaguch static int	ixl_atq_post_locked(struct ixl_softc *, struct ixl_atq *);
    758       1.1  yamaguch static void	ixl_atq_done(struct ixl_softc *);
    759       1.1  yamaguch static int	ixl_atq_exec(struct ixl_softc *, struct ixl_atq *);
    760       1.1  yamaguch static int	ixl_get_version(struct ixl_softc *);
    761  1.16.2.1        ad static int	ixl_get_nvm_version(struct ixl_softc *);
    762       1.1  yamaguch static int	ixl_get_hw_capabilities(struct ixl_softc *);
    763       1.1  yamaguch static int	ixl_pxe_clear(struct ixl_softc *);
    764       1.1  yamaguch static int	ixl_lldp_shut(struct ixl_softc *);
    765       1.1  yamaguch static int	ixl_get_mac(struct ixl_softc *);
    766       1.1  yamaguch static int	ixl_get_switch_config(struct ixl_softc *);
    767       1.1  yamaguch static int	ixl_phy_mask_ints(struct ixl_softc *);
    768       1.1  yamaguch static int	ixl_get_phy_types(struct ixl_softc *, uint64_t *);
    769       1.1  yamaguch static int	ixl_restart_an(struct ixl_softc *);
    770       1.1  yamaguch static int	ixl_hmc(struct ixl_softc *);
    771       1.1  yamaguch static void	ixl_hmc_free(struct ixl_softc *);
    772       1.1  yamaguch static int	ixl_get_vsi(struct ixl_softc *);
    773       1.1  yamaguch static int	ixl_set_vsi(struct ixl_softc *);
    774       1.1  yamaguch static void	ixl_set_filter_control(struct ixl_softc *);
    775       1.4  yamaguch static void	ixl_get_link_status(void *);
    776       1.4  yamaguch static int	ixl_get_link_status_poll(struct ixl_softc *);
    777       1.1  yamaguch static int	ixl_set_link_status(struct ixl_softc *,
    778       1.1  yamaguch 		    const struct ixl_aq_desc *);
    779       1.1  yamaguch static void	ixl_config_rss(struct ixl_softc *);
    780       1.1  yamaguch static int	ixl_add_macvlan(struct ixl_softc *, const uint8_t *,
    781       1.1  yamaguch 		    uint16_t, uint16_t);
    782      1.12  yamaguch static int	ixl_remove_macvlan(struct ixl_softc *, const uint8_t *,
    783      1.12  yamaguch 		    uint16_t, uint16_t);
    784       1.1  yamaguch static void	ixl_arq(void *);
    785       1.1  yamaguch static void	ixl_hmc_pack(void *, const void *,
    786       1.1  yamaguch 		    const struct ixl_hmc_pack *, unsigned int);
    787       1.1  yamaguch static uint32_t	ixl_rd_rx_csr(struct ixl_softc *, uint32_t);
    788       1.1  yamaguch static void	ixl_wr_rx_csr(struct ixl_softc *, uint32_t, uint32_t);
    789  1.16.2.1        ad static int	ixl_rd16_nvm(struct ixl_softc *, uint16_t, uint16_t *);
    790       1.1  yamaguch 
    791       1.1  yamaguch static int	ixl_match(device_t, cfdata_t, void *);
    792       1.1  yamaguch static void	ixl_attach(device_t, device_t, void *);
    793       1.1  yamaguch static int	ixl_detach(device_t, int);
    794       1.1  yamaguch 
    795       1.1  yamaguch static void	ixl_media_add(struct ixl_softc *, uint64_t);
    796       1.1  yamaguch static int	ixl_media_change(struct ifnet *);
    797       1.1  yamaguch static void	ixl_media_status(struct ifnet *, struct ifmediareq *);
    798       1.1  yamaguch static void	ixl_watchdog(struct ifnet *);
    799       1.1  yamaguch static int	ixl_ioctl(struct ifnet *, u_long, void *);
    800       1.1  yamaguch static void	ixl_start(struct ifnet *);
    801       1.1  yamaguch static int	ixl_transmit(struct ifnet *, struct mbuf *);
    802       1.1  yamaguch static void	ixl_deferred_transmit(void *);
    803       1.1  yamaguch static int	ixl_intr(void *);
    804       1.1  yamaguch static int	ixl_queue_intr(void *);
    805       1.1  yamaguch static int	ixl_other_intr(void *);
    806       1.1  yamaguch static void	ixl_handle_queue(void *);
    807       1.1  yamaguch static void	ixl_sched_handle_queue(struct ixl_softc *,
    808       1.1  yamaguch 		    struct ixl_queue_pair *);
    809       1.1  yamaguch static int	ixl_init(struct ifnet *);
    810       1.1  yamaguch static int	ixl_init_locked(struct ixl_softc *);
    811       1.1  yamaguch static void	ixl_stop(struct ifnet *, int);
    812       1.1  yamaguch static void	ixl_stop_locked(struct ixl_softc *);
    813       1.1  yamaguch static int	ixl_iff(struct ixl_softc *);
    814       1.1  yamaguch static int	ixl_ifflags_cb(struct ethercom *);
    815       1.1  yamaguch static int	ixl_setup_interrupts(struct ixl_softc *);
    816       1.1  yamaguch static int	ixl_establish_intx(struct ixl_softc *);
    817       1.1  yamaguch static int	ixl_establish_msix(struct ixl_softc *);
    818       1.1  yamaguch static void	ixl_enable_queue_intr(struct ixl_softc *,
    819       1.1  yamaguch 		    struct ixl_queue_pair *);
    820       1.1  yamaguch static void	ixl_disable_queue_intr(struct ixl_softc *,
    821       1.1  yamaguch 		    struct ixl_queue_pair *);
    822       1.1  yamaguch static void	ixl_enable_other_intr(struct ixl_softc *);
    823       1.1  yamaguch static void	ixl_disable_other_intr(struct ixl_softc *);
    824       1.1  yamaguch static void	ixl_config_queue_intr(struct ixl_softc *);
    825       1.1  yamaguch static void	ixl_config_other_intr(struct ixl_softc *);
    826       1.1  yamaguch 
    827       1.1  yamaguch static struct ixl_tx_ring *
    828       1.1  yamaguch 		ixl_txr_alloc(struct ixl_softc *, unsigned int);
    829       1.1  yamaguch static void	ixl_txr_qdis(struct ixl_softc *, struct ixl_tx_ring *, int);
    830       1.1  yamaguch static void	ixl_txr_config(struct ixl_softc *, struct ixl_tx_ring *);
    831       1.1  yamaguch static int	ixl_txr_enabled(struct ixl_softc *, struct ixl_tx_ring *);
    832       1.1  yamaguch static int	ixl_txr_disabled(struct ixl_softc *, struct ixl_tx_ring *);
    833       1.1  yamaguch static void	ixl_txr_unconfig(struct ixl_softc *, struct ixl_tx_ring *);
    834       1.1  yamaguch static void	ixl_txr_clean(struct ixl_softc *, struct ixl_tx_ring *);
    835       1.1  yamaguch static void	ixl_txr_free(struct ixl_softc *, struct ixl_tx_ring *);
    836       1.1  yamaguch static int	ixl_txeof(struct ixl_softc *, struct ixl_tx_ring *, u_int);
    837       1.1  yamaguch 
    838       1.1  yamaguch static struct ixl_rx_ring *
    839       1.1  yamaguch 		ixl_rxr_alloc(struct ixl_softc *, unsigned int);
    840       1.1  yamaguch static void	ixl_rxr_config(struct ixl_softc *, struct ixl_rx_ring *);
    841       1.1  yamaguch static int	ixl_rxr_enabled(struct ixl_softc *, struct ixl_rx_ring *);
    842       1.1  yamaguch static int	ixl_rxr_disabled(struct ixl_softc *, struct ixl_rx_ring *);
    843       1.1  yamaguch static void	ixl_rxr_unconfig(struct ixl_softc *, struct ixl_rx_ring *);
    844       1.1  yamaguch static void	ixl_rxr_clean(struct ixl_softc *, struct ixl_rx_ring *);
    845       1.1  yamaguch static void	ixl_rxr_free(struct ixl_softc *, struct ixl_rx_ring *);
    846       1.1  yamaguch static int	ixl_rxeof(struct ixl_softc *, struct ixl_rx_ring *, u_int);
    847       1.1  yamaguch static int	ixl_rxfill(struct ixl_softc *, struct ixl_rx_ring *);
    848       1.1  yamaguch 
    849       1.1  yamaguch static struct workqueue *
    850       1.1  yamaguch     ixl_workq_create(const char *, pri_t, int, int);
    851       1.1  yamaguch static void	ixl_workq_destroy(struct workqueue *);
    852       1.1  yamaguch static int	ixl_workqs_teardown(device_t);
    853       1.1  yamaguch static void	ixl_work_set(struct ixl_work *, void (*)(void *), void *);
    854       1.1  yamaguch static void	ixl_work_add(struct workqueue *, struct ixl_work *);
    855       1.1  yamaguch static void	ixl_work_wait(struct workqueue *, struct ixl_work *);
    856       1.1  yamaguch static void	ixl_workq_work(struct work *, void *);
    857       1.1  yamaguch static const struct ixl_product *
    858       1.1  yamaguch 		ixl_lookup(const struct pci_attach_args *pa);
    859       1.4  yamaguch static void	ixl_link_state_update(struct ixl_softc *,
    860       1.4  yamaguch 		    const struct ixl_aq_desc *);
    861      1.12  yamaguch static int	ixl_vlan_cb(struct ethercom *, uint16_t, bool);
    862      1.12  yamaguch static int	ixl_setup_vlan_hwfilter(struct ixl_softc *);
    863      1.12  yamaguch static void	ixl_teardown_vlan_hwfilter(struct ixl_softc *);
    864      1.12  yamaguch static int	ixl_update_macvlan(struct ixl_softc *);
    865       1.1  yamaguch static int	ixl_setup_interrupts(struct ixl_softc *);;
    866       1.1  yamaguch static void	ixl_teardown_interrupts(struct ixl_softc *);
    867       1.1  yamaguch static int	ixl_setup_stats(struct ixl_softc *);
    868       1.1  yamaguch static void	ixl_teardown_stats(struct ixl_softc *);
    869  1.16.2.1        ad static void	ixl_stats_callout(void *);
    870  1.16.2.1        ad static void	ixl_stats_update(void *);
    871       1.1  yamaguch static int	ixl_setup_sysctls(struct ixl_softc *);
    872       1.1  yamaguch static void	ixl_teardown_sysctls(struct ixl_softc *);
    873       1.1  yamaguch static int	ixl_queue_pairs_alloc(struct ixl_softc *);
    874       1.1  yamaguch static void	ixl_queue_pairs_free(struct ixl_softc *);
    875       1.1  yamaguch 
    876       1.1  yamaguch static const struct ixl_phy_type ixl_phy_type_map[] = {
    877       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_SGMII,		IFM_1000_SGMII },
    878       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_1000BASE_KX,	IFM_1000_KX },
    879       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_KX4,	IFM_10G_KX4 },
    880       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_KR,	IFM_10G_KR },
    881       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_40GBASE_KR4,	IFM_40G_KR4 },
    882       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_XAUI |
    883       1.1  yamaguch 	  1ULL << IXL_PHY_TYPE_XFI,		IFM_10G_CX4 },
    884       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_SFI,		IFM_10G_SFI },
    885       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_XLAUI |
    886       1.1  yamaguch 	  1ULL << IXL_PHY_TYPE_XLPPI,		IFM_40G_XLPPI },
    887       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_40GBASE_CR4_CU |
    888       1.1  yamaguch 	  1ULL << IXL_PHY_TYPE_40GBASE_CR4,	IFM_40G_CR4 },
    889       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_CR1_CU |
    890       1.1  yamaguch 	  1ULL << IXL_PHY_TYPE_10GBASE_CR1,	IFM_10G_CR1 },
    891       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_AOC,	IFM_10G_AOC },
    892       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_40GBASE_AOC,	IFM_40G_AOC },
    893       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_100BASE_TX,	IFM_100_TX },
    894       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_1000BASE_T_OPTICAL |
    895       1.1  yamaguch 	  1ULL << IXL_PHY_TYPE_1000BASE_T,	IFM_1000_T },
    896       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_T,	IFM_10G_T },
    897       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_SR,	IFM_10G_SR },
    898       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_LR,	IFM_10G_LR },
    899       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_10GBASE_SFPP_CU,	IFM_10G_TWINAX },
    900       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_40GBASE_SR4,	IFM_40G_SR4 },
    901       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_40GBASE_LR4,	IFM_40G_LR4 },
    902       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_1000BASE_SX,	IFM_1000_SX },
    903       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_1000BASE_LX,	IFM_1000_LX },
    904       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_20GBASE_KR2,	IFM_20G_KR2 },
    905       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_KR,	IFM_25G_KR },
    906       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_CR,	IFM_25G_CR },
    907       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_SR,	IFM_25G_SR },
    908       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_LR,	IFM_25G_LR },
    909       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_AOC,	IFM_25G_AOC },
    910       1.1  yamaguch 	{ 1ULL << IXL_PHY_TYPE_25GBASE_ACC,	IFM_25G_CR },
    911       1.1  yamaguch };
    912       1.1  yamaguch 
    913       1.1  yamaguch static const struct ixl_speed_type ixl_speed_type_map[] = {
    914       1.1  yamaguch 	{ IXL_AQ_LINK_SPEED_40GB,		IF_Gbps(40) },
    915       1.1  yamaguch 	{ IXL_AQ_LINK_SPEED_25GB,		IF_Gbps(25) },
    916       1.1  yamaguch 	{ IXL_AQ_LINK_SPEED_10GB,		IF_Gbps(10) },
    917       1.1  yamaguch 	{ IXL_AQ_LINK_SPEED_1000MB,		IF_Mbps(1000) },
    918       1.1  yamaguch 	{ IXL_AQ_LINK_SPEED_100MB,		IF_Mbps(100)},
    919       1.1  yamaguch };
    920       1.1  yamaguch 
    921       1.1  yamaguch static const struct ixl_aq_regs ixl_pf_aq_regs = {
    922       1.1  yamaguch 	.atq_tail	= I40E_PF_ATQT,
    923       1.1  yamaguch 	.atq_tail_mask	= I40E_PF_ATQT_ATQT_MASK,
    924       1.1  yamaguch 	.atq_head	= I40E_PF_ATQH,
    925       1.1  yamaguch 	.atq_head_mask	= I40E_PF_ATQH_ATQH_MASK,
    926       1.1  yamaguch 	.atq_len	= I40E_PF_ATQLEN,
    927       1.1  yamaguch 	.atq_bal	= I40E_PF_ATQBAL,
    928       1.1  yamaguch 	.atq_bah	= I40E_PF_ATQBAH,
    929       1.1  yamaguch 	.atq_len_enable	= I40E_PF_ATQLEN_ATQENABLE_MASK,
    930       1.1  yamaguch 
    931       1.1  yamaguch 	.arq_tail	= I40E_PF_ARQT,
    932       1.1  yamaguch 	.arq_tail_mask	= I40E_PF_ARQT_ARQT_MASK,
    933       1.1  yamaguch 	.arq_head	= I40E_PF_ARQH,
    934       1.1  yamaguch 	.arq_head_mask	= I40E_PF_ARQH_ARQH_MASK,
    935       1.1  yamaguch 	.arq_len	= I40E_PF_ARQLEN,
    936       1.1  yamaguch 	.arq_bal	= I40E_PF_ARQBAL,
    937       1.1  yamaguch 	.arq_bah	= I40E_PF_ARQBAH,
    938       1.1  yamaguch 	.arq_len_enable	= I40E_PF_ARQLEN_ARQENABLE_MASK,
    939       1.1  yamaguch };
    940       1.1  yamaguch 
    941       1.1  yamaguch #define ixl_rd(_s, _r)			\
    942       1.1  yamaguch 	bus_space_read_4((_s)->sc_memt, (_s)->sc_memh, (_r))
    943       1.1  yamaguch #define ixl_wr(_s, _r, _v)		\
    944       1.1  yamaguch 	bus_space_write_4((_s)->sc_memt, (_s)->sc_memh, (_r), (_v))
    945       1.1  yamaguch #define ixl_barrier(_s, _r, _l, _o) \
    946       1.1  yamaguch     bus_space_barrier((_s)->sc_memt, (_s)->sc_memh, (_r), (_l), (_o))
    947       1.1  yamaguch #define ixl_flush(_s)	(void)ixl_rd((_s), I40E_GLGEN_STAT)
    948       1.1  yamaguch #define ixl_nqueues(_sc)	(1 << ((_sc)->sc_nqueue_pairs - 1))
    949       1.2  yamaguch 
    950       1.2  yamaguch static inline uint32_t
    951       1.2  yamaguch ixl_dmamem_hi(struct ixl_dmamem *ixm)
    952       1.2  yamaguch {
    953       1.3  yamaguch 	uint32_t retval;
    954       1.3  yamaguch 	uint64_t val;
    955       1.2  yamaguch 
    956       1.5  yamaguch 	if (sizeof(IXL_DMA_DVA(ixm)) > 4) {
    957       1.3  yamaguch 		val = (intptr_t)IXL_DMA_DVA(ixm);
    958       1.3  yamaguch 		retval = (uint32_t)(val >> 32);
    959       1.3  yamaguch 	} else {
    960       1.3  yamaguch 		retval = 0;
    961       1.3  yamaguch 	}
    962       1.2  yamaguch 
    963       1.3  yamaguch 	return retval;
    964       1.2  yamaguch }
    965       1.2  yamaguch 
    966       1.2  yamaguch static inline uint32_t
    967       1.2  yamaguch ixl_dmamem_lo(struct ixl_dmamem *ixm)
    968       1.2  yamaguch {
    969       1.2  yamaguch 
    970       1.2  yamaguch 	return (uint32_t)IXL_DMA_DVA(ixm);
    971       1.2  yamaguch }
    972       1.1  yamaguch 
    973       1.1  yamaguch static inline void
    974       1.1  yamaguch ixl_aq_dva(struct ixl_aq_desc *iaq, bus_addr_t addr)
    975       1.1  yamaguch {
    976       1.3  yamaguch 	uint64_t val;
    977       1.2  yamaguch 
    978       1.5  yamaguch 	if (sizeof(addr) > 4) {
    979       1.3  yamaguch 		val = (intptr_t)addr;
    980       1.3  yamaguch 		iaq->iaq_param[2] = htole32(val >> 32);
    981       1.3  yamaguch 	} else {
    982       1.2  yamaguch 		iaq->iaq_param[2] = htole32(0);
    983       1.3  yamaguch 	}
    984       1.2  yamaguch 
    985       1.1  yamaguch 	iaq->iaq_param[3] = htole32(addr);
    986       1.1  yamaguch }
    987       1.1  yamaguch 
    988       1.1  yamaguch static inline unsigned int
    989       1.1  yamaguch ixl_rxr_unrefreshed(unsigned int prod, unsigned int cons, unsigned int ndescs)
    990       1.1  yamaguch {
    991       1.1  yamaguch 	unsigned int num;
    992       1.1  yamaguch 
    993       1.1  yamaguch 	if (prod  < cons)
    994       1.1  yamaguch 		num = cons - prod;
    995       1.1  yamaguch 	else
    996       1.1  yamaguch 		num  = (ndescs - prod) + cons;
    997       1.1  yamaguch 
    998       1.1  yamaguch 	if (__predict_true(num > 0)) {
    999       1.1  yamaguch 		/* device cannot receive packets if all descripter is filled */
   1000       1.1  yamaguch 		num -= 1;
   1001       1.1  yamaguch 	}
   1002       1.1  yamaguch 
   1003       1.1  yamaguch 	return num;
   1004       1.1  yamaguch }
   1005       1.1  yamaguch 
   1006       1.1  yamaguch CFATTACH_DECL3_NEW(ixl, sizeof(struct ixl_softc),
   1007       1.1  yamaguch     ixl_match, ixl_attach, ixl_detach, NULL, NULL, NULL,
   1008       1.1  yamaguch     DVF_DETACH_SHUTDOWN);
   1009       1.1  yamaguch 
   1010       1.1  yamaguch static const struct ixl_product ixl_products[] = {
   1011       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_SFP },
   1012       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_KX_B },
   1013       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_KX_C },
   1014       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_QSFP_A },
   1015       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_QSFP_B },
   1016       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_QSFP_C },
   1017       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X710_10G_T },
   1018       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_20G_BP_1 },
   1019       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XL710_20G_BP_2 },
   1020       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X710_T4_10G },
   1021       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XXV710_25G_BP },
   1022       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_XXV710_25G_SFP28 },
   1023       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_KX },
   1024       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_QSFP },
   1025       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_SFP },
   1026       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_1G_BASET },
   1027       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_10G_BASET },
   1028       1.1  yamaguch 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_X722_I_SFP },
   1029       1.1  yamaguch 	/* required last entry */
   1030       1.1  yamaguch 	{0, 0}
   1031       1.1  yamaguch };
   1032       1.1  yamaguch 
   1033       1.1  yamaguch static const struct ixl_product *
   1034       1.1  yamaguch ixl_lookup(const struct pci_attach_args *pa)
   1035       1.1  yamaguch {
   1036       1.1  yamaguch 	const struct ixl_product *ixlp;
   1037       1.1  yamaguch 
   1038       1.1  yamaguch 	for (ixlp = ixl_products; ixlp->vendor_id != 0; ixlp++) {
   1039       1.1  yamaguch 		if (PCI_VENDOR(pa->pa_id) == ixlp->vendor_id &&
   1040       1.1  yamaguch 		    PCI_PRODUCT(pa->pa_id) == ixlp->product_id)
   1041       1.1  yamaguch 			return ixlp;
   1042       1.1  yamaguch 	}
   1043       1.1  yamaguch 
   1044       1.1  yamaguch 	return NULL;
   1045       1.1  yamaguch }
   1046       1.1  yamaguch 
   1047       1.1  yamaguch static int
   1048       1.1  yamaguch ixl_match(device_t parent, cfdata_t match, void *aux)
   1049       1.1  yamaguch {
   1050       1.1  yamaguch 	const struct pci_attach_args *pa = aux;
   1051       1.1  yamaguch 
   1052       1.1  yamaguch 	return (ixl_lookup(pa) != NULL) ? 1 : 0;
   1053       1.1  yamaguch }
   1054       1.1  yamaguch 
   1055       1.1  yamaguch static void
   1056       1.1  yamaguch ixl_attach(device_t parent, device_t self, void *aux)
   1057       1.1  yamaguch {
   1058       1.1  yamaguch 	struct ixl_softc *sc;
   1059       1.1  yamaguch 	struct pci_attach_args *pa = aux;
   1060       1.1  yamaguch 	struct ifnet *ifp;
   1061  1.16.2.1        ad 	pcireg_t memtype;
   1062       1.1  yamaguch 	uint32_t firstq, port, ari, func;
   1063       1.1  yamaguch 	uint64_t phy_types = 0;
   1064       1.1  yamaguch 	char xnamebuf[32];
   1065       1.1  yamaguch 	int tries, rv;
   1066       1.1  yamaguch 
   1067       1.1  yamaguch 	sc = device_private(self);
   1068       1.1  yamaguch 	sc->sc_dev = self;
   1069       1.1  yamaguch 	ifp = &sc->sc_ec.ec_if;
   1070       1.1  yamaguch 
   1071       1.1  yamaguch 	sc->sc_pa = *pa;
   1072       1.1  yamaguch 	sc->sc_dmat = (pci_dma64_available(pa)) ?
   1073       1.1  yamaguch 	    pa->pa_dmat64 : pa->pa_dmat;
   1074       1.1  yamaguch 	sc->sc_aq_regs = &ixl_pf_aq_regs;
   1075       1.1  yamaguch 
   1076  1.16.2.1        ad 	sc->sc_mac_type = ixl_mactype(PCI_PRODUCT(pa->pa_id));
   1077       1.1  yamaguch 
   1078       1.1  yamaguch 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IXL_PCIREG);
   1079       1.1  yamaguch 	if (pci_mapreg_map(pa, IXL_PCIREG, memtype, 0,
   1080       1.1  yamaguch 	    &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) {
   1081       1.1  yamaguch 		aprint_error(": unable to map registers\n");
   1082       1.1  yamaguch 		return;
   1083       1.1  yamaguch 	}
   1084       1.1  yamaguch 
   1085       1.1  yamaguch 	mutex_init(&sc->sc_cfg_lock, MUTEX_DEFAULT, IPL_SOFTNET);
   1086       1.1  yamaguch 
   1087       1.1  yamaguch 	firstq = ixl_rd(sc, I40E_PFLAN_QALLOC);
   1088       1.1  yamaguch 	firstq &= I40E_PFLAN_QALLOC_FIRSTQ_MASK;
   1089       1.1  yamaguch 	firstq >>= I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
   1090       1.1  yamaguch 	sc->sc_base_queue = firstq;
   1091       1.1  yamaguch 
   1092       1.1  yamaguch 	ixl_clear_hw(sc);
   1093       1.1  yamaguch 	if (ixl_pf_reset(sc) == -1) {
   1094       1.1  yamaguch 		/* error printed by ixl pf_reset */
   1095       1.1  yamaguch 		goto unmap;
   1096       1.1  yamaguch 	}
   1097       1.1  yamaguch 
   1098       1.1  yamaguch 	port = ixl_rd(sc, I40E_PFGEN_PORTNUM);
   1099       1.1  yamaguch 	port &= I40E_PFGEN_PORTNUM_PORT_NUM_MASK;
   1100       1.1  yamaguch 	port >>= I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
   1101  1.16.2.1        ad 	sc->sc_port = port;
   1102  1.16.2.1        ad 	aprint_normal(": port %u", sc->sc_port);
   1103       1.1  yamaguch 
   1104       1.1  yamaguch 	ari = ixl_rd(sc, I40E_GLPCI_CAPSUP);
   1105       1.1  yamaguch 	ari &= I40E_GLPCI_CAPSUP_ARI_EN_MASK;
   1106       1.1  yamaguch 	ari >>= I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
   1107       1.1  yamaguch 
   1108       1.1  yamaguch 	func = ixl_rd(sc, I40E_PF_FUNC_RID);
   1109       1.1  yamaguch 	sc->sc_pf_id = func & (ari ? 0xff : 0x7);
   1110       1.1  yamaguch 
   1111       1.1  yamaguch 	/* initialise the adminq */
   1112       1.1  yamaguch 
   1113       1.1  yamaguch 	mutex_init(&sc->sc_atq_lock, MUTEX_DEFAULT, IPL_NET);
   1114       1.1  yamaguch 
   1115       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &sc->sc_atq,
   1116       1.1  yamaguch 	    sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) {
   1117       1.1  yamaguch 		aprint_error("\n" "%s: unable to allocate atq\n",
   1118       1.1  yamaguch 		    device_xname(self));
   1119       1.1  yamaguch 		goto unmap;
   1120       1.1  yamaguch 	}
   1121       1.1  yamaguch 
   1122       1.1  yamaguch 	SIMPLEQ_INIT(&sc->sc_arq_idle);
   1123       1.1  yamaguch 	ixl_work_set(&sc->sc_arq_task, ixl_arq, sc);
   1124       1.1  yamaguch 	sc->sc_arq_cons = 0;
   1125       1.1  yamaguch 	sc->sc_arq_prod = 0;
   1126       1.1  yamaguch 
   1127       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &sc->sc_arq,
   1128       1.1  yamaguch 	    sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) {
   1129       1.1  yamaguch 		aprint_error("\n" "%s: unable to allocate arq\n",
   1130       1.1  yamaguch 		    device_xname(self));
   1131       1.1  yamaguch 		goto free_atq;
   1132       1.1  yamaguch 	}
   1133       1.1  yamaguch 
   1134       1.1  yamaguch 	if (!ixl_arq_fill(sc)) {
   1135       1.1  yamaguch 		aprint_error("\n" "%s: unable to fill arq descriptors\n",
   1136       1.1  yamaguch 		    device_xname(self));
   1137       1.1  yamaguch 		goto free_arq;
   1138       1.1  yamaguch 	}
   1139       1.1  yamaguch 
   1140       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   1141       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   1142       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1143       1.1  yamaguch 
   1144       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   1145       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   1146       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1147       1.1  yamaguch 
   1148       1.1  yamaguch 	for (tries = 0; tries < 10; tries++) {
   1149       1.1  yamaguch 		sc->sc_atq_cons = 0;
   1150       1.1  yamaguch 		sc->sc_atq_prod = 0;
   1151       1.1  yamaguch 
   1152       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->atq_head, 0);
   1153       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_head, 0);
   1154       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0);
   1155       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0);
   1156       1.1  yamaguch 
   1157       1.1  yamaguch 		ixl_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE);
   1158       1.1  yamaguch 
   1159       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->atq_bal,
   1160       1.1  yamaguch 		    ixl_dmamem_lo(&sc->sc_atq));
   1161       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->atq_bah,
   1162       1.1  yamaguch 		    ixl_dmamem_hi(&sc->sc_atq));
   1163       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->atq_len,
   1164       1.1  yamaguch 		    sc->sc_aq_regs->atq_len_enable | IXL_AQ_NUM);
   1165       1.1  yamaguch 
   1166       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_bal,
   1167       1.1  yamaguch 		    ixl_dmamem_lo(&sc->sc_arq));
   1168       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_bah,
   1169       1.1  yamaguch 		    ixl_dmamem_hi(&sc->sc_arq));
   1170       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_len,
   1171       1.1  yamaguch 		    sc->sc_aq_regs->arq_len_enable | IXL_AQ_NUM);
   1172       1.1  yamaguch 
   1173       1.1  yamaguch 		rv = ixl_get_version(sc);
   1174       1.1  yamaguch 		if (rv == 0)
   1175       1.1  yamaguch 			break;
   1176       1.1  yamaguch 		if (rv != ETIMEDOUT) {
   1177       1.1  yamaguch 			aprint_error(", unable to get firmware version\n");
   1178       1.1  yamaguch 			goto shutdown;
   1179       1.1  yamaguch 		}
   1180       1.1  yamaguch 
   1181       1.1  yamaguch 		delaymsec(100);
   1182       1.1  yamaguch 	}
   1183       1.1  yamaguch 
   1184       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod);
   1185       1.1  yamaguch 
   1186  1.16.2.1        ad 	if (ixl_dmamem_alloc(sc, &sc->sc_aqbuf, IXL_AQ_BUFLEN, 0) != 0) {
   1187  1.16.2.1        ad 		aprint_error_dev(self, ", unable to allocate nvm buffer\n");
   1188  1.16.2.1        ad 		goto shutdown;
   1189  1.16.2.1        ad 	}
   1190  1.16.2.1        ad 
   1191  1.16.2.1        ad 	ixl_get_nvm_version(sc);
   1192  1.16.2.1        ad 
   1193       1.1  yamaguch 	if (sc->sc_mac_type == I40E_MAC_X722)
   1194       1.1  yamaguch 		sc->sc_nqueue_pairs_device = 128;
   1195       1.1  yamaguch 	else
   1196       1.1  yamaguch 		sc->sc_nqueue_pairs_device = 64;
   1197       1.1  yamaguch 
   1198       1.1  yamaguch 	rv = ixl_get_hw_capabilities(sc);
   1199       1.1  yamaguch 	if (rv != 0) {
   1200       1.1  yamaguch 		aprint_error(", GET HW CAPABILITIES %s\n",
   1201       1.1  yamaguch 		    rv == ETIMEDOUT ? "timeout" : "error");
   1202  1.16.2.1        ad 		goto free_aqbuf;
   1203  1.16.2.1        ad 	}
   1204  1.16.2.1        ad 
   1205  1.16.2.1        ad 	sc->sc_nqueue_pairs_max = MIN((int)sc->sc_nqueue_pairs_device, ncpu);
   1206  1.16.2.1        ad 	if (ixl_param_nqps_limit > 0) {
   1207  1.16.2.1        ad 		sc->sc_nqueue_pairs_max = MIN((int)sc->sc_nqueue_pairs_max,
   1208  1.16.2.1        ad 		    ixl_param_nqps_limit);
   1209       1.1  yamaguch 	}
   1210       1.1  yamaguch 
   1211  1.16.2.1        ad 	sc->sc_nqueue_pairs = sc->sc_nqueue_pairs_max;
   1212  1.16.2.1        ad 	sc->sc_tx_ring_ndescs = ixl_param_tx_ndescs;
   1213  1.16.2.1        ad 	sc->sc_rx_ring_ndescs = ixl_param_rx_ndescs;
   1214       1.1  yamaguch 
   1215       1.1  yamaguch 	KASSERT(IXL_TXRX_PROCESS_UNLIMIT > sc->sc_rx_ring_ndescs);
   1216       1.1  yamaguch 	KASSERT(IXL_TXRX_PROCESS_UNLIMIT > sc->sc_tx_ring_ndescs);
   1217       1.1  yamaguch 
   1218       1.1  yamaguch 	if (ixl_get_mac(sc) != 0) {
   1219       1.1  yamaguch 		/* error printed by ixl_get_mac */
   1220  1.16.2.1        ad 		goto free_aqbuf;
   1221       1.1  yamaguch 	}
   1222       1.1  yamaguch 
   1223       1.1  yamaguch 	aprint_normal("\n");
   1224       1.1  yamaguch 	aprint_naive("\n");
   1225       1.1  yamaguch 
   1226       1.1  yamaguch 	aprint_normal_dev(self, "Ethernet address %s\n",
   1227       1.1  yamaguch 	    ether_sprintf(sc->sc_enaddr));
   1228       1.1  yamaguch 
   1229       1.1  yamaguch 	rv = ixl_pxe_clear(sc);
   1230       1.1  yamaguch 	if (rv != 0) {
   1231       1.1  yamaguch 		aprint_debug_dev(self, "CLEAR PXE MODE %s\n",
   1232       1.1  yamaguch 		    rv == ETIMEDOUT ? "timeout" : "error");
   1233       1.1  yamaguch 	}
   1234       1.1  yamaguch 
   1235       1.1  yamaguch 	ixl_set_filter_control(sc);
   1236       1.1  yamaguch 
   1237       1.1  yamaguch 	if (ixl_hmc(sc) != 0) {
   1238       1.1  yamaguch 		/* error printed by ixl_hmc */
   1239  1.16.2.1        ad 		goto free_aqbuf;
   1240       1.1  yamaguch 	}
   1241       1.1  yamaguch 
   1242       1.1  yamaguch 	if (ixl_lldp_shut(sc) != 0) {
   1243       1.1  yamaguch 		/* error printed by ixl_lldp_shut */
   1244       1.1  yamaguch 		goto free_hmc;
   1245       1.1  yamaguch 	}
   1246       1.1  yamaguch 
   1247       1.1  yamaguch 	if (ixl_phy_mask_ints(sc) != 0) {
   1248       1.1  yamaguch 		/* error printed by ixl_phy_mask_ints */
   1249       1.1  yamaguch 		goto free_hmc;
   1250       1.1  yamaguch 	}
   1251       1.1  yamaguch 
   1252       1.1  yamaguch 	if (ixl_restart_an(sc) != 0) {
   1253       1.1  yamaguch 		/* error printed by ixl_restart_an */
   1254       1.1  yamaguch 		goto free_hmc;
   1255       1.1  yamaguch 	}
   1256       1.1  yamaguch 
   1257       1.1  yamaguch 	if (ixl_get_switch_config(sc) != 0) {
   1258       1.1  yamaguch 		/* error printed by ixl_get_switch_config */
   1259       1.1  yamaguch 		goto free_hmc;
   1260       1.1  yamaguch 	}
   1261       1.1  yamaguch 
   1262       1.1  yamaguch 	if (ixl_get_phy_types(sc, &phy_types) != 0) {
   1263       1.1  yamaguch 		/* error printed by ixl_get_phy_abilities */
   1264       1.1  yamaguch 		goto free_hmc;
   1265       1.1  yamaguch 	}
   1266       1.1  yamaguch 
   1267       1.4  yamaguch 	rv = ixl_get_link_status_poll(sc);
   1268       1.1  yamaguch 	if (rv != 0) {
   1269       1.1  yamaguch 		aprint_error_dev(self, "GET LINK STATUS %s\n",
   1270       1.1  yamaguch 		    rv == ETIMEDOUT ? "timeout" : "error");
   1271       1.1  yamaguch 		goto free_hmc;
   1272       1.1  yamaguch 	}
   1273       1.1  yamaguch 
   1274       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &sc->sc_scratch,
   1275       1.1  yamaguch 	    sizeof(struct ixl_aq_vsi_data), 8) != 0) {
   1276       1.1  yamaguch 		aprint_error_dev(self, "unable to allocate scratch buffer\n");
   1277       1.1  yamaguch 		goto free_hmc;
   1278       1.1  yamaguch 	}
   1279       1.1  yamaguch 
   1280      1.11  yamaguch 	rv = ixl_get_vsi(sc);
   1281      1.11  yamaguch 	if (rv != 0) {
   1282      1.11  yamaguch 		aprint_error_dev(self, "GET VSI %s %d\n",
   1283      1.11  yamaguch 		    rv == ETIMEDOUT ? "timeout" : "error", rv);
   1284       1.1  yamaguch 		goto free_scratch;
   1285       1.1  yamaguch 	}
   1286       1.1  yamaguch 
   1287      1.11  yamaguch 	rv = ixl_set_vsi(sc);
   1288      1.11  yamaguch 	if (rv != 0) {
   1289      1.11  yamaguch 		aprint_error_dev(self, "UPDATE VSI error %s %d\n",
   1290      1.11  yamaguch 		    rv == ETIMEDOUT ? "timeout" : "error", rv);
   1291       1.1  yamaguch 		goto free_scratch;
   1292       1.1  yamaguch 	}
   1293       1.1  yamaguch 
   1294       1.1  yamaguch 	if (ixl_queue_pairs_alloc(sc) != 0) {
   1295       1.1  yamaguch 		/* error printed by ixl_queue_pairs_alloc */
   1296       1.1  yamaguch 		goto free_scratch;
   1297       1.1  yamaguch 	}
   1298       1.1  yamaguch 
   1299       1.1  yamaguch 	if (ixl_setup_interrupts(sc) != 0) {
   1300       1.1  yamaguch 		/* error printed by ixl_setup_interrupts */
   1301       1.1  yamaguch 		goto free_queue_pairs;
   1302       1.1  yamaguch 	}
   1303       1.1  yamaguch 
   1304       1.1  yamaguch 	if (ixl_setup_stats(sc) != 0) {
   1305       1.1  yamaguch 		aprint_error_dev(self, "failed to setup event counters\n");
   1306       1.1  yamaguch 		goto teardown_intrs;
   1307       1.1  yamaguch 	}
   1308       1.1  yamaguch 
   1309       1.1  yamaguch 	if (ixl_setup_sysctls(sc) != 0) {
   1310       1.1  yamaguch 		/* error printed by ixl_setup_sysctls */
   1311       1.1  yamaguch 		goto teardown_stats;
   1312       1.1  yamaguch 	}
   1313       1.1  yamaguch 
   1314       1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_cfg", device_xname(self));
   1315       1.1  yamaguch 	sc->sc_workq = ixl_workq_create(xnamebuf, IXL_WORKQUEUE_PRI,
   1316       1.1  yamaguch 	    IPL_NET, WQ_PERCPU | WQ_MPSAFE);
   1317       1.1  yamaguch 	if (sc->sc_workq == NULL)
   1318       1.1  yamaguch 		goto teardown_sysctls;
   1319       1.1  yamaguch 
   1320       1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_txrx", device_xname(self));
   1321       1.1  yamaguch 	sc->sc_workq_txrx = ixl_workq_create(xnamebuf, IXL_WORKQUEUE_PRI,
   1322       1.1  yamaguch 	    IPL_NET, WQ_PERCPU | WQ_MPSAFE);
   1323       1.1  yamaguch 	if (sc->sc_workq_txrx == NULL)
   1324       1.1  yamaguch 		goto teardown_wqs;
   1325       1.1  yamaguch 
   1326       1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s_atq_cv", device_xname(self));
   1327       1.1  yamaguch 	cv_init(&sc->sc_atq_cv, xnamebuf);
   1328       1.1  yamaguch 
   1329       1.1  yamaguch 	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
   1330       1.1  yamaguch 
   1331       1.1  yamaguch 	ifp->if_softc = sc;
   1332       1.1  yamaguch 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
   1333       1.1  yamaguch 	ifp->if_extflags = IFEF_MPSAFE;
   1334       1.1  yamaguch 	ifp->if_ioctl = ixl_ioctl;
   1335       1.1  yamaguch 	ifp->if_start = ixl_start;
   1336       1.1  yamaguch 	ifp->if_transmit = ixl_transmit;
   1337       1.1  yamaguch 	ifp->if_watchdog = ixl_watchdog;
   1338       1.1  yamaguch 	ifp->if_init = ixl_init;
   1339       1.1  yamaguch 	ifp->if_stop = ixl_stop;
   1340       1.1  yamaguch 	IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_ndescs);
   1341       1.1  yamaguch 	IFQ_SET_READY(&ifp->if_snd);
   1342      1.14  yamaguch 	ifp->if_capabilities |= IXL_IFCAP_RXCSUM;
   1343       1.1  yamaguch #if 0
   1344      1.14  yamaguch 	ifp->if_capabilities |= IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
   1345       1.1  yamaguch #endif
   1346      1.12  yamaguch 	ether_set_vlan_cb(&sc->sc_ec, ixl_vlan_cb);
   1347       1.1  yamaguch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
   1348       1.1  yamaguch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
   1349      1.12  yamaguch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWFILTER;
   1350      1.11  yamaguch 
   1351      1.11  yamaguch 	sc->sc_ec.ec_capenable = sc->sc_ec.ec_capabilities;
   1352      1.12  yamaguch 	/* Disable VLAN_HWFILTER by default */
   1353      1.12  yamaguch 	CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1354      1.12  yamaguch 
   1355      1.11  yamaguch 	sc->sc_cur_ec_capenable = sc->sc_ec.ec_capenable;
   1356       1.1  yamaguch 
   1357       1.1  yamaguch 	sc->sc_ec.ec_ifmedia = &sc->sc_media;
   1358       1.1  yamaguch 	ifmedia_init(&sc->sc_media, IFM_IMASK, ixl_media_change,
   1359       1.1  yamaguch 	    ixl_media_status);
   1360       1.1  yamaguch 
   1361       1.1  yamaguch 	ixl_media_add(sc, phy_types);
   1362       1.1  yamaguch 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
   1363       1.1  yamaguch 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
   1364       1.1  yamaguch 
   1365       1.1  yamaguch 	if_attach(ifp);
   1366       1.1  yamaguch 	if_deferred_start_init(ifp, NULL);
   1367       1.1  yamaguch 	ether_ifattach(ifp, sc->sc_enaddr);
   1368       1.1  yamaguch 	ether_set_ifflags_cb(&sc->sc_ec, ixl_ifflags_cb);
   1369       1.1  yamaguch 
   1370      1.10  yamaguch 	(void)ixl_get_link_status_poll(sc);
   1371       1.4  yamaguch 	ixl_work_set(&sc->sc_link_state_task, ixl_get_link_status, sc);
   1372       1.1  yamaguch 
   1373       1.1  yamaguch 	ixl_config_other_intr(sc);
   1374      1.10  yamaguch 	ixl_enable_other_intr(sc);
   1375       1.1  yamaguch 
   1376      1.12  yamaguch 	/* remove default mac filter and replace it so we can see vlans */
   1377      1.12  yamaguch 	rv = ixl_remove_macvlan(sc, sc->sc_enaddr, 0, 0);
   1378      1.12  yamaguch 	if (rv != ENOENT) {
   1379      1.12  yamaguch 		aprint_debug_dev(self,
   1380      1.12  yamaguch 		    "unable to remove macvlan %u\n", rv);
   1381      1.12  yamaguch 	}
   1382      1.12  yamaguch 	rv = ixl_remove_macvlan(sc, sc->sc_enaddr, 0,
   1383      1.12  yamaguch 	    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   1384      1.12  yamaguch 	if (rv != ENOENT) {
   1385      1.12  yamaguch 		aprint_debug_dev(self,
   1386      1.12  yamaguch 		    "unable to remove macvlan, ignore vlan %u\n", rv);
   1387      1.12  yamaguch 	}
   1388      1.12  yamaguch 
   1389      1.12  yamaguch 	if (ixl_update_macvlan(sc) != 0) {
   1390      1.12  yamaguch 		aprint_debug_dev(self,
   1391      1.12  yamaguch 		    "couldn't enable vlan hardware filter\n");
   1392      1.12  yamaguch 		CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1393      1.12  yamaguch 		CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER);
   1394      1.12  yamaguch 	}
   1395       1.1  yamaguch 
   1396       1.1  yamaguch 	sc->sc_txrx_workqueue = true;
   1397       1.1  yamaguch 	sc->sc_tx_process_limit = IXL_TX_PROCESS_LIMIT;
   1398       1.1  yamaguch 	sc->sc_rx_process_limit = IXL_RX_PROCESS_LIMIT;
   1399       1.1  yamaguch 	sc->sc_tx_intr_process_limit = IXL_TX_INTR_PROCESS_LIMIT;
   1400       1.1  yamaguch 	sc->sc_rx_intr_process_limit = IXL_RX_INTR_PROCESS_LIMIT;
   1401       1.1  yamaguch 
   1402  1.16.2.1        ad 	ixl_stats_update(sc);
   1403  1.16.2.1        ad 	sc->sc_stats_counters.isc_has_offset = true;
   1404  1.16.2.1        ad 	callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval));
   1405  1.16.2.1        ad 
   1406       1.1  yamaguch 	if (pmf_device_register(self, NULL, NULL) != true)
   1407       1.1  yamaguch 		aprint_debug_dev(self, "couldn't establish power handler\n");
   1408       1.1  yamaguch 	sc->sc_attached = true;
   1409       1.1  yamaguch 	return;
   1410       1.1  yamaguch 
   1411       1.1  yamaguch teardown_wqs:
   1412       1.1  yamaguch 	config_finalize_register(self, ixl_workqs_teardown);
   1413       1.1  yamaguch teardown_sysctls:
   1414       1.1  yamaguch 	ixl_teardown_sysctls(sc);
   1415       1.1  yamaguch teardown_stats:
   1416       1.1  yamaguch 	ixl_teardown_stats(sc);
   1417       1.1  yamaguch teardown_intrs:
   1418       1.1  yamaguch 	ixl_teardown_interrupts(sc);
   1419       1.1  yamaguch free_queue_pairs:
   1420       1.1  yamaguch 	ixl_queue_pairs_free(sc);
   1421       1.1  yamaguch free_scratch:
   1422       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_scratch);
   1423       1.1  yamaguch free_hmc:
   1424       1.1  yamaguch 	ixl_hmc_free(sc);
   1425  1.16.2.1        ad free_aqbuf:
   1426  1.16.2.1        ad 	ixl_dmamem_free(sc, &sc->sc_aqbuf);
   1427       1.1  yamaguch shutdown:
   1428       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_head, 0);
   1429       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_head, 0);
   1430       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0);
   1431       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0);
   1432       1.1  yamaguch 
   1433       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_bal, 0);
   1434       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_bah, 0);
   1435       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_len, 0);
   1436       1.1  yamaguch 
   1437       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_bal, 0);
   1438       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_bah, 0);
   1439       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_len, 0);
   1440       1.1  yamaguch 
   1441       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   1442       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   1443       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   1444       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   1445       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   1446       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1447       1.1  yamaguch 
   1448       1.1  yamaguch 	ixl_arq_unfill(sc);
   1449       1.1  yamaguch free_arq:
   1450       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_arq);
   1451       1.1  yamaguch free_atq:
   1452       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_atq);
   1453       1.1  yamaguch unmap:
   1454       1.1  yamaguch 	mutex_destroy(&sc->sc_atq_lock);
   1455       1.1  yamaguch 	bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
   1456       1.1  yamaguch 	mutex_destroy(&sc->sc_cfg_lock);
   1457       1.1  yamaguch 	sc->sc_mems = 0;
   1458       1.1  yamaguch 
   1459       1.1  yamaguch 	sc->sc_attached = false;
   1460       1.1  yamaguch }
   1461       1.1  yamaguch 
   1462       1.1  yamaguch static int
   1463       1.1  yamaguch ixl_detach(device_t self, int flags)
   1464       1.1  yamaguch {
   1465       1.1  yamaguch 	struct ixl_softc *sc = device_private(self);
   1466       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1467       1.1  yamaguch 
   1468       1.1  yamaguch 	if (!sc->sc_attached)
   1469       1.1  yamaguch 		return 0;
   1470       1.1  yamaguch 
   1471       1.1  yamaguch 	ixl_stop(ifp, 1);
   1472       1.1  yamaguch 
   1473      1.10  yamaguch 	ixl_disable_other_intr(sc);
   1474      1.10  yamaguch 
   1475  1.16.2.1        ad 	callout_stop(&sc->sc_stats_callout);
   1476  1.16.2.1        ad 	ixl_work_wait(sc->sc_workq, &sc->sc_stats_task);
   1477  1.16.2.1        ad 
   1478      1.10  yamaguch 	/* wait for ATQ handler */
   1479      1.10  yamaguch 	mutex_enter(&sc->sc_atq_lock);
   1480      1.10  yamaguch 	mutex_exit(&sc->sc_atq_lock);
   1481      1.10  yamaguch 
   1482      1.10  yamaguch 	ixl_work_wait(sc->sc_workq, &sc->sc_arq_task);
   1483      1.10  yamaguch 	ixl_work_wait(sc->sc_workq, &sc->sc_link_state_task);
   1484      1.10  yamaguch 
   1485       1.1  yamaguch 	if (sc->sc_workq != NULL) {
   1486       1.1  yamaguch 		ixl_workq_destroy(sc->sc_workq);
   1487       1.1  yamaguch 		sc->sc_workq = NULL;
   1488       1.1  yamaguch 	}
   1489       1.1  yamaguch 
   1490       1.1  yamaguch 	if (sc->sc_workq_txrx != NULL) {
   1491       1.1  yamaguch 		ixl_workq_destroy(sc->sc_workq_txrx);
   1492       1.1  yamaguch 		sc->sc_workq_txrx = NULL;
   1493       1.1  yamaguch 	}
   1494       1.1  yamaguch 
   1495       1.1  yamaguch 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
   1496       1.1  yamaguch 	ether_ifdetach(ifp);
   1497       1.1  yamaguch 	if_detach(ifp);
   1498       1.1  yamaguch 
   1499       1.1  yamaguch 	ixl_teardown_interrupts(sc);
   1500       1.1  yamaguch 	ixl_teardown_stats(sc);
   1501      1.15  yamaguch 	ixl_teardown_sysctls(sc);
   1502       1.1  yamaguch 
   1503       1.1  yamaguch 	ixl_queue_pairs_free(sc);
   1504       1.1  yamaguch 
   1505       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_scratch);
   1506       1.1  yamaguch 	ixl_hmc_free(sc);
   1507       1.1  yamaguch 
   1508       1.1  yamaguch 	/* shutdown */
   1509       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_head, 0);
   1510       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_head, 0);
   1511       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0);
   1512       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0);
   1513       1.1  yamaguch 
   1514       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_bal, 0);
   1515       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_bah, 0);
   1516       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_len, 0);
   1517       1.1  yamaguch 
   1518       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_bal, 0);
   1519       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_bah, 0);
   1520       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->arq_len, 0);
   1521       1.1  yamaguch 
   1522       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   1523       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   1524       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   1525       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   1526       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   1527       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1528       1.1  yamaguch 
   1529       1.1  yamaguch 	ixl_arq_unfill(sc);
   1530       1.1  yamaguch 
   1531       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_arq);
   1532       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_atq);
   1533  1.16.2.1        ad 	ixl_dmamem_free(sc, &sc->sc_aqbuf);
   1534       1.1  yamaguch 
   1535       1.1  yamaguch 	cv_destroy(&sc->sc_atq_cv);
   1536       1.1  yamaguch 	mutex_destroy(&sc->sc_atq_lock);
   1537       1.1  yamaguch 
   1538       1.1  yamaguch 	if (sc->sc_mems != 0) {
   1539       1.1  yamaguch 		bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
   1540       1.1  yamaguch 		sc->sc_mems = 0;
   1541       1.1  yamaguch 	}
   1542       1.1  yamaguch 
   1543       1.1  yamaguch 	mutex_destroy(&sc->sc_cfg_lock);
   1544       1.1  yamaguch 
   1545       1.1  yamaguch 	return 0;
   1546       1.1  yamaguch }
   1547       1.1  yamaguch 
   1548       1.1  yamaguch static int
   1549       1.1  yamaguch ixl_workqs_teardown(device_t self)
   1550       1.1  yamaguch {
   1551       1.1  yamaguch 	struct ixl_softc *sc = device_private(self);
   1552       1.1  yamaguch 
   1553       1.1  yamaguch 	if (sc->sc_workq != NULL) {
   1554       1.1  yamaguch 		ixl_workq_destroy(sc->sc_workq);
   1555       1.1  yamaguch 		sc->sc_workq = NULL;
   1556       1.1  yamaguch 	}
   1557       1.1  yamaguch 
   1558       1.1  yamaguch 	if (sc->sc_workq_txrx != NULL) {
   1559       1.1  yamaguch 		ixl_workq_destroy(sc->sc_workq_txrx);
   1560       1.1  yamaguch 		sc->sc_workq_txrx = NULL;
   1561       1.1  yamaguch 	}
   1562       1.1  yamaguch 
   1563       1.1  yamaguch 	return 0;
   1564       1.1  yamaguch }
   1565       1.1  yamaguch 
   1566      1.12  yamaguch static int
   1567      1.12  yamaguch ixl_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
   1568      1.12  yamaguch {
   1569      1.12  yamaguch 	struct ifnet *ifp = &ec->ec_if;
   1570      1.12  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   1571      1.12  yamaguch 	int rv;
   1572      1.12  yamaguch 
   1573      1.12  yamaguch 	if (!ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER)) {
   1574      1.12  yamaguch 		return 0;
   1575      1.12  yamaguch 	}
   1576      1.12  yamaguch 
   1577      1.12  yamaguch 	if (set) {
   1578      1.12  yamaguch 		rv = ixl_add_macvlan(sc, sc->sc_enaddr, vid,
   1579      1.12  yamaguch 		    IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   1580      1.12  yamaguch 		if (rv == 0) {
   1581      1.12  yamaguch 			rv = ixl_add_macvlan(sc, etherbroadcastaddr,
   1582      1.12  yamaguch 			    vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   1583      1.12  yamaguch 		}
   1584      1.12  yamaguch 	} else {
   1585      1.12  yamaguch 		rv = ixl_remove_macvlan(sc, sc->sc_enaddr, vid,
   1586      1.12  yamaguch 		    IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   1587      1.12  yamaguch 		(void)ixl_remove_macvlan(sc, etherbroadcastaddr, vid,
   1588      1.12  yamaguch 		    IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   1589      1.12  yamaguch 	}
   1590      1.12  yamaguch 
   1591      1.12  yamaguch 	return rv;
   1592      1.12  yamaguch }
   1593      1.12  yamaguch 
   1594       1.1  yamaguch static void
   1595       1.1  yamaguch ixl_media_add(struct ixl_softc *sc, uint64_t phy_types)
   1596       1.1  yamaguch {
   1597       1.1  yamaguch 	struct ifmedia *ifm = &sc->sc_media;
   1598       1.1  yamaguch 	const struct ixl_phy_type *itype;
   1599       1.1  yamaguch 	unsigned int i;
   1600       1.1  yamaguch 
   1601       1.1  yamaguch 	for (i = 0; i < __arraycount(ixl_phy_type_map); i++) {
   1602       1.1  yamaguch 		itype = &ixl_phy_type_map[i];
   1603       1.1  yamaguch 
   1604       1.1  yamaguch 		if (ISSET(phy_types, itype->phy_type)) {
   1605       1.1  yamaguch 			ifmedia_add(ifm,
   1606       1.1  yamaguch 			    IFM_ETHER | IFM_FDX | itype->ifm_type, 0, NULL);
   1607       1.1  yamaguch 
   1608       1.1  yamaguch 			if (itype->ifm_type == IFM_100_TX) {
   1609       1.1  yamaguch 				ifmedia_add(ifm, IFM_ETHER | itype->ifm_type,
   1610       1.1  yamaguch 				    0, NULL);
   1611       1.1  yamaguch 			}
   1612       1.1  yamaguch 		}
   1613       1.1  yamaguch 	}
   1614       1.1  yamaguch }
   1615       1.1  yamaguch 
   1616       1.1  yamaguch static void
   1617       1.1  yamaguch ixl_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
   1618       1.1  yamaguch {
   1619       1.1  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   1620       1.1  yamaguch 
   1621       1.1  yamaguch 	ifmr->ifm_status = sc->sc_media_status;
   1622       1.1  yamaguch 	ifmr->ifm_active = sc->sc_media_active;
   1623       1.1  yamaguch 
   1624       1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   1625       1.1  yamaguch 	if (ifp->if_link_state == LINK_STATE_UP)
   1626       1.1  yamaguch 		SET(ifmr->ifm_status, IFM_ACTIVE);
   1627       1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   1628       1.1  yamaguch }
   1629       1.1  yamaguch 
   1630       1.1  yamaguch static int
   1631       1.1  yamaguch ixl_media_change(struct ifnet *ifp)
   1632       1.1  yamaguch {
   1633       1.1  yamaguch 
   1634       1.1  yamaguch 	return 0;
   1635       1.1  yamaguch }
   1636       1.1  yamaguch 
   1637       1.1  yamaguch static void
   1638       1.1  yamaguch ixl_watchdog(struct ifnet *ifp)
   1639       1.1  yamaguch {
   1640       1.1  yamaguch 
   1641       1.1  yamaguch }
   1642       1.1  yamaguch 
   1643       1.1  yamaguch static void
   1644       1.1  yamaguch ixl_del_all_multiaddr(struct ixl_softc *sc)
   1645       1.1  yamaguch {
   1646       1.1  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   1647       1.1  yamaguch 	struct ether_multi *enm;
   1648       1.1  yamaguch 	struct ether_multistep step;
   1649       1.1  yamaguch 
   1650       1.1  yamaguch 	ETHER_LOCK(ec);
   1651       1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1652       1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1653       1.1  yamaguch 		ixl_remove_macvlan(sc, enm->enm_addrlo, 0,
   1654       1.1  yamaguch 		    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   1655       1.1  yamaguch 	}
   1656       1.1  yamaguch 	ETHER_UNLOCK(ec);
   1657       1.1  yamaguch }
   1658       1.1  yamaguch 
   1659       1.1  yamaguch static int
   1660       1.1  yamaguch ixl_add_multi(struct ixl_softc *sc, uint8_t *addrlo, uint8_t *addrhi)
   1661       1.1  yamaguch {
   1662       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1663       1.1  yamaguch 	int rv;
   1664       1.1  yamaguch 
   1665       1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_ALLMULTI))
   1666       1.1  yamaguch 		return 0;
   1667       1.1  yamaguch 
   1668       1.1  yamaguch 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) {
   1669       1.1  yamaguch 		ixl_del_all_multiaddr(sc);
   1670       1.1  yamaguch 		SET(ifp->if_flags, IFF_ALLMULTI);
   1671       1.8  yamaguch 		return ENETRESET;
   1672       1.1  yamaguch 	}
   1673       1.1  yamaguch 
   1674      1.12  yamaguch 	/* multicast address can not use VLAN HWFILTER */
   1675       1.1  yamaguch 	rv = ixl_add_macvlan(sc, addrlo, 0,
   1676       1.1  yamaguch 	    IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN);
   1677       1.1  yamaguch 
   1678       1.7  yamaguch 	if (rv == ENOSPC) {
   1679       1.1  yamaguch 		ixl_del_all_multiaddr(sc);
   1680       1.1  yamaguch 		SET(ifp->if_flags, IFF_ALLMULTI);
   1681       1.8  yamaguch 		return ENETRESET;
   1682       1.1  yamaguch 	}
   1683       1.1  yamaguch 
   1684       1.7  yamaguch 	return rv;
   1685       1.1  yamaguch }
   1686       1.1  yamaguch 
   1687       1.8  yamaguch static int
   1688       1.1  yamaguch ixl_del_multi(struct ixl_softc *sc, uint8_t *addrlo, uint8_t *addrhi)
   1689       1.1  yamaguch {
   1690       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1691       1.1  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   1692       1.1  yamaguch 	struct ether_multi *enm, *enm_last;
   1693       1.1  yamaguch 	struct ether_multistep step;
   1694       1.8  yamaguch 	int error, rv = 0;
   1695       1.1  yamaguch 
   1696       1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) {
   1697       1.1  yamaguch 		ixl_remove_macvlan(sc, addrlo, 0,
   1698       1.1  yamaguch 		    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   1699       1.8  yamaguch 		return 0;
   1700       1.1  yamaguch 	}
   1701       1.1  yamaguch 
   1702       1.1  yamaguch 	ETHER_LOCK(ec);
   1703       1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1704       1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1705       1.1  yamaguch 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1706       1.1  yamaguch 		    ETHER_ADDR_LEN) != 0) {
   1707       1.8  yamaguch 			goto out;
   1708       1.1  yamaguch 		}
   1709       1.1  yamaguch 	}
   1710       1.1  yamaguch 
   1711       1.1  yamaguch 	for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1712       1.1  yamaguch 	    ETHER_NEXT_MULTI(step, enm)) {
   1713       1.8  yamaguch 		error = ixl_add_macvlan(sc, enm->enm_addrlo, 0,
   1714       1.1  yamaguch 		    IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN);
   1715       1.8  yamaguch 		if (error != 0)
   1716       1.1  yamaguch 			break;
   1717       1.1  yamaguch 	}
   1718       1.1  yamaguch 
   1719       1.1  yamaguch 	if (enm != NULL) {
   1720       1.1  yamaguch 		enm_last = enm;
   1721       1.1  yamaguch 		for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL;
   1722       1.1  yamaguch 		    ETHER_NEXT_MULTI(step, enm)) {
   1723       1.1  yamaguch 			if (enm == enm_last)
   1724       1.1  yamaguch 				break;
   1725       1.1  yamaguch 
   1726       1.1  yamaguch 			ixl_remove_macvlan(sc, enm->enm_addrlo, 0,
   1727       1.1  yamaguch 			    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   1728       1.1  yamaguch 		}
   1729       1.1  yamaguch 	} else {
   1730       1.1  yamaguch 		CLR(ifp->if_flags, IFF_ALLMULTI);
   1731       1.8  yamaguch 		rv = ENETRESET;
   1732       1.1  yamaguch 	}
   1733       1.1  yamaguch 
   1734       1.8  yamaguch out:
   1735       1.1  yamaguch 	ETHER_UNLOCK(ec);
   1736       1.8  yamaguch 	return rv;
   1737       1.1  yamaguch }
   1738       1.1  yamaguch 
   1739       1.1  yamaguch static int
   1740       1.1  yamaguch ixl_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1741       1.1  yamaguch {
   1742       1.1  yamaguch 	struct ifreq *ifr = (struct ifreq *)data;
   1743       1.1  yamaguch 	struct ixl_softc *sc = (struct ixl_softc *)ifp->if_softc;
   1744       1.1  yamaguch 	struct ixl_tx_ring *txr;
   1745       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   1746       1.1  yamaguch 	const struct sockaddr *sa;
   1747       1.1  yamaguch 	uint8_t addrhi[ETHER_ADDR_LEN], addrlo[ETHER_ADDR_LEN];
   1748       1.1  yamaguch 	int s, error = 0;
   1749       1.1  yamaguch 	unsigned int i;
   1750       1.1  yamaguch 
   1751       1.1  yamaguch 	switch (cmd) {
   1752       1.1  yamaguch 	case SIOCADDMULTI:
   1753       1.1  yamaguch 		sa = ifreq_getaddr(SIOCADDMULTI, ifr);
   1754       1.1  yamaguch 		if (ether_addmulti(sa, &sc->sc_ec) == ENETRESET) {
   1755       1.1  yamaguch 			error = ether_multiaddr(sa, addrlo, addrhi);
   1756       1.1  yamaguch 			if (error != 0)
   1757       1.1  yamaguch 				return error;
   1758       1.1  yamaguch 
   1759       1.8  yamaguch 			error = ixl_add_multi(sc, addrlo, addrhi);
   1760       1.8  yamaguch 			if (error != 0 && error != ENETRESET) {
   1761       1.1  yamaguch 				ether_delmulti(sa, &sc->sc_ec);
   1762       1.1  yamaguch 				error = EIO;
   1763       1.1  yamaguch 			}
   1764       1.1  yamaguch 		}
   1765       1.1  yamaguch 		break;
   1766       1.1  yamaguch 
   1767       1.1  yamaguch 	case SIOCDELMULTI:
   1768       1.1  yamaguch 		sa = ifreq_getaddr(SIOCDELMULTI, ifr);
   1769       1.1  yamaguch 		if (ether_delmulti(sa, &sc->sc_ec) == ENETRESET) {
   1770       1.1  yamaguch 			error = ether_multiaddr(sa, addrlo, addrhi);
   1771       1.1  yamaguch 			if (error != 0)
   1772       1.1  yamaguch 				return error;
   1773       1.1  yamaguch 
   1774       1.8  yamaguch 			error = ixl_del_multi(sc, addrlo, addrhi);
   1775       1.1  yamaguch 		}
   1776       1.1  yamaguch 		break;
   1777       1.1  yamaguch 
   1778       1.1  yamaguch 	case SIOCGIFDATA:
   1779       1.1  yamaguch 	case SIOCZIFDATA:
   1780       1.1  yamaguch 		ifp->if_ipackets = 0;
   1781       1.1  yamaguch 		ifp->if_ibytes = 0;
   1782       1.1  yamaguch 		ifp->if_iqdrops = 0;
   1783       1.1  yamaguch 		ifp->if_ierrors = 0;
   1784       1.1  yamaguch 		ifp->if_opackets = 0;
   1785       1.1  yamaguch 		ifp->if_obytes = 0;
   1786       1.1  yamaguch 		ifp->if_omcasts = 0;
   1787       1.1  yamaguch 
   1788       1.1  yamaguch 		for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   1789       1.1  yamaguch 			txr = sc->sc_qps[i].qp_txr;
   1790       1.1  yamaguch 			rxr = sc->sc_qps[i].qp_rxr;
   1791       1.1  yamaguch 
   1792       1.1  yamaguch 			mutex_enter(&rxr->rxr_lock);
   1793       1.1  yamaguch 			ifp->if_ipackets += rxr->rxr_ipackets;
   1794       1.1  yamaguch 			ifp->if_ibytes += rxr->rxr_ibytes;
   1795       1.1  yamaguch 			ifp->if_iqdrops += rxr->rxr_iqdrops;
   1796       1.1  yamaguch 			ifp->if_ierrors += rxr->rxr_ierrors;
   1797       1.1  yamaguch 			if (cmd == SIOCZIFDATA) {
   1798       1.1  yamaguch 				rxr->rxr_ipackets = 0;
   1799       1.1  yamaguch 				rxr->rxr_ibytes = 0;
   1800       1.1  yamaguch 				rxr->rxr_iqdrops = 0;
   1801       1.1  yamaguch 				rxr->rxr_ierrors = 0;
   1802       1.1  yamaguch 			}
   1803       1.1  yamaguch 			mutex_exit(&rxr->rxr_lock);
   1804       1.1  yamaguch 
   1805       1.1  yamaguch 			mutex_enter(&txr->txr_lock);
   1806       1.1  yamaguch 			ifp->if_opackets += txr->txr_opackets;
   1807  1.16.2.1        ad 			ifp->if_obytes += txr->txr_obytes;
   1808       1.1  yamaguch 			ifp->if_omcasts += txr->txr_omcasts;
   1809       1.1  yamaguch 			if (cmd == SIOCZIFDATA) {
   1810       1.1  yamaguch 				txr->txr_opackets = 0;
   1811  1.16.2.1        ad 				txr->txr_obytes = 0;
   1812       1.1  yamaguch 				txr->txr_omcasts = 0;
   1813       1.1  yamaguch 			}
   1814       1.1  yamaguch 			mutex_exit(&txr->txr_lock);
   1815       1.1  yamaguch 		}
   1816       1.1  yamaguch 		/* FALLTHROUGH */
   1817       1.1  yamaguch 	default:
   1818       1.1  yamaguch 		s = splnet();
   1819       1.1  yamaguch 		error = ether_ioctl(ifp, cmd, data);
   1820       1.1  yamaguch 		splx(s);
   1821       1.1  yamaguch 	}
   1822       1.1  yamaguch 
   1823       1.1  yamaguch 	if (error == ENETRESET)
   1824       1.1  yamaguch 		error = ixl_iff(sc);
   1825       1.1  yamaguch 
   1826       1.1  yamaguch 	return error;
   1827       1.1  yamaguch }
   1828       1.1  yamaguch 
   1829       1.1  yamaguch static enum i40e_mac_type
   1830       1.1  yamaguch ixl_mactype(pci_product_id_t id)
   1831       1.1  yamaguch {
   1832       1.1  yamaguch 
   1833       1.1  yamaguch 	switch (id) {
   1834       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_SFP:
   1835       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_KX_B:
   1836       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_KX_C:
   1837       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_QSFP_A:
   1838       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_QSFP_B:
   1839       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_QSFP_C:
   1840       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X710_10G_T:
   1841       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_20G_BP_1:
   1842       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XL710_20G_BP_2:
   1843       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X710_T4_10G:
   1844       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XXV710_25G_BP:
   1845       1.1  yamaguch 	case PCI_PRODUCT_INTEL_XXV710_25G_SFP28:
   1846       1.1  yamaguch 		return I40E_MAC_XL710;
   1847       1.1  yamaguch 
   1848       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_KX:
   1849       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_QSFP:
   1850       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_SFP:
   1851       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_1G_BASET:
   1852       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_10G_BASET:
   1853       1.1  yamaguch 	case PCI_PRODUCT_INTEL_X722_I_SFP:
   1854       1.1  yamaguch 		return I40E_MAC_X722;
   1855       1.1  yamaguch 	}
   1856       1.1  yamaguch 
   1857       1.1  yamaguch 	return I40E_MAC_GENERIC;
   1858       1.1  yamaguch }
   1859       1.1  yamaguch 
   1860       1.1  yamaguch static inline void *
   1861       1.1  yamaguch ixl_hmc_kva(struct ixl_softc *sc, enum ixl_hmc_types type, unsigned int i)
   1862       1.1  yamaguch {
   1863       1.1  yamaguch 	uint8_t *kva = IXL_DMA_KVA(&sc->sc_hmc_pd);
   1864       1.1  yamaguch 	struct ixl_hmc_entry *e = &sc->sc_hmc_entries[type];
   1865       1.1  yamaguch 
   1866       1.1  yamaguch 	if (i >= e->hmc_count)
   1867       1.1  yamaguch 		return NULL;
   1868       1.1  yamaguch 
   1869       1.1  yamaguch 	kva += e->hmc_base;
   1870       1.1  yamaguch 	kva += i * e->hmc_size;
   1871       1.1  yamaguch 
   1872       1.1  yamaguch 	return kva;
   1873       1.1  yamaguch }
   1874       1.1  yamaguch 
   1875       1.1  yamaguch static inline size_t
   1876       1.1  yamaguch ixl_hmc_len(struct ixl_softc *sc, enum ixl_hmc_types type)
   1877       1.1  yamaguch {
   1878       1.1  yamaguch 	struct ixl_hmc_entry *e = &sc->sc_hmc_entries[type];
   1879       1.1  yamaguch 
   1880       1.1  yamaguch 	return e->hmc_size;
   1881       1.1  yamaguch }
   1882       1.1  yamaguch 
   1883       1.1  yamaguch static void
   1884       1.1  yamaguch ixl_enable_queue_intr(struct ixl_softc *sc, struct ixl_queue_pair *qp)
   1885       1.1  yamaguch {
   1886       1.1  yamaguch 	struct ixl_rx_ring *rxr = qp->qp_rxr;
   1887       1.1  yamaguch 
   1888       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_DYN_CTLN(rxr->rxr_qid),
   1889       1.1  yamaguch 	    I40E_PFINT_DYN_CTLN_INTENA_MASK |
   1890       1.1  yamaguch 	    I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
   1891       1.1  yamaguch 	    (IXL_NOITR << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT));
   1892       1.1  yamaguch 	ixl_flush(sc);
   1893       1.1  yamaguch }
   1894       1.1  yamaguch 
   1895       1.1  yamaguch static void
   1896       1.1  yamaguch ixl_disable_queue_intr(struct ixl_softc *sc, struct ixl_queue_pair *qp)
   1897       1.1  yamaguch {
   1898       1.1  yamaguch 	struct ixl_rx_ring *rxr = qp->qp_rxr;
   1899       1.1  yamaguch 
   1900       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_DYN_CTLN(rxr->rxr_qid),
   1901       1.1  yamaguch 	    (IXL_NOITR << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT));
   1902       1.1  yamaguch 	ixl_flush(sc);
   1903       1.1  yamaguch }
   1904       1.1  yamaguch 
   1905       1.1  yamaguch static void
   1906       1.1  yamaguch ixl_enable_other_intr(struct ixl_softc *sc)
   1907       1.1  yamaguch {
   1908       1.1  yamaguch 
   1909       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_DYN_CTL0,
   1910       1.1  yamaguch 	    I40E_PFINT_DYN_CTL0_INTENA_MASK |
   1911       1.1  yamaguch 	    I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
   1912       1.1  yamaguch 	    (IXL_NOITR << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT));
   1913       1.1  yamaguch 	ixl_flush(sc);
   1914       1.1  yamaguch }
   1915       1.1  yamaguch 
   1916       1.1  yamaguch static void
   1917       1.1  yamaguch ixl_disable_other_intr(struct ixl_softc *sc)
   1918       1.1  yamaguch {
   1919       1.1  yamaguch 
   1920       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_DYN_CTL0,
   1921       1.1  yamaguch 	    (IXL_NOITR << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT));
   1922       1.1  yamaguch 	ixl_flush(sc);
   1923       1.1  yamaguch }
   1924       1.1  yamaguch 
   1925       1.1  yamaguch static int
   1926       1.1  yamaguch ixl_reinit(struct ixl_softc *sc)
   1927       1.1  yamaguch {
   1928       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   1929       1.1  yamaguch 	struct ixl_tx_ring *txr;
   1930       1.1  yamaguch 	unsigned int i;
   1931       1.1  yamaguch 	uint32_t reg;
   1932       1.1  yamaguch 
   1933       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   1934       1.1  yamaguch 
   1935      1.11  yamaguch 	if (ixl_get_vsi(sc) != 0)
   1936      1.11  yamaguch 		return EIO;
   1937      1.11  yamaguch 
   1938      1.11  yamaguch 	if (ixl_set_vsi(sc) != 0)
   1939      1.11  yamaguch 		return EIO;
   1940      1.11  yamaguch 
   1941       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1942       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   1943       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   1944       1.1  yamaguch 
   1945       1.1  yamaguch 		txr->txr_cons = txr->txr_prod = 0;
   1946       1.1  yamaguch 		rxr->rxr_cons = rxr->rxr_prod = 0;
   1947       1.1  yamaguch 
   1948       1.1  yamaguch 		ixl_txr_config(sc, txr);
   1949       1.1  yamaguch 		ixl_rxr_config(sc, rxr);
   1950       1.1  yamaguch 	}
   1951       1.1  yamaguch 
   1952       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd),
   1953       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_PREWRITE);
   1954       1.1  yamaguch 
   1955       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   1956       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   1957       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   1958       1.1  yamaguch 
   1959       1.1  yamaguch 		ixl_wr(sc, I40E_QTX_CTL(i), I40E_QTX_CTL_PF_QUEUE |
   1960       1.1  yamaguch 		    (sc->sc_pf_id << I40E_QTX_CTL_PF_INDX_SHIFT));
   1961       1.1  yamaguch 		ixl_flush(sc);
   1962       1.1  yamaguch 
   1963       1.1  yamaguch 		ixl_wr(sc, txr->txr_tail, txr->txr_prod);
   1964       1.1  yamaguch 		ixl_wr(sc, rxr->rxr_tail, rxr->rxr_prod);
   1965       1.1  yamaguch 
   1966       1.1  yamaguch 		/* ixl_rxfill() needs lock held */
   1967       1.1  yamaguch 		mutex_enter(&rxr->rxr_lock);
   1968       1.1  yamaguch 		ixl_rxfill(sc, rxr);
   1969       1.1  yamaguch 		mutex_exit(&rxr->rxr_lock);
   1970       1.1  yamaguch 
   1971       1.1  yamaguch 		reg = ixl_rd(sc, I40E_QRX_ENA(i));
   1972       1.1  yamaguch 		SET(reg, I40E_QRX_ENA_QENA_REQ_MASK);
   1973       1.1  yamaguch 		ixl_wr(sc, I40E_QRX_ENA(i), reg);
   1974       1.1  yamaguch 		if (ixl_rxr_enabled(sc, rxr) != 0)
   1975       1.1  yamaguch 			goto stop;
   1976       1.1  yamaguch 
   1977       1.1  yamaguch 		ixl_txr_qdis(sc, txr, 1);
   1978       1.1  yamaguch 
   1979       1.1  yamaguch 		reg = ixl_rd(sc, I40E_QTX_ENA(i));
   1980       1.1  yamaguch 		SET(reg, I40E_QTX_ENA_QENA_REQ_MASK);
   1981       1.1  yamaguch 		ixl_wr(sc, I40E_QTX_ENA(i), reg);
   1982       1.1  yamaguch 
   1983       1.1  yamaguch 		if (ixl_txr_enabled(sc, txr) != 0)
   1984       1.1  yamaguch 			goto stop;
   1985       1.1  yamaguch 	}
   1986       1.1  yamaguch 
   1987       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd),
   1988       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_POSTWRITE);
   1989       1.1  yamaguch 
   1990       1.1  yamaguch 	return 0;
   1991       1.1  yamaguch 
   1992       1.1  yamaguch stop:
   1993       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd),
   1994       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_POSTWRITE);
   1995       1.1  yamaguch 
   1996       1.1  yamaguch 	return ETIMEDOUT;
   1997       1.1  yamaguch }
   1998       1.1  yamaguch 
   1999       1.1  yamaguch static int
   2000       1.1  yamaguch ixl_init_locked(struct ixl_softc *sc)
   2001       1.1  yamaguch {
   2002       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2003       1.1  yamaguch 	unsigned int i;
   2004      1.12  yamaguch 	int error, eccap_change;
   2005       1.1  yamaguch 
   2006       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   2007       1.1  yamaguch 
   2008      1.11  yamaguch 	if (ISSET(ifp->if_flags, IFF_RUNNING))
   2009      1.11  yamaguch 		ixl_stop_locked(sc);
   2010      1.11  yamaguch 
   2011       1.1  yamaguch 	if (sc->sc_dead) {
   2012       1.1  yamaguch 		return ENXIO;
   2013       1.1  yamaguch 	}
   2014       1.1  yamaguch 
   2015      1.12  yamaguch 	eccap_change = sc->sc_ec.ec_capenable ^ sc->sc_cur_ec_capenable;
   2016      1.12  yamaguch 	if (ISSET(eccap_change, ETHERCAP_VLAN_HWTAGGING))
   2017      1.12  yamaguch 		sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWTAGGING;
   2018      1.12  yamaguch 
   2019      1.12  yamaguch 	if (ISSET(eccap_change, ETHERCAP_VLAN_HWFILTER)) {
   2020      1.12  yamaguch 		if (ixl_update_macvlan(sc) == 0) {
   2021      1.12  yamaguch 			sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWFILTER;
   2022      1.12  yamaguch 		} else {
   2023      1.12  yamaguch 			CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER);
   2024      1.12  yamaguch 			CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER);
   2025      1.12  yamaguch 		}
   2026      1.12  yamaguch 	}
   2027      1.11  yamaguch 
   2028       1.1  yamaguch 	if (sc->sc_intrtype != PCI_INTR_TYPE_MSIX)
   2029       1.1  yamaguch 		sc->sc_nqueue_pairs = 1;
   2030       1.1  yamaguch 	else
   2031       1.1  yamaguch 		sc->sc_nqueue_pairs = sc->sc_nqueue_pairs_max;
   2032       1.1  yamaguch 
   2033       1.1  yamaguch 	error = ixl_reinit(sc);
   2034       1.1  yamaguch 	if (error) {
   2035       1.1  yamaguch 		ixl_stop_locked(sc);
   2036       1.1  yamaguch 		return error;
   2037       1.1  yamaguch 	}
   2038       1.1  yamaguch 
   2039       1.1  yamaguch 	SET(ifp->if_flags, IFF_RUNNING);
   2040       1.1  yamaguch 	CLR(ifp->if_flags, IFF_OACTIVE);
   2041       1.4  yamaguch 
   2042      1.10  yamaguch 	(void)ixl_get_link_status(sc);
   2043       1.1  yamaguch 
   2044       1.1  yamaguch 	ixl_config_rss(sc);
   2045       1.1  yamaguch 	ixl_config_queue_intr(sc);
   2046       1.1  yamaguch 
   2047       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   2048       1.1  yamaguch 		ixl_enable_queue_intr(sc, &sc->sc_qps[i]);
   2049       1.1  yamaguch 	}
   2050       1.1  yamaguch 
   2051       1.1  yamaguch 	error = ixl_iff(sc);
   2052       1.1  yamaguch 	if (error) {
   2053       1.1  yamaguch 		ixl_stop_locked(sc);
   2054       1.1  yamaguch 		return error;
   2055       1.1  yamaguch 	}
   2056       1.1  yamaguch 
   2057       1.1  yamaguch 	return 0;
   2058       1.1  yamaguch }
   2059       1.1  yamaguch 
   2060       1.1  yamaguch static int
   2061       1.1  yamaguch ixl_init(struct ifnet *ifp)
   2062       1.1  yamaguch {
   2063       1.1  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   2064       1.1  yamaguch 	int error;
   2065       1.1  yamaguch 
   2066       1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   2067       1.1  yamaguch 	error = ixl_init_locked(sc);
   2068       1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   2069       1.1  yamaguch 
   2070       1.1  yamaguch 	return error;
   2071       1.1  yamaguch }
   2072       1.1  yamaguch 
   2073       1.1  yamaguch static int
   2074       1.1  yamaguch ixl_iff(struct ixl_softc *sc)
   2075       1.1  yamaguch {
   2076       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2077       1.1  yamaguch 	struct ixl_atq iatq;
   2078       1.1  yamaguch 	struct ixl_aq_desc *iaq;
   2079       1.1  yamaguch 	struct ixl_aq_vsi_promisc_param *param;
   2080      1.12  yamaguch 	uint16_t flag_add, flag_del;
   2081       1.1  yamaguch 	int error;
   2082       1.1  yamaguch 
   2083       1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
   2084       1.1  yamaguch 		return 0;
   2085       1.1  yamaguch 
   2086       1.1  yamaguch 	memset(&iatq, 0, sizeof(iatq));
   2087       1.1  yamaguch 
   2088       1.1  yamaguch 	iaq = &iatq.iatq_desc;
   2089       1.1  yamaguch 	iaq->iaq_opcode = htole16(IXL_AQ_OP_SET_VSI_PROMISC);
   2090       1.1  yamaguch 
   2091       1.1  yamaguch 	param = (struct ixl_aq_vsi_promisc_param *)&iaq->iaq_param;
   2092      1.12  yamaguch 	param->flags = htole16(0);
   2093      1.12  yamaguch 
   2094      1.12  yamaguch 	if (!ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER)
   2095      1.12  yamaguch 	    || ISSET(ifp->if_flags, IFF_PROMISC)) {
   2096      1.12  yamaguch 		param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_BCAST |
   2097      1.12  yamaguch 		    IXL_AQ_VSI_PROMISC_FLAG_VLAN);
   2098      1.12  yamaguch 	}
   2099      1.12  yamaguch 
   2100       1.1  yamaguch 	if (ISSET(ifp->if_flags, IFF_PROMISC)) {
   2101       1.1  yamaguch 		param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_UCAST |
   2102       1.1  yamaguch 		    IXL_AQ_VSI_PROMISC_FLAG_MCAST);
   2103       1.1  yamaguch 	} else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) {
   2104       1.1  yamaguch 		param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_MCAST);
   2105       1.1  yamaguch 	}
   2106       1.1  yamaguch 	param->valid_flags = htole16(IXL_AQ_VSI_PROMISC_FLAG_UCAST |
   2107       1.1  yamaguch 	    IXL_AQ_VSI_PROMISC_FLAG_MCAST | IXL_AQ_VSI_PROMISC_FLAG_BCAST |
   2108       1.1  yamaguch 	    IXL_AQ_VSI_PROMISC_FLAG_VLAN);
   2109       1.1  yamaguch 	param->seid = sc->sc_seid;
   2110       1.1  yamaguch 
   2111       1.1  yamaguch 	error = ixl_atq_exec(sc, &iatq);
   2112       1.1  yamaguch 	if (error)
   2113       1.1  yamaguch 		return error;
   2114       1.1  yamaguch 
   2115       1.1  yamaguch 	if (iaq->iaq_retval != htole16(IXL_AQ_RC_OK))
   2116       1.1  yamaguch 		return EIO;
   2117       1.1  yamaguch 
   2118       1.1  yamaguch 	if (memcmp(sc->sc_enaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN) != 0) {
   2119      1.12  yamaguch 		if (ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER)) {
   2120      1.12  yamaguch 			flag_add = IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH;
   2121      1.12  yamaguch 			flag_del = IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH;
   2122      1.12  yamaguch 		} else {
   2123      1.12  yamaguch 			flag_add = IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN;
   2124      1.12  yamaguch 			flag_del = IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN;
   2125      1.12  yamaguch 		}
   2126      1.12  yamaguch 
   2127      1.12  yamaguch 		ixl_remove_macvlan(sc, sc->sc_enaddr, 0, flag_del);
   2128       1.1  yamaguch 
   2129       1.1  yamaguch 		memcpy(sc->sc_enaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
   2130      1.12  yamaguch 		ixl_add_macvlan(sc, sc->sc_enaddr, 0, flag_add);
   2131       1.1  yamaguch 	}
   2132       1.1  yamaguch 	return 0;
   2133       1.1  yamaguch }
   2134       1.1  yamaguch 
   2135       1.1  yamaguch static void
   2136       1.1  yamaguch ixl_stop_rendezvous(struct ixl_softc *sc)
   2137       1.1  yamaguch {
   2138       1.1  yamaguch 	struct ixl_tx_ring *txr;
   2139       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   2140       1.1  yamaguch 	unsigned int i;
   2141       1.1  yamaguch 
   2142       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   2143       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   2144       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   2145       1.1  yamaguch 
   2146       1.1  yamaguch 		mutex_enter(&txr->txr_lock);
   2147       1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   2148       1.1  yamaguch 
   2149       1.1  yamaguch 		mutex_enter(&rxr->rxr_lock);
   2150       1.1  yamaguch 		mutex_exit(&rxr->rxr_lock);
   2151       1.1  yamaguch 
   2152       1.1  yamaguch 		ixl_work_wait(sc->sc_workq_txrx,
   2153       1.1  yamaguch 		    &sc->sc_qps[i].qp_task);
   2154       1.1  yamaguch 	}
   2155       1.1  yamaguch }
   2156       1.1  yamaguch 
   2157       1.1  yamaguch static void
   2158       1.1  yamaguch ixl_stop_locked(struct ixl_softc *sc)
   2159       1.1  yamaguch {
   2160       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2161       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   2162       1.1  yamaguch 	struct ixl_tx_ring *txr;
   2163       1.1  yamaguch 	unsigned int i;
   2164       1.1  yamaguch 	uint32_t reg;
   2165       1.1  yamaguch 
   2166       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   2167       1.1  yamaguch 
   2168       1.1  yamaguch 	CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE);
   2169       1.1  yamaguch 
   2170       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   2171       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   2172       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   2173       1.1  yamaguch 
   2174       1.1  yamaguch 		ixl_disable_queue_intr(sc, &sc->sc_qps[i]);
   2175       1.1  yamaguch 
   2176       1.1  yamaguch 		mutex_enter(&txr->txr_lock);
   2177       1.1  yamaguch 		ixl_txr_qdis(sc, txr, 0);
   2178       1.1  yamaguch 		/* XXX wait at least 400 usec for all tx queues in one go */
   2179       1.1  yamaguch 		ixl_flush(sc);
   2180       1.1  yamaguch 		DELAY(500);
   2181       1.1  yamaguch 
   2182       1.1  yamaguch 		reg = ixl_rd(sc, I40E_QTX_ENA(i));
   2183       1.1  yamaguch 		CLR(reg, I40E_QTX_ENA_QENA_REQ_MASK);
   2184       1.1  yamaguch 		ixl_wr(sc, I40E_QTX_ENA(i), reg);
   2185       1.1  yamaguch 		/* XXX wait 50ms from completaion of the TX queue disable*/
   2186       1.1  yamaguch 		ixl_flush(sc);
   2187       1.1  yamaguch 		DELAY(50);
   2188       1.1  yamaguch 
   2189       1.1  yamaguch 		if (ixl_txr_disabled(sc, txr) != 0) {
   2190       1.1  yamaguch 			mutex_exit(&txr->txr_lock);
   2191       1.1  yamaguch 			goto die;
   2192       1.1  yamaguch 		}
   2193       1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   2194       1.1  yamaguch 
   2195       1.1  yamaguch 		mutex_enter(&rxr->rxr_lock);
   2196       1.1  yamaguch 		reg = ixl_rd(sc, I40E_QRX_ENA(i));
   2197       1.1  yamaguch 		CLR(reg, I40E_QRX_ENA_QENA_REQ_MASK);
   2198       1.1  yamaguch 		ixl_wr(sc, I40E_QRX_ENA(i), reg);
   2199       1.1  yamaguch 		/* XXX wait 50ms from completion of the RX queue disable */
   2200       1.1  yamaguch 		ixl_flush(sc);
   2201       1.1  yamaguch 		DELAY(50);
   2202       1.1  yamaguch 
   2203       1.1  yamaguch 		if (ixl_rxr_disabled(sc, rxr) != 0) {
   2204       1.1  yamaguch 			mutex_exit(&rxr->rxr_lock);
   2205       1.1  yamaguch 			goto die;
   2206       1.1  yamaguch 		}
   2207       1.1  yamaguch 		mutex_exit(&rxr->rxr_lock);
   2208       1.1  yamaguch 	}
   2209       1.1  yamaguch 
   2210       1.1  yamaguch 	ixl_stop_rendezvous(sc);
   2211       1.1  yamaguch 
   2212       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   2213       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   2214       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   2215       1.1  yamaguch 
   2216       1.1  yamaguch 		ixl_txr_unconfig(sc, txr);
   2217       1.1  yamaguch 		ixl_rxr_unconfig(sc, rxr);
   2218       1.1  yamaguch 
   2219       1.1  yamaguch 		ixl_txr_clean(sc, txr);
   2220       1.1  yamaguch 		ixl_rxr_clean(sc, rxr);
   2221       1.1  yamaguch 	}
   2222       1.1  yamaguch 
   2223       1.1  yamaguch 	return;
   2224       1.1  yamaguch die:
   2225       1.1  yamaguch 	sc->sc_dead = true;
   2226       1.1  yamaguch 	log(LOG_CRIT, "%s: failed to shut down rings",
   2227       1.1  yamaguch 	    device_xname(sc->sc_dev));
   2228       1.1  yamaguch 	return;
   2229       1.1  yamaguch }
   2230       1.1  yamaguch 
   2231       1.1  yamaguch static void
   2232       1.1  yamaguch ixl_stop(struct ifnet *ifp, int disable)
   2233       1.1  yamaguch {
   2234       1.1  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   2235       1.1  yamaguch 
   2236       1.1  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   2237       1.1  yamaguch 	ixl_stop_locked(sc);
   2238       1.1  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   2239       1.1  yamaguch }
   2240       1.1  yamaguch 
   2241       1.1  yamaguch static int
   2242       1.1  yamaguch ixl_queue_pairs_alloc(struct ixl_softc *sc)
   2243       1.1  yamaguch {
   2244       1.1  yamaguch 	struct ixl_queue_pair *qp;
   2245       1.1  yamaguch 	unsigned int i;
   2246       1.1  yamaguch 	size_t sz;
   2247       1.1  yamaguch 
   2248       1.1  yamaguch 	sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max;
   2249       1.1  yamaguch 	sc->sc_qps = kmem_zalloc(sz, KM_SLEEP);
   2250       1.1  yamaguch 
   2251       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   2252       1.1  yamaguch 		qp = &sc->sc_qps[i];
   2253       1.1  yamaguch 
   2254       1.1  yamaguch 		qp->qp_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
   2255       1.1  yamaguch 		    ixl_handle_queue, qp);
   2256       1.6  yamaguch 		if (qp->qp_si == NULL)
   2257       1.6  yamaguch 			goto free;
   2258       1.1  yamaguch 
   2259       1.1  yamaguch 		qp->qp_txr = ixl_txr_alloc(sc, i);
   2260       1.1  yamaguch 		if (qp->qp_txr == NULL)
   2261       1.1  yamaguch 			goto free;
   2262       1.1  yamaguch 
   2263       1.1  yamaguch 		qp->qp_rxr = ixl_rxr_alloc(sc, i);
   2264       1.1  yamaguch 		if (qp->qp_rxr == NULL)
   2265       1.1  yamaguch 			goto free;
   2266       1.1  yamaguch 
   2267       1.1  yamaguch 		qp->qp_sc = sc;
   2268       1.1  yamaguch 		ixl_work_set(&qp->qp_task, ixl_handle_queue, qp);
   2269       1.1  yamaguch 		snprintf(qp->qp_name, sizeof(qp->qp_name),
   2270       1.1  yamaguch 		    "%s-TXRX%d", device_xname(sc->sc_dev), i);
   2271       1.1  yamaguch 	}
   2272       1.1  yamaguch 
   2273       1.1  yamaguch 	return 0;
   2274       1.1  yamaguch free:
   2275       1.1  yamaguch 	if (sc->sc_qps != NULL) {
   2276       1.1  yamaguch 		for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   2277       1.1  yamaguch 			qp = &sc->sc_qps[i];
   2278       1.1  yamaguch 
   2279       1.1  yamaguch 			if (qp->qp_txr != NULL)
   2280       1.1  yamaguch 				ixl_txr_free(sc, qp->qp_txr);
   2281       1.1  yamaguch 			if (qp->qp_rxr != NULL)
   2282       1.1  yamaguch 				ixl_rxr_free(sc, qp->qp_rxr);
   2283       1.6  yamaguch 			if (qp->qp_si != NULL)
   2284       1.6  yamaguch 				softint_disestablish(qp->qp_si);
   2285       1.1  yamaguch 		}
   2286       1.1  yamaguch 
   2287       1.1  yamaguch 		sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max;
   2288       1.1  yamaguch 		kmem_free(sc->sc_qps, sz);
   2289       1.1  yamaguch 		sc->sc_qps = NULL;
   2290       1.1  yamaguch 	}
   2291       1.1  yamaguch 
   2292       1.1  yamaguch 	return -1;
   2293       1.1  yamaguch }
   2294       1.1  yamaguch 
   2295       1.1  yamaguch static void
   2296       1.1  yamaguch ixl_queue_pairs_free(struct ixl_softc *sc)
   2297       1.1  yamaguch {
   2298       1.1  yamaguch 	struct ixl_queue_pair *qp;
   2299       1.1  yamaguch 	unsigned int i;
   2300       1.1  yamaguch 	size_t sz;
   2301       1.1  yamaguch 
   2302       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   2303       1.1  yamaguch 		qp = &sc->sc_qps[i];
   2304       1.1  yamaguch 		ixl_txr_free(sc, qp->qp_txr);
   2305       1.1  yamaguch 		ixl_rxr_free(sc, qp->qp_rxr);
   2306       1.6  yamaguch 		softint_disestablish(qp->qp_si);
   2307       1.1  yamaguch 	}
   2308       1.1  yamaguch 
   2309       1.1  yamaguch 	sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max;
   2310       1.1  yamaguch 	kmem_free(sc->sc_qps, sz);
   2311       1.1  yamaguch 	sc->sc_qps = NULL;
   2312       1.1  yamaguch }
   2313       1.1  yamaguch 
   2314       1.1  yamaguch static struct ixl_tx_ring *
   2315       1.1  yamaguch ixl_txr_alloc(struct ixl_softc *sc, unsigned int qid)
   2316       1.1  yamaguch {
   2317       1.1  yamaguch 	struct ixl_tx_ring *txr = NULL;
   2318       1.1  yamaguch 	struct ixl_tx_map *maps = NULL, *txm;
   2319       1.1  yamaguch 	unsigned int i;
   2320       1.1  yamaguch 
   2321       1.1  yamaguch 	txr = kmem_zalloc(sizeof(*txr), KM_SLEEP);
   2322       1.1  yamaguch 	maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_tx_ring_ndescs,
   2323       1.1  yamaguch 	    KM_SLEEP);
   2324       1.1  yamaguch 
   2325       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &txr->txr_mem,
   2326       1.1  yamaguch 	    sizeof(struct ixl_tx_desc) * sc->sc_tx_ring_ndescs,
   2327       1.1  yamaguch 	    IXL_TX_QUEUE_ALIGN) != 0)
   2328       1.1  yamaguch 	    goto free;
   2329       1.1  yamaguch 
   2330       1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2331       1.1  yamaguch 		txm = &maps[i];
   2332       1.1  yamaguch 
   2333       1.1  yamaguch 		if (bus_dmamap_create(sc->sc_dmat,
   2334       1.1  yamaguch 		    IXL_HARDMTU, IXL_TX_PKT_DESCS, IXL_HARDMTU, 0,
   2335       1.1  yamaguch 		    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &txm->txm_map) != 0)
   2336       1.1  yamaguch 			goto uncreate;
   2337       1.1  yamaguch 
   2338       1.1  yamaguch 		txm->txm_eop = -1;
   2339       1.1  yamaguch 		txm->txm_m = NULL;
   2340       1.1  yamaguch 	}
   2341       1.1  yamaguch 
   2342       1.1  yamaguch 	txr->txr_cons = txr->txr_prod = 0;
   2343       1.1  yamaguch 	txr->txr_maps = maps;
   2344       1.1  yamaguch 
   2345       1.1  yamaguch 	txr->txr_intrq = pcq_create(sc->sc_tx_ring_ndescs, KM_NOSLEEP);
   2346       1.1  yamaguch 	if (txr->txr_intrq == NULL)
   2347       1.1  yamaguch 		goto uncreate;
   2348       1.1  yamaguch 
   2349       1.1  yamaguch 	txr->txr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
   2350       1.1  yamaguch 	    ixl_deferred_transmit, txr);
   2351       1.1  yamaguch 	if (txr->txr_si == NULL)
   2352       1.1  yamaguch 		goto destroy_pcq;
   2353       1.1  yamaguch 
   2354       1.1  yamaguch 	txr->txr_tail = I40E_QTX_TAIL(qid);
   2355       1.1  yamaguch 	txr->txr_qid = qid;
   2356       1.1  yamaguch 	txr->txr_sc = sc;
   2357       1.1  yamaguch 	mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET);
   2358       1.1  yamaguch 
   2359       1.1  yamaguch 	return txr;
   2360       1.1  yamaguch 
   2361       1.1  yamaguch destroy_pcq:
   2362       1.1  yamaguch 	pcq_destroy(txr->txr_intrq);
   2363       1.1  yamaguch uncreate:
   2364       1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2365       1.1  yamaguch 		txm = &maps[i];
   2366       1.1  yamaguch 
   2367       1.1  yamaguch 		if (txm->txm_map == NULL)
   2368       1.1  yamaguch 			continue;
   2369       1.1  yamaguch 
   2370       1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, txm->txm_map);
   2371       1.1  yamaguch 	}
   2372       1.1  yamaguch 
   2373       1.1  yamaguch 	ixl_dmamem_free(sc, &txr->txr_mem);
   2374       1.1  yamaguch free:
   2375       1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs);
   2376       1.1  yamaguch 	kmem_free(txr, sizeof(*txr));
   2377       1.1  yamaguch 
   2378       1.1  yamaguch 	return NULL;
   2379       1.1  yamaguch }
   2380       1.1  yamaguch 
   2381       1.1  yamaguch static void
   2382       1.1  yamaguch ixl_txr_qdis(struct ixl_softc *sc, struct ixl_tx_ring *txr, int enable)
   2383       1.1  yamaguch {
   2384       1.1  yamaguch 	unsigned int qid;
   2385       1.1  yamaguch 	bus_size_t reg;
   2386       1.1  yamaguch 	uint32_t r;
   2387       1.1  yamaguch 
   2388       1.1  yamaguch 	qid = txr->txr_qid + sc->sc_base_queue;
   2389       1.1  yamaguch 	reg = I40E_GLLAN_TXPRE_QDIS(qid / 128);
   2390       1.1  yamaguch 	qid %= 128;
   2391       1.1  yamaguch 
   2392       1.1  yamaguch 	r = ixl_rd(sc, reg);
   2393       1.1  yamaguch 	CLR(r, I40E_GLLAN_TXPRE_QDIS_QINDX_MASK);
   2394       1.1  yamaguch 	SET(r, qid << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
   2395       1.1  yamaguch 	SET(r, enable ? I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK :
   2396       1.1  yamaguch 	    I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK);
   2397       1.1  yamaguch 	ixl_wr(sc, reg, r);
   2398       1.1  yamaguch }
   2399       1.1  yamaguch 
   2400       1.1  yamaguch static void
   2401       1.1  yamaguch ixl_txr_config(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2402       1.1  yamaguch {
   2403       1.1  yamaguch 	struct ixl_hmc_txq txq;
   2404       1.1  yamaguch 	struct ixl_aq_vsi_data *data = IXL_DMA_KVA(&sc->sc_scratch);
   2405       1.1  yamaguch 	void *hmc;
   2406       1.1  yamaguch 
   2407       1.1  yamaguch 	memset(&txq, 0, sizeof(txq));
   2408       1.1  yamaguch 	txq.head = htole16(txr->txr_cons);
   2409       1.1  yamaguch 	txq.new_context = 1;
   2410       1.1  yamaguch 	txq.base = htole64(IXL_DMA_DVA(&txr->txr_mem) / IXL_HMC_TXQ_BASE_UNIT);
   2411       1.1  yamaguch 	txq.head_wb_ena = IXL_HMC_TXQ_DESC_WB;
   2412       1.1  yamaguch 	txq.qlen = htole16(sc->sc_tx_ring_ndescs);
   2413       1.1  yamaguch 	txq.tphrdesc_ena = 0;
   2414       1.1  yamaguch 	txq.tphrpacket_ena = 0;
   2415       1.1  yamaguch 	txq.tphwdesc_ena = 0;
   2416       1.1  yamaguch 	txq.rdylist = data->qs_handle[0];
   2417       1.1  yamaguch 
   2418       1.1  yamaguch 	hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_TX, txr->txr_qid);
   2419       1.1  yamaguch 	memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_TX));
   2420       1.1  yamaguch 	ixl_hmc_pack(hmc, &txq, ixl_hmc_pack_txq,
   2421       1.1  yamaguch 	    __arraycount(ixl_hmc_pack_txq));
   2422       1.1  yamaguch }
   2423       1.1  yamaguch 
   2424       1.1  yamaguch static void
   2425       1.1  yamaguch ixl_txr_unconfig(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2426       1.1  yamaguch {
   2427       1.1  yamaguch 	void *hmc;
   2428       1.1  yamaguch 
   2429       1.1  yamaguch 	hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_TX, txr->txr_qid);
   2430       1.1  yamaguch 	memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_TX));
   2431       1.1  yamaguch }
   2432       1.1  yamaguch 
   2433       1.1  yamaguch static void
   2434       1.1  yamaguch ixl_txr_clean(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2435       1.1  yamaguch {
   2436       1.1  yamaguch 	struct ixl_tx_map *maps, *txm;
   2437       1.1  yamaguch 	bus_dmamap_t map;
   2438       1.1  yamaguch 	unsigned int i;
   2439       1.1  yamaguch 
   2440       1.1  yamaguch 	maps = txr->txr_maps;
   2441       1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2442       1.1  yamaguch 		txm = &maps[i];
   2443       1.1  yamaguch 
   2444       1.1  yamaguch 		if (txm->txm_m == NULL)
   2445       1.1  yamaguch 			continue;
   2446       1.1  yamaguch 
   2447       1.1  yamaguch 		map = txm->txm_map;
   2448       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2449       1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   2450       1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2451       1.1  yamaguch 
   2452       1.1  yamaguch 		m_freem(txm->txm_m);
   2453       1.1  yamaguch 		txm->txm_m = NULL;
   2454       1.1  yamaguch 	}
   2455       1.1  yamaguch }
   2456       1.1  yamaguch 
   2457       1.1  yamaguch static int
   2458       1.1  yamaguch ixl_txr_enabled(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2459       1.1  yamaguch {
   2460       1.1  yamaguch 	bus_size_t ena = I40E_QTX_ENA(txr->txr_qid);
   2461       1.1  yamaguch 	uint32_t reg;
   2462       1.1  yamaguch 	int i;
   2463       1.1  yamaguch 
   2464       1.1  yamaguch 	for (i = 0; i < 10; i++) {
   2465       1.1  yamaguch 		reg = ixl_rd(sc, ena);
   2466       1.1  yamaguch 		if (ISSET(reg, I40E_QTX_ENA_QENA_STAT_MASK))
   2467       1.1  yamaguch 			return 0;
   2468       1.1  yamaguch 
   2469       1.1  yamaguch 		delaymsec(10);
   2470       1.1  yamaguch 	}
   2471       1.1  yamaguch 
   2472       1.1  yamaguch 	return ETIMEDOUT;
   2473       1.1  yamaguch }
   2474       1.1  yamaguch 
   2475       1.1  yamaguch static int
   2476       1.1  yamaguch ixl_txr_disabled(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2477       1.1  yamaguch {
   2478       1.1  yamaguch 	bus_size_t ena = I40E_QTX_ENA(txr->txr_qid);
   2479       1.1  yamaguch 	uint32_t reg;
   2480       1.1  yamaguch 	int i;
   2481       1.1  yamaguch 
   2482       1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2483       1.1  yamaguch 
   2484       1.1  yamaguch 	for (i = 0; i < 20; i++) {
   2485       1.1  yamaguch 		reg = ixl_rd(sc, ena);
   2486       1.1  yamaguch 		if (ISSET(reg, I40E_QTX_ENA_QENA_STAT_MASK) == 0)
   2487       1.1  yamaguch 			return 0;
   2488       1.1  yamaguch 
   2489       1.1  yamaguch 		delaymsec(10);
   2490       1.1  yamaguch 	}
   2491       1.1  yamaguch 
   2492       1.1  yamaguch 	return ETIMEDOUT;
   2493       1.1  yamaguch }
   2494       1.1  yamaguch 
   2495       1.1  yamaguch static void
   2496       1.1  yamaguch ixl_txr_free(struct ixl_softc *sc, struct ixl_tx_ring *txr)
   2497       1.1  yamaguch {
   2498       1.1  yamaguch 	struct ixl_tx_map *maps, *txm;
   2499       1.1  yamaguch 	struct mbuf *m;
   2500       1.1  yamaguch 	unsigned int i;
   2501       1.1  yamaguch 
   2502       1.1  yamaguch 	softint_disestablish(txr->txr_si);
   2503       1.1  yamaguch 	while ((m = pcq_get(txr->txr_intrq)) != NULL)
   2504       1.1  yamaguch 		m_freem(m);
   2505       1.1  yamaguch 	pcq_destroy(txr->txr_intrq);
   2506       1.1  yamaguch 
   2507       1.1  yamaguch 	maps = txr->txr_maps;
   2508       1.1  yamaguch 	for (i = 0; i < sc->sc_tx_ring_ndescs; i++) {
   2509       1.1  yamaguch 		txm = &maps[i];
   2510       1.1  yamaguch 
   2511       1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, txm->txm_map);
   2512       1.1  yamaguch 	}
   2513       1.1  yamaguch 
   2514       1.1  yamaguch 	ixl_dmamem_free(sc, &txr->txr_mem);
   2515       1.1  yamaguch 	mutex_destroy(&txr->txr_lock);
   2516       1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs);
   2517       1.1  yamaguch 	kmem_free(txr, sizeof(*txr));
   2518       1.1  yamaguch }
   2519       1.1  yamaguch 
   2520       1.1  yamaguch static inline int
   2521       1.1  yamaguch ixl_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf **m0,
   2522       1.1  yamaguch     struct ixl_tx_ring *txr)
   2523       1.1  yamaguch {
   2524       1.1  yamaguch 	struct mbuf *m;
   2525       1.1  yamaguch 	int error;
   2526       1.1  yamaguch 
   2527       1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2528       1.1  yamaguch 
   2529       1.1  yamaguch 	m = *m0;
   2530       1.1  yamaguch 
   2531       1.1  yamaguch 	error = bus_dmamap_load_mbuf(dmat, map, m,
   2532       1.1  yamaguch 	    BUS_DMA_STREAMING | BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   2533       1.1  yamaguch 	if (error != EFBIG)
   2534       1.1  yamaguch 		return error;
   2535       1.1  yamaguch 
   2536       1.1  yamaguch 	m = m_defrag(m, M_DONTWAIT);
   2537       1.1  yamaguch 	if (m != NULL) {
   2538       1.1  yamaguch 		*m0 = m;
   2539       1.1  yamaguch 		txr->txr_defragged.ev_count++;
   2540       1.1  yamaguch 
   2541       1.1  yamaguch 		error = bus_dmamap_load_mbuf(dmat, map, m,
   2542       1.1  yamaguch 		    BUS_DMA_STREAMING | BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   2543       1.1  yamaguch 	} else {
   2544       1.1  yamaguch 		txr->txr_defrag_failed.ev_count++;
   2545       1.1  yamaguch 		error = ENOBUFS;
   2546       1.1  yamaguch 	}
   2547       1.1  yamaguch 
   2548       1.1  yamaguch 	return error;
   2549       1.1  yamaguch }
   2550       1.1  yamaguch 
   2551       1.1  yamaguch static void
   2552       1.1  yamaguch ixl_tx_common_locked(struct ifnet *ifp, struct ixl_tx_ring *txr,
   2553       1.1  yamaguch     bool is_transmit)
   2554       1.1  yamaguch {
   2555       1.1  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   2556       1.1  yamaguch 	struct ixl_tx_desc *ring, *txd;
   2557       1.1  yamaguch 	struct ixl_tx_map *txm;
   2558       1.1  yamaguch 	bus_dmamap_t map;
   2559       1.1  yamaguch 	struct mbuf *m;
   2560      1.11  yamaguch 	uint64_t cmd, cmd_vlan;
   2561       1.1  yamaguch 	unsigned int prod, free, last, i;
   2562       1.1  yamaguch 	unsigned int mask;
   2563       1.1  yamaguch 	int post = 0;
   2564       1.1  yamaguch 
   2565       1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2566       1.1  yamaguch 
   2567       1.1  yamaguch 	if (ifp->if_link_state != LINK_STATE_UP
   2568       1.1  yamaguch 	    || !ISSET(ifp->if_flags, IFF_RUNNING)
   2569       1.1  yamaguch 	    || (!is_transmit && ISSET(ifp->if_flags, IFF_OACTIVE))) {
   2570       1.1  yamaguch 		if (!is_transmit)
   2571       1.1  yamaguch 			IFQ_PURGE(&ifp->if_snd);
   2572       1.1  yamaguch 		return;
   2573       1.1  yamaguch 	}
   2574       1.1  yamaguch 
   2575       1.1  yamaguch 	prod = txr->txr_prod;
   2576       1.1  yamaguch 	free = txr->txr_cons;
   2577       1.1  yamaguch 	if (free <= prod)
   2578       1.1  yamaguch 		free += sc->sc_tx_ring_ndescs;
   2579       1.1  yamaguch 	free -= prod;
   2580       1.1  yamaguch 
   2581       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2582       1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTWRITE);
   2583       1.1  yamaguch 
   2584       1.1  yamaguch 	ring = IXL_DMA_KVA(&txr->txr_mem);
   2585       1.1  yamaguch 	mask = sc->sc_tx_ring_ndescs - 1;
   2586       1.1  yamaguch 	last = prod;
   2587       1.1  yamaguch 	cmd = 0;
   2588       1.1  yamaguch 	txd = NULL;
   2589       1.1  yamaguch 
   2590       1.1  yamaguch 	for (;;) {
   2591       1.1  yamaguch 		if (free <= IXL_TX_PKT_DESCS) {
   2592       1.1  yamaguch 			if (!is_transmit)
   2593       1.1  yamaguch 				SET(ifp->if_flags, IFF_OACTIVE);
   2594       1.1  yamaguch 			break;
   2595       1.1  yamaguch 		}
   2596       1.1  yamaguch 
   2597       1.1  yamaguch 		if (is_transmit)
   2598       1.1  yamaguch 			m = pcq_get(txr->txr_intrq);
   2599       1.1  yamaguch 		else
   2600       1.1  yamaguch 			IFQ_DEQUEUE(&ifp->if_snd, m);
   2601       1.1  yamaguch 
   2602       1.1  yamaguch 		if (m == NULL)
   2603       1.1  yamaguch 			break;
   2604       1.1  yamaguch 
   2605       1.1  yamaguch 		txm = &txr->txr_maps[prod];
   2606       1.1  yamaguch 		map = txm->txm_map;
   2607       1.1  yamaguch 
   2608       1.1  yamaguch 		if (ixl_load_mbuf(sc->sc_dmat, map, &m, txr) != 0) {
   2609       1.1  yamaguch 			txr->txr_oerrors++;
   2610       1.1  yamaguch 			m_freem(m);
   2611       1.1  yamaguch 			continue;
   2612       1.1  yamaguch 		}
   2613       1.1  yamaguch 
   2614      1.11  yamaguch 		if (vlan_has_tag(m)) {
   2615      1.11  yamaguch 			cmd_vlan = (uint64_t)vlan_get_tag(m) <<
   2616      1.11  yamaguch 			    IXL_TX_DESC_L2TAG1_SHIFT;
   2617      1.11  yamaguch 			cmd_vlan |= IXL_TX_DESC_CMD_IL2TAG1;
   2618      1.11  yamaguch 		} else {
   2619      1.11  yamaguch 			cmd_vlan = 0;
   2620      1.11  yamaguch 		}
   2621      1.11  yamaguch 
   2622       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0,
   2623       1.1  yamaguch 		    map->dm_mapsize, BUS_DMASYNC_PREWRITE);
   2624       1.1  yamaguch 
   2625       1.1  yamaguch 		for (i = 0; i < (unsigned int)map->dm_nsegs; i++) {
   2626       1.1  yamaguch 			txd = &ring[prod];
   2627       1.1  yamaguch 
   2628       1.1  yamaguch 			cmd = (uint64_t)map->dm_segs[i].ds_len <<
   2629       1.1  yamaguch 			    IXL_TX_DESC_BSIZE_SHIFT;
   2630       1.1  yamaguch 			cmd |= IXL_TX_DESC_DTYPE_DATA | IXL_TX_DESC_CMD_ICRC;
   2631      1.11  yamaguch 			cmd |= cmd_vlan;
   2632       1.1  yamaguch 
   2633       1.1  yamaguch 			txd->addr = htole64(map->dm_segs[i].ds_addr);
   2634       1.1  yamaguch 			txd->cmd = htole64(cmd);
   2635       1.1  yamaguch 
   2636       1.1  yamaguch 			last = prod;
   2637       1.1  yamaguch 
   2638       1.1  yamaguch 			prod++;
   2639       1.1  yamaguch 			prod &= mask;
   2640       1.1  yamaguch 		}
   2641       1.1  yamaguch 		cmd |= IXL_TX_DESC_CMD_EOP | IXL_TX_DESC_CMD_RS;
   2642       1.1  yamaguch 		txd->cmd = htole64(cmd);
   2643       1.1  yamaguch 
   2644       1.1  yamaguch 		txm->txm_m = m;
   2645       1.1  yamaguch 		txm->txm_eop = last;
   2646       1.1  yamaguch 
   2647       1.1  yamaguch 		bpf_mtap(ifp, m, BPF_D_OUT);
   2648       1.1  yamaguch 
   2649       1.1  yamaguch 		free -= i;
   2650       1.1  yamaguch 		post = 1;
   2651       1.1  yamaguch 	}
   2652       1.1  yamaguch 
   2653       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2654       1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREWRITE);
   2655       1.1  yamaguch 
   2656       1.1  yamaguch 	if (post) {
   2657       1.1  yamaguch 		txr->txr_prod = prod;
   2658       1.1  yamaguch 		ixl_wr(sc, txr->txr_tail, prod);
   2659       1.1  yamaguch 	}
   2660       1.1  yamaguch }
   2661       1.1  yamaguch 
   2662       1.1  yamaguch static int
   2663       1.1  yamaguch ixl_txeof(struct ixl_softc *sc, struct ixl_tx_ring *txr, u_int txlimit)
   2664       1.1  yamaguch {
   2665       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2666       1.1  yamaguch 	struct ixl_tx_desc *ring, *txd;
   2667       1.1  yamaguch 	struct ixl_tx_map *txm;
   2668       1.1  yamaguch 	struct mbuf *m;
   2669       1.1  yamaguch 	bus_dmamap_t map;
   2670       1.1  yamaguch 	unsigned int cons, prod, last;
   2671       1.1  yamaguch 	unsigned int mask;
   2672       1.1  yamaguch 	uint64_t dtype;
   2673       1.1  yamaguch 	int done = 0, more = 0;
   2674       1.1  yamaguch 
   2675       1.1  yamaguch 	KASSERT(mutex_owned(&txr->txr_lock));
   2676       1.1  yamaguch 
   2677       1.1  yamaguch 	prod = txr->txr_prod;
   2678       1.1  yamaguch 	cons = txr->txr_cons;
   2679       1.1  yamaguch 
   2680       1.1  yamaguch 	if (cons == prod)
   2681       1.1  yamaguch 		return 0;
   2682       1.1  yamaguch 
   2683       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2684       1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTREAD);
   2685       1.1  yamaguch 
   2686       1.1  yamaguch 	ring = IXL_DMA_KVA(&txr->txr_mem);
   2687       1.1  yamaguch 	mask = sc->sc_tx_ring_ndescs - 1;
   2688       1.1  yamaguch 
   2689       1.1  yamaguch 	do {
   2690       1.1  yamaguch 		if (txlimit-- <= 0) {
   2691       1.1  yamaguch 			more = 1;
   2692       1.1  yamaguch 			break;
   2693       1.1  yamaguch 		}
   2694       1.1  yamaguch 
   2695       1.1  yamaguch 		txm = &txr->txr_maps[cons];
   2696       1.1  yamaguch 		last = txm->txm_eop;
   2697       1.1  yamaguch 		txd = &ring[last];
   2698       1.1  yamaguch 
   2699       1.1  yamaguch 		dtype = txd->cmd & htole64(IXL_TX_DESC_DTYPE_MASK);
   2700       1.1  yamaguch 		if (dtype != htole64(IXL_TX_DESC_DTYPE_DONE))
   2701       1.1  yamaguch 			break;
   2702       1.1  yamaguch 
   2703       1.1  yamaguch 		map = txm->txm_map;
   2704       1.1  yamaguch 
   2705       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2706       1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   2707       1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2708       1.1  yamaguch 
   2709       1.1  yamaguch 		m = txm->txm_m;
   2710       1.1  yamaguch 		if (m != NULL) {
   2711       1.1  yamaguch 			txr->txr_opackets++;
   2712       1.1  yamaguch 			txr->txr_obytes += m->m_pkthdr.len;
   2713       1.1  yamaguch 			if (ISSET(m->m_flags, M_MCAST))
   2714       1.1  yamaguch 				txr->txr_omcasts++;
   2715       1.1  yamaguch 			m_freem(m);
   2716       1.1  yamaguch 		}
   2717       1.1  yamaguch 
   2718       1.1  yamaguch 		txm->txm_m = NULL;
   2719       1.1  yamaguch 		txm->txm_eop = -1;
   2720       1.1  yamaguch 
   2721       1.1  yamaguch 		cons = last + 1;
   2722       1.1  yamaguch 		cons &= mask;
   2723       1.1  yamaguch 		done = 1;
   2724       1.1  yamaguch 	} while (cons != prod);
   2725       1.1  yamaguch 
   2726       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem),
   2727       1.1  yamaguch 	    0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREREAD);
   2728       1.1  yamaguch 
   2729       1.1  yamaguch 	txr->txr_cons = cons;
   2730       1.1  yamaguch 
   2731       1.1  yamaguch 	if (done) {
   2732       1.1  yamaguch 		softint_schedule(txr->txr_si);
   2733       1.1  yamaguch 		if (txr->txr_qid == 0) {
   2734       1.1  yamaguch 			CLR(ifp->if_flags, IFF_OACTIVE);
   2735       1.1  yamaguch 			if_schedule_deferred_start(ifp);
   2736       1.1  yamaguch 		}
   2737       1.1  yamaguch 	}
   2738       1.1  yamaguch 
   2739       1.1  yamaguch 	return more;
   2740       1.1  yamaguch }
   2741       1.1  yamaguch 
   2742       1.1  yamaguch static void
   2743       1.1  yamaguch ixl_start(struct ifnet *ifp)
   2744       1.1  yamaguch {
   2745       1.1  yamaguch 	struct ixl_softc	*sc;
   2746       1.1  yamaguch 	struct ixl_tx_ring	*txr;
   2747       1.1  yamaguch 
   2748       1.1  yamaguch 	sc = ifp->if_softc;
   2749       1.1  yamaguch 	txr = sc->sc_qps[0].qp_txr;
   2750       1.1  yamaguch 
   2751       1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   2752       1.1  yamaguch 	ixl_tx_common_locked(ifp, txr, false);
   2753       1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   2754       1.1  yamaguch }
   2755       1.1  yamaguch 
   2756       1.1  yamaguch static inline unsigned int
   2757       1.1  yamaguch ixl_select_txqueue(struct ixl_softc *sc, struct mbuf *m)
   2758       1.1  yamaguch {
   2759       1.1  yamaguch 	u_int cpuid;
   2760       1.1  yamaguch 
   2761       1.1  yamaguch 	cpuid = cpu_index(curcpu());
   2762       1.1  yamaguch 
   2763       1.1  yamaguch 	return (unsigned int)(cpuid % sc->sc_nqueue_pairs);
   2764       1.1  yamaguch }
   2765       1.1  yamaguch 
   2766       1.1  yamaguch static int
   2767       1.1  yamaguch ixl_transmit(struct ifnet *ifp, struct mbuf *m)
   2768       1.1  yamaguch {
   2769       1.1  yamaguch 	struct ixl_softc *sc;
   2770       1.1  yamaguch 	struct ixl_tx_ring *txr;
   2771       1.1  yamaguch 	unsigned int qid;
   2772       1.1  yamaguch 
   2773       1.1  yamaguch 	sc = ifp->if_softc;
   2774       1.1  yamaguch 	qid = ixl_select_txqueue(sc, m);
   2775       1.1  yamaguch 
   2776       1.1  yamaguch 	txr = sc->sc_qps[qid].qp_txr;
   2777       1.1  yamaguch 
   2778       1.1  yamaguch 	if (__predict_false(!pcq_put(txr->txr_intrq, m))) {
   2779       1.1  yamaguch 		mutex_enter(&txr->txr_lock);
   2780       1.1  yamaguch 		txr->txr_pcqdrop.ev_count++;
   2781       1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   2782       1.1  yamaguch 
   2783       1.1  yamaguch 		m_freem(m);
   2784       1.1  yamaguch 		return ENOBUFS;
   2785       1.1  yamaguch 	}
   2786       1.1  yamaguch 
   2787       1.1  yamaguch 	if (mutex_tryenter(&txr->txr_lock)) {
   2788       1.1  yamaguch 		ixl_tx_common_locked(ifp, txr, true);
   2789       1.1  yamaguch 		mutex_exit(&txr->txr_lock);
   2790       1.1  yamaguch 	} else {
   2791       1.1  yamaguch 		softint_schedule(txr->txr_si);
   2792       1.1  yamaguch 	}
   2793       1.1  yamaguch 
   2794       1.1  yamaguch 	return 0;
   2795       1.1  yamaguch }
   2796       1.1  yamaguch 
   2797       1.1  yamaguch static void
   2798       1.1  yamaguch ixl_deferred_transmit(void *xtxr)
   2799       1.1  yamaguch {
   2800       1.1  yamaguch 	struct ixl_tx_ring *txr = xtxr;
   2801       1.1  yamaguch 	struct ixl_softc *sc = txr->txr_sc;
   2802       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2803       1.1  yamaguch 
   2804       1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   2805       1.1  yamaguch 	txr->txr_transmitdef.ev_count++;
   2806       1.1  yamaguch 	if (pcq_peek(txr->txr_intrq) != NULL)
   2807       1.1  yamaguch 		ixl_tx_common_locked(ifp, txr, true);
   2808       1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   2809       1.1  yamaguch }
   2810       1.1  yamaguch 
   2811       1.1  yamaguch static struct ixl_rx_ring *
   2812       1.1  yamaguch ixl_rxr_alloc(struct ixl_softc *sc, unsigned int qid)
   2813       1.1  yamaguch {
   2814       1.1  yamaguch 	struct ixl_rx_ring *rxr = NULL;
   2815       1.1  yamaguch 	struct ixl_rx_map *maps = NULL, *rxm;
   2816       1.1  yamaguch 	unsigned int i;
   2817       1.1  yamaguch 
   2818       1.1  yamaguch 	rxr = kmem_zalloc(sizeof(*rxr), KM_SLEEP);
   2819       1.1  yamaguch 	maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_rx_ring_ndescs,
   2820       1.1  yamaguch 	    KM_SLEEP);
   2821       1.1  yamaguch 
   2822       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &rxr->rxr_mem,
   2823      1.11  yamaguch 	    sizeof(struct ixl_rx_rd_desc_32) * sc->sc_rx_ring_ndescs,
   2824       1.1  yamaguch 	    IXL_RX_QUEUE_ALIGN) != 0)
   2825       1.1  yamaguch 		goto free;
   2826       1.1  yamaguch 
   2827       1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2828       1.1  yamaguch 		rxm = &maps[i];
   2829       1.1  yamaguch 
   2830       1.1  yamaguch 		if (bus_dmamap_create(sc->sc_dmat,
   2831       1.1  yamaguch 		    IXL_HARDMTU, 1, IXL_HARDMTU, 0,
   2832       1.1  yamaguch 		    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &rxm->rxm_map) != 0)
   2833       1.1  yamaguch 			goto uncreate;
   2834       1.1  yamaguch 
   2835       1.1  yamaguch 		rxm->rxm_m = NULL;
   2836       1.1  yamaguch 	}
   2837       1.1  yamaguch 
   2838       1.1  yamaguch 	rxr->rxr_cons = rxr->rxr_prod = 0;
   2839       1.1  yamaguch 	rxr->rxr_m_head = NULL;
   2840       1.1  yamaguch 	rxr->rxr_m_tail = &rxr->rxr_m_head;
   2841       1.1  yamaguch 	rxr->rxr_maps = maps;
   2842       1.1  yamaguch 
   2843       1.1  yamaguch 	rxr->rxr_tail = I40E_QRX_TAIL(qid);
   2844       1.1  yamaguch 	rxr->rxr_qid = qid;
   2845       1.1  yamaguch 	mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET);
   2846       1.1  yamaguch 
   2847       1.1  yamaguch 	return rxr;
   2848       1.1  yamaguch 
   2849       1.1  yamaguch uncreate:
   2850       1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2851       1.1  yamaguch 		rxm = &maps[i];
   2852       1.1  yamaguch 
   2853       1.1  yamaguch 		if (rxm->rxm_map == NULL)
   2854       1.1  yamaguch 			continue;
   2855       1.1  yamaguch 
   2856       1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, rxm->rxm_map);
   2857       1.1  yamaguch 	}
   2858       1.1  yamaguch 
   2859       1.1  yamaguch 	ixl_dmamem_free(sc, &rxr->rxr_mem);
   2860       1.1  yamaguch free:
   2861       1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs);
   2862       1.1  yamaguch 	kmem_free(rxr, sizeof(*rxr));
   2863       1.1  yamaguch 
   2864       1.1  yamaguch 	return NULL;
   2865       1.1  yamaguch }
   2866       1.1  yamaguch 
   2867       1.1  yamaguch static void
   2868       1.1  yamaguch ixl_rxr_clean(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2869       1.1  yamaguch {
   2870       1.1  yamaguch 	struct ixl_rx_map *maps, *rxm;
   2871       1.1  yamaguch 	bus_dmamap_t map;
   2872       1.1  yamaguch 	unsigned int i;
   2873       1.1  yamaguch 
   2874       1.1  yamaguch 	maps = rxr->rxr_maps;
   2875       1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2876       1.1  yamaguch 		rxm = &maps[i];
   2877       1.1  yamaguch 
   2878       1.1  yamaguch 		if (rxm->rxm_m == NULL)
   2879       1.1  yamaguch 			continue;
   2880       1.1  yamaguch 
   2881       1.1  yamaguch 		map = rxm->rxm_map;
   2882       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   2883       1.1  yamaguch 		    BUS_DMASYNC_POSTWRITE);
   2884       1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   2885       1.1  yamaguch 
   2886       1.1  yamaguch 		m_freem(rxm->rxm_m);
   2887       1.1  yamaguch 		rxm->rxm_m = NULL;
   2888       1.1  yamaguch 	}
   2889       1.1  yamaguch 
   2890       1.1  yamaguch 	m_freem(rxr->rxr_m_head);
   2891       1.1  yamaguch 	rxr->rxr_m_head = NULL;
   2892       1.1  yamaguch 	rxr->rxr_m_tail = &rxr->rxr_m_head;
   2893       1.1  yamaguch 
   2894       1.1  yamaguch 	rxr->rxr_prod = rxr->rxr_cons = 0;
   2895       1.1  yamaguch }
   2896       1.1  yamaguch 
   2897       1.1  yamaguch static int
   2898       1.1  yamaguch ixl_rxr_enabled(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2899       1.1  yamaguch {
   2900       1.1  yamaguch 	bus_size_t ena = I40E_QRX_ENA(rxr->rxr_qid);
   2901       1.1  yamaguch 	uint32_t reg;
   2902       1.1  yamaguch 	int i;
   2903       1.1  yamaguch 
   2904       1.1  yamaguch 	for (i = 0; i < 10; i++) {
   2905       1.1  yamaguch 		reg = ixl_rd(sc, ena);
   2906       1.1  yamaguch 		if (ISSET(reg, I40E_QRX_ENA_QENA_STAT_MASK))
   2907       1.1  yamaguch 			return 0;
   2908       1.1  yamaguch 
   2909       1.1  yamaguch 		delaymsec(10);
   2910       1.1  yamaguch 	}
   2911       1.1  yamaguch 
   2912       1.1  yamaguch 	return ETIMEDOUT;
   2913       1.1  yamaguch }
   2914       1.1  yamaguch 
   2915       1.1  yamaguch static int
   2916       1.1  yamaguch ixl_rxr_disabled(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2917       1.1  yamaguch {
   2918       1.1  yamaguch 	bus_size_t ena = I40E_QRX_ENA(rxr->rxr_qid);
   2919       1.1  yamaguch 	uint32_t reg;
   2920       1.1  yamaguch 	int i;
   2921       1.1  yamaguch 
   2922       1.1  yamaguch 	KASSERT(mutex_owned(&rxr->rxr_lock));
   2923       1.1  yamaguch 
   2924       1.1  yamaguch 	for (i = 0; i < 20; i++) {
   2925       1.1  yamaguch 		reg = ixl_rd(sc, ena);
   2926       1.1  yamaguch 		if (ISSET(reg, I40E_QRX_ENA_QENA_STAT_MASK) == 0)
   2927       1.1  yamaguch 			return 0;
   2928       1.1  yamaguch 
   2929       1.1  yamaguch 		delaymsec(10);
   2930       1.1  yamaguch 	}
   2931       1.1  yamaguch 
   2932       1.1  yamaguch 	return ETIMEDOUT;
   2933       1.1  yamaguch }
   2934       1.1  yamaguch 
   2935       1.1  yamaguch static void
   2936       1.1  yamaguch ixl_rxr_config(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2937       1.1  yamaguch {
   2938       1.1  yamaguch 	struct ixl_hmc_rxq rxq;
   2939       1.1  yamaguch 	void *hmc;
   2940       1.1  yamaguch 
   2941       1.1  yamaguch 	memset(&rxq, 0, sizeof(rxq));
   2942       1.1  yamaguch 
   2943       1.1  yamaguch 	rxq.head = htole16(rxr->rxr_cons);
   2944       1.1  yamaguch 	rxq.base = htole64(IXL_DMA_DVA(&rxr->rxr_mem) / IXL_HMC_RXQ_BASE_UNIT);
   2945       1.1  yamaguch 	rxq.qlen = htole16(sc->sc_rx_ring_ndescs);
   2946       1.1  yamaguch 	rxq.dbuff = htole16(MCLBYTES / IXL_HMC_RXQ_DBUFF_UNIT);
   2947       1.1  yamaguch 	rxq.hbuff = 0;
   2948       1.1  yamaguch 	rxq.dtype = IXL_HMC_RXQ_DTYPE_NOSPLIT;
   2949      1.11  yamaguch 	rxq.dsize = IXL_HMC_RXQ_DSIZE_32;
   2950       1.1  yamaguch 	rxq.crcstrip = 1;
   2951      1.11  yamaguch 	rxq.l2sel = 1;
   2952      1.11  yamaguch 	rxq.showiv = 1;
   2953       1.1  yamaguch 	rxq.rxmax = htole16(IXL_HARDMTU);
   2954       1.1  yamaguch 	rxq.tphrdesc_ena = 0;
   2955       1.1  yamaguch 	rxq.tphwdesc_ena = 0;
   2956       1.1  yamaguch 	rxq.tphdata_ena = 0;
   2957       1.1  yamaguch 	rxq.tphhead_ena = 0;
   2958       1.1  yamaguch 	rxq.lrxqthresh = 0;
   2959       1.1  yamaguch 	rxq.prefena = 1;
   2960       1.1  yamaguch 
   2961       1.1  yamaguch 	hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_RX, rxr->rxr_qid);
   2962       1.1  yamaguch 	memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_RX));
   2963       1.1  yamaguch 	ixl_hmc_pack(hmc, &rxq, ixl_hmc_pack_rxq,
   2964       1.1  yamaguch 	    __arraycount(ixl_hmc_pack_rxq));
   2965       1.1  yamaguch }
   2966       1.1  yamaguch 
   2967       1.1  yamaguch static void
   2968       1.1  yamaguch ixl_rxr_unconfig(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2969       1.1  yamaguch {
   2970       1.1  yamaguch 	void *hmc;
   2971       1.1  yamaguch 
   2972       1.1  yamaguch 	hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_RX, rxr->rxr_qid);
   2973       1.1  yamaguch 	memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_RX));
   2974       1.1  yamaguch }
   2975       1.1  yamaguch 
   2976       1.1  yamaguch static void
   2977       1.1  yamaguch ixl_rxr_free(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   2978       1.1  yamaguch {
   2979       1.1  yamaguch 	struct ixl_rx_map *maps, *rxm;
   2980       1.1  yamaguch 	unsigned int i;
   2981       1.1  yamaguch 
   2982       1.1  yamaguch 	maps = rxr->rxr_maps;
   2983       1.1  yamaguch 	for (i = 0; i < sc->sc_rx_ring_ndescs; i++) {
   2984       1.1  yamaguch 		rxm = &maps[i];
   2985       1.1  yamaguch 
   2986       1.1  yamaguch 		bus_dmamap_destroy(sc->sc_dmat, rxm->rxm_map);
   2987       1.1  yamaguch 	}
   2988       1.1  yamaguch 
   2989       1.1  yamaguch 	ixl_dmamem_free(sc, &rxr->rxr_mem);
   2990       1.1  yamaguch 	mutex_destroy(&rxr->rxr_lock);
   2991       1.1  yamaguch 	kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs);
   2992       1.1  yamaguch 	kmem_free(rxr, sizeof(*rxr));
   2993       1.1  yamaguch }
   2994       1.1  yamaguch 
   2995      1.14  yamaguch static inline void
   2996      1.14  yamaguch ixl_rx_csum(struct mbuf *m, uint64_t qword)
   2997      1.14  yamaguch {
   2998      1.14  yamaguch 	int flags_mask;
   2999      1.14  yamaguch 
   3000      1.14  yamaguch 	if (!ISSET(qword, IXL_RX_DESC_L3L4P)) {
   3001      1.14  yamaguch 		/* No L3 or L4 checksum was calculated */
   3002      1.14  yamaguch 		return;
   3003      1.14  yamaguch 	}
   3004      1.14  yamaguch 
   3005      1.14  yamaguch 	switch (__SHIFTOUT(qword, IXL_RX_DESC_PTYPE_MASK)) {
   3006      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_IPV4FRAG:
   3007      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_IPV4:
   3008      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_SCTPV4:
   3009      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_ICMPV4:
   3010      1.14  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   3011      1.14  yamaguch 		break;
   3012      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_TCPV4:
   3013      1.14  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   3014      1.14  yamaguch 		flags_mask |= M_CSUM_TCPv4 | M_CSUM_TCP_UDP_BAD;
   3015      1.14  yamaguch 		break;
   3016      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_UDPV4:
   3017      1.14  yamaguch 		flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD;
   3018      1.14  yamaguch 		flags_mask |= M_CSUM_UDPv4 | M_CSUM_TCP_UDP_BAD;
   3019      1.14  yamaguch 		break;
   3020      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_TCPV6:
   3021      1.14  yamaguch 		flags_mask = M_CSUM_TCPv6 | M_CSUM_TCP_UDP_BAD;
   3022      1.14  yamaguch 		break;
   3023      1.14  yamaguch 	case IXL_RX_DESC_PTYPE_UDPV6:
   3024      1.14  yamaguch 		flags_mask = M_CSUM_UDPv6 | M_CSUM_TCP_UDP_BAD;
   3025      1.14  yamaguch 		break;
   3026      1.14  yamaguch 	default:
   3027      1.14  yamaguch 		flags_mask = 0;
   3028      1.14  yamaguch 	}
   3029      1.14  yamaguch 
   3030      1.14  yamaguch 	m->m_pkthdr.csum_flags |= (flags_mask & (M_CSUM_IPv4 |
   3031      1.14  yamaguch 	    M_CSUM_TCPv4 | M_CSUM_TCPv6 | M_CSUM_UDPv4 | M_CSUM_UDPv6));
   3032      1.14  yamaguch 
   3033      1.14  yamaguch 	if (ISSET(qword, IXL_RX_DESC_IPE)) {
   3034      1.14  yamaguch 		m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_IPv4_BAD);
   3035      1.14  yamaguch 	}
   3036      1.14  yamaguch 
   3037      1.14  yamaguch 	if (ISSET(qword, IXL_RX_DESC_L4E)) {
   3038      1.14  yamaguch 		m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_TCP_UDP_BAD);
   3039      1.14  yamaguch 	}
   3040      1.14  yamaguch }
   3041      1.14  yamaguch 
   3042       1.1  yamaguch static int
   3043       1.1  yamaguch ixl_rxeof(struct ixl_softc *sc, struct ixl_rx_ring *rxr, u_int rxlimit)
   3044       1.1  yamaguch {
   3045       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   3046      1.11  yamaguch 	struct ixl_rx_wb_desc_32 *ring, *rxd;
   3047       1.1  yamaguch 	struct ixl_rx_map *rxm;
   3048       1.1  yamaguch 	bus_dmamap_t map;
   3049       1.1  yamaguch 	unsigned int cons, prod;
   3050       1.1  yamaguch 	struct mbuf *m;
   3051      1.11  yamaguch 	uint64_t word, word0;
   3052       1.1  yamaguch 	unsigned int len;
   3053       1.1  yamaguch 	unsigned int mask;
   3054       1.1  yamaguch 	int done = 0, more = 0;
   3055       1.1  yamaguch 
   3056       1.1  yamaguch 	KASSERT(mutex_owned(&rxr->rxr_lock));
   3057       1.1  yamaguch 
   3058       1.1  yamaguch 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
   3059       1.1  yamaguch 		return 0;
   3060       1.1  yamaguch 
   3061       1.1  yamaguch 	prod = rxr->rxr_prod;
   3062       1.1  yamaguch 	cons = rxr->rxr_cons;
   3063       1.1  yamaguch 
   3064       1.1  yamaguch 	if (cons == prod)
   3065       1.1  yamaguch 		return 0;
   3066       1.1  yamaguch 
   3067       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem),
   3068       1.1  yamaguch 	    0, IXL_DMA_LEN(&rxr->rxr_mem),
   3069       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   3070       1.1  yamaguch 
   3071       1.1  yamaguch 	ring = IXL_DMA_KVA(&rxr->rxr_mem);
   3072       1.1  yamaguch 	mask = sc->sc_rx_ring_ndescs - 1;
   3073       1.1  yamaguch 
   3074       1.1  yamaguch 	do {
   3075       1.1  yamaguch 		if (rxlimit-- <= 0) {
   3076       1.1  yamaguch 			more = 1;
   3077       1.1  yamaguch 			break;
   3078       1.1  yamaguch 		}
   3079       1.1  yamaguch 
   3080       1.1  yamaguch 		rxd = &ring[cons];
   3081       1.1  yamaguch 
   3082       1.1  yamaguch 		word = le64toh(rxd->qword1);
   3083       1.1  yamaguch 
   3084       1.1  yamaguch 		if (!ISSET(word, IXL_RX_DESC_DD))
   3085       1.1  yamaguch 			break;
   3086       1.1  yamaguch 
   3087       1.1  yamaguch 		rxm = &rxr->rxr_maps[cons];
   3088       1.1  yamaguch 
   3089       1.1  yamaguch 		map = rxm->rxm_map;
   3090       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   3091       1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   3092       1.1  yamaguch 		bus_dmamap_unload(sc->sc_dmat, map);
   3093       1.1  yamaguch 
   3094       1.1  yamaguch 		m = rxm->rxm_m;
   3095       1.1  yamaguch 		rxm->rxm_m = NULL;
   3096       1.1  yamaguch 
   3097       1.1  yamaguch 		KASSERT(m != NULL);
   3098       1.1  yamaguch 
   3099       1.1  yamaguch 		len = (word & IXL_RX_DESC_PLEN_MASK) >> IXL_RX_DESC_PLEN_SHIFT;
   3100       1.1  yamaguch 		m->m_len = len;
   3101       1.1  yamaguch 		m->m_pkthdr.len = 0;
   3102       1.1  yamaguch 
   3103       1.1  yamaguch 		m->m_next = NULL;
   3104       1.1  yamaguch 		*rxr->rxr_m_tail = m;
   3105       1.1  yamaguch 		rxr->rxr_m_tail = &m->m_next;
   3106       1.1  yamaguch 
   3107       1.1  yamaguch 		m = rxr->rxr_m_head;
   3108       1.1  yamaguch 		m->m_pkthdr.len += len;
   3109       1.1  yamaguch 
   3110       1.1  yamaguch 		if (ISSET(word, IXL_RX_DESC_EOP)) {
   3111      1.11  yamaguch 			word0 = le64toh(rxd->qword0);
   3112      1.11  yamaguch 
   3113      1.11  yamaguch 			if (ISSET(word, IXL_RX_DESC_L2TAG1P)) {
   3114      1.11  yamaguch 				vlan_set_tag(m,
   3115      1.11  yamaguch 				    __SHIFTOUT(word0, IXL_RX_DESC_L2TAG1_MASK));
   3116      1.11  yamaguch 			}
   3117      1.11  yamaguch 
   3118      1.14  yamaguch 			if ((ifp->if_capenable & IXL_IFCAP_RXCSUM) != 0)
   3119      1.14  yamaguch 				ixl_rx_csum(m, word);
   3120      1.14  yamaguch 
   3121       1.1  yamaguch 			if (!ISSET(word,
   3122       1.1  yamaguch 			    IXL_RX_DESC_RXE | IXL_RX_DESC_OVERSIZE)) {
   3123       1.1  yamaguch 				m_set_rcvif(m, ifp);
   3124       1.1  yamaguch 				rxr->rxr_ipackets++;
   3125       1.1  yamaguch 				rxr->rxr_ibytes += m->m_pkthdr.len;
   3126       1.1  yamaguch 				if_percpuq_enqueue(ifp->if_percpuq, m);
   3127       1.1  yamaguch 			} else {
   3128       1.1  yamaguch 				rxr->rxr_ierrors++;
   3129       1.1  yamaguch 				m_freem(m);
   3130       1.1  yamaguch 			}
   3131       1.1  yamaguch 
   3132       1.1  yamaguch 			rxr->rxr_m_head = NULL;
   3133       1.1  yamaguch 			rxr->rxr_m_tail = &rxr->rxr_m_head;
   3134       1.1  yamaguch 		}
   3135       1.1  yamaguch 
   3136       1.1  yamaguch 		cons++;
   3137       1.1  yamaguch 		cons &= mask;
   3138       1.1  yamaguch 
   3139       1.1  yamaguch 		done = 1;
   3140       1.1  yamaguch 	} while (cons != prod);
   3141       1.1  yamaguch 
   3142       1.1  yamaguch 	if (done) {
   3143       1.1  yamaguch 		rxr->rxr_cons = cons;
   3144       1.1  yamaguch 		if (ixl_rxfill(sc, rxr) == -1)
   3145       1.1  yamaguch 			rxr->rxr_iqdrops++;
   3146       1.1  yamaguch 	}
   3147       1.1  yamaguch 
   3148       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem),
   3149       1.1  yamaguch 	    0, IXL_DMA_LEN(&rxr->rxr_mem),
   3150       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   3151       1.1  yamaguch 
   3152       1.1  yamaguch 	return more;
   3153       1.1  yamaguch }
   3154       1.1  yamaguch 
   3155       1.1  yamaguch static int
   3156       1.1  yamaguch ixl_rxfill(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
   3157       1.1  yamaguch {
   3158      1.11  yamaguch 	struct ixl_rx_rd_desc_32 *ring, *rxd;
   3159       1.1  yamaguch 	struct ixl_rx_map *rxm;
   3160       1.1  yamaguch 	bus_dmamap_t map;
   3161       1.1  yamaguch 	struct mbuf *m;
   3162       1.1  yamaguch 	unsigned int prod;
   3163       1.1  yamaguch 	unsigned int slots;
   3164       1.1  yamaguch 	unsigned int mask;
   3165       1.1  yamaguch 	int post = 0, error = 0;
   3166       1.1  yamaguch 
   3167       1.1  yamaguch 	KASSERT(mutex_owned(&rxr->rxr_lock));
   3168       1.1  yamaguch 
   3169       1.1  yamaguch 	prod = rxr->rxr_prod;
   3170       1.1  yamaguch 	slots = ixl_rxr_unrefreshed(rxr->rxr_prod, rxr->rxr_cons,
   3171       1.1  yamaguch 	    sc->sc_rx_ring_ndescs);
   3172       1.1  yamaguch 
   3173       1.1  yamaguch 	ring = IXL_DMA_KVA(&rxr->rxr_mem);
   3174       1.1  yamaguch 	mask = sc->sc_rx_ring_ndescs - 1;
   3175       1.1  yamaguch 
   3176       1.1  yamaguch 	if (__predict_false(slots <= 0))
   3177       1.1  yamaguch 		return -1;
   3178       1.1  yamaguch 
   3179       1.1  yamaguch 	do {
   3180       1.1  yamaguch 		rxm = &rxr->rxr_maps[prod];
   3181       1.1  yamaguch 
   3182       1.1  yamaguch 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   3183       1.1  yamaguch 		if (m == NULL) {
   3184       1.1  yamaguch 			rxr->rxr_mgethdr_failed.ev_count++;
   3185       1.1  yamaguch 			error = -1;
   3186       1.1  yamaguch 			break;
   3187       1.1  yamaguch 		}
   3188       1.1  yamaguch 
   3189       1.1  yamaguch 		MCLGET(m, M_DONTWAIT);
   3190       1.1  yamaguch 		if (!ISSET(m->m_flags, M_EXT)) {
   3191       1.1  yamaguch 			rxr->rxr_mgetcl_failed.ev_count++;
   3192       1.1  yamaguch 			error = -1;
   3193       1.1  yamaguch 			m_freem(m);
   3194       1.1  yamaguch 			break;
   3195       1.1  yamaguch 		}
   3196       1.1  yamaguch 
   3197       1.1  yamaguch 		m->m_len = m->m_pkthdr.len = MCLBYTES + ETHER_ALIGN;
   3198       1.1  yamaguch 		m_adj(m, ETHER_ALIGN);
   3199       1.1  yamaguch 
   3200       1.1  yamaguch 		map = rxm->rxm_map;
   3201       1.1  yamaguch 
   3202       1.1  yamaguch 		if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
   3203       1.1  yamaguch 		    BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) {
   3204       1.1  yamaguch 			rxr->rxr_mbuf_load_failed.ev_count++;
   3205       1.1  yamaguch 			error = -1;
   3206       1.1  yamaguch 			m_freem(m);
   3207       1.1  yamaguch 			break;
   3208       1.1  yamaguch 		}
   3209       1.1  yamaguch 
   3210       1.1  yamaguch 		rxm->rxm_m = m;
   3211       1.1  yamaguch 
   3212       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   3213       1.1  yamaguch 		    BUS_DMASYNC_PREREAD);
   3214       1.1  yamaguch 
   3215       1.1  yamaguch 		rxd = &ring[prod];
   3216       1.1  yamaguch 
   3217       1.1  yamaguch 		rxd->paddr = htole64(map->dm_segs[0].ds_addr);
   3218       1.1  yamaguch 		rxd->haddr = htole64(0);
   3219       1.1  yamaguch 
   3220       1.1  yamaguch 		prod++;
   3221       1.1  yamaguch 		prod &= mask;
   3222       1.1  yamaguch 
   3223       1.1  yamaguch 		post = 1;
   3224       1.1  yamaguch 
   3225       1.1  yamaguch 	} while (--slots);
   3226       1.1  yamaguch 
   3227       1.1  yamaguch 	if (post) {
   3228       1.1  yamaguch 		rxr->rxr_prod = prod;
   3229       1.1  yamaguch 		ixl_wr(sc, rxr->rxr_tail, prod);
   3230       1.1  yamaguch 	}
   3231       1.1  yamaguch 
   3232       1.1  yamaguch 	return error;
   3233       1.1  yamaguch }
   3234       1.1  yamaguch 
   3235       1.1  yamaguch static inline int
   3236       1.1  yamaguch ixl_handle_queue_common(struct ixl_softc *sc, struct ixl_queue_pair *qp,
   3237       1.1  yamaguch     u_int txlimit, struct evcnt *txevcnt,
   3238       1.1  yamaguch     u_int rxlimit, struct evcnt *rxevcnt)
   3239       1.1  yamaguch {
   3240       1.1  yamaguch 	struct ixl_tx_ring *txr = qp->qp_txr;
   3241       1.1  yamaguch 	struct ixl_rx_ring *rxr = qp->qp_rxr;
   3242       1.1  yamaguch 	int txmore, rxmore;
   3243       1.1  yamaguch 	int rv;
   3244       1.1  yamaguch 
   3245       1.1  yamaguch 	KASSERT(!mutex_owned(&txr->txr_lock));
   3246       1.1  yamaguch 	KASSERT(!mutex_owned(&rxr->rxr_lock));
   3247       1.1  yamaguch 
   3248       1.1  yamaguch 	mutex_enter(&txr->txr_lock);
   3249       1.1  yamaguch 	txevcnt->ev_count++;
   3250       1.1  yamaguch 	txmore = ixl_txeof(sc, txr, txlimit);
   3251       1.1  yamaguch 	mutex_exit(&txr->txr_lock);
   3252       1.1  yamaguch 
   3253       1.1  yamaguch 	mutex_enter(&rxr->rxr_lock);
   3254       1.1  yamaguch 	rxevcnt->ev_count++;
   3255       1.1  yamaguch 	rxmore = ixl_rxeof(sc, rxr, rxlimit);
   3256       1.1  yamaguch 	mutex_exit(&rxr->rxr_lock);
   3257       1.1  yamaguch 
   3258       1.1  yamaguch 	rv = txmore | (rxmore << 1);
   3259       1.1  yamaguch 
   3260       1.1  yamaguch 	return rv;
   3261       1.1  yamaguch }
   3262       1.1  yamaguch 
   3263       1.1  yamaguch static void
   3264       1.1  yamaguch ixl_sched_handle_queue(struct ixl_softc *sc, struct ixl_queue_pair *qp)
   3265       1.1  yamaguch {
   3266       1.1  yamaguch 
   3267       1.1  yamaguch 	if (qp->qp_workqueue)
   3268       1.1  yamaguch 		ixl_work_add(sc->sc_workq_txrx, &qp->qp_task);
   3269       1.1  yamaguch 	else
   3270       1.1  yamaguch 		softint_schedule(qp->qp_si);
   3271       1.1  yamaguch }
   3272       1.1  yamaguch 
   3273       1.1  yamaguch static int
   3274       1.1  yamaguch ixl_intr(void *xsc)
   3275       1.1  yamaguch {
   3276       1.1  yamaguch 	struct ixl_softc *sc = xsc;
   3277       1.1  yamaguch 	struct ixl_tx_ring *txr;
   3278       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   3279       1.1  yamaguch 	uint32_t icr, rxintr, txintr;
   3280       1.1  yamaguch 	int rv = 0;
   3281       1.1  yamaguch 	unsigned int i;
   3282       1.1  yamaguch 
   3283       1.1  yamaguch 	KASSERT(sc != NULL);
   3284       1.1  yamaguch 
   3285       1.1  yamaguch 	ixl_enable_other_intr(sc);
   3286       1.1  yamaguch 	icr = ixl_rd(sc, I40E_PFINT_ICR0);
   3287       1.1  yamaguch 
   3288       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_ADMINQ_MASK)) {
   3289       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_atq.ev_count);
   3290       1.1  yamaguch 		ixl_atq_done(sc);
   3291       1.1  yamaguch 		ixl_work_add(sc->sc_workq, &sc->sc_arq_task);
   3292       1.1  yamaguch 		rv = 1;
   3293       1.1  yamaguch 	}
   3294       1.1  yamaguch 
   3295       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK)) {
   3296       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_link.ev_count);
   3297       1.1  yamaguch 		ixl_work_add(sc->sc_workq, &sc->sc_link_state_task);
   3298       1.1  yamaguch 		rv = 1;
   3299       1.1  yamaguch 	}
   3300       1.1  yamaguch 
   3301       1.1  yamaguch 	rxintr = icr & I40E_INTR_NOTX_RX_MASK;
   3302       1.1  yamaguch 	txintr = icr & I40E_INTR_NOTX_TX_MASK;
   3303       1.1  yamaguch 
   3304       1.1  yamaguch 	if (txintr || rxintr) {
   3305       1.1  yamaguch 		for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   3306       1.1  yamaguch 			txr = sc->sc_qps[i].qp_txr;
   3307       1.1  yamaguch 			rxr = sc->sc_qps[i].qp_rxr;
   3308       1.1  yamaguch 
   3309       1.1  yamaguch 			ixl_handle_queue_common(sc, &sc->sc_qps[i],
   3310       1.1  yamaguch 			    IXL_TXRX_PROCESS_UNLIMIT, &txr->txr_intr,
   3311       1.1  yamaguch 			    IXL_TXRX_PROCESS_UNLIMIT, &rxr->rxr_intr);
   3312       1.1  yamaguch 		}
   3313       1.1  yamaguch 		rv = 1;
   3314       1.1  yamaguch 	}
   3315       1.1  yamaguch 
   3316       1.1  yamaguch 	return rv;
   3317       1.1  yamaguch }
   3318       1.1  yamaguch 
   3319       1.1  yamaguch static int
   3320       1.1  yamaguch ixl_queue_intr(void *xqp)
   3321       1.1  yamaguch {
   3322       1.1  yamaguch 	struct ixl_queue_pair *qp = xqp;
   3323       1.1  yamaguch 	struct ixl_tx_ring *txr = qp->qp_txr;
   3324       1.1  yamaguch 	struct ixl_rx_ring *rxr = qp->qp_rxr;
   3325       1.1  yamaguch 	struct ixl_softc *sc = qp->qp_sc;
   3326       1.1  yamaguch 	u_int txlimit, rxlimit;
   3327       1.1  yamaguch 	int more;
   3328       1.1  yamaguch 
   3329       1.1  yamaguch 	txlimit = sc->sc_tx_intr_process_limit;
   3330       1.1  yamaguch 	rxlimit = sc->sc_rx_intr_process_limit;
   3331       1.1  yamaguch 	qp->qp_workqueue = sc->sc_txrx_workqueue;
   3332       1.1  yamaguch 
   3333       1.1  yamaguch 	more = ixl_handle_queue_common(sc, qp,
   3334       1.1  yamaguch 	    txlimit, &txr->txr_intr, rxlimit, &rxr->rxr_intr);
   3335       1.1  yamaguch 
   3336       1.1  yamaguch 	if (more != 0) {
   3337       1.1  yamaguch 		ixl_sched_handle_queue(sc, qp);
   3338       1.1  yamaguch 	} else {
   3339       1.1  yamaguch 		/* for ALTQ */
   3340       1.1  yamaguch 		if (txr->txr_qid == 0)
   3341       1.1  yamaguch 			if_schedule_deferred_start(&sc->sc_ec.ec_if);
   3342       1.1  yamaguch 		softint_schedule(txr->txr_si);
   3343       1.1  yamaguch 
   3344       1.1  yamaguch 		ixl_enable_queue_intr(sc, qp);
   3345       1.1  yamaguch 	}
   3346       1.1  yamaguch 
   3347       1.1  yamaguch 	return 1;
   3348       1.1  yamaguch }
   3349       1.1  yamaguch 
   3350       1.1  yamaguch static void
   3351       1.1  yamaguch ixl_handle_queue(void *xqp)
   3352       1.1  yamaguch {
   3353       1.1  yamaguch 	struct ixl_queue_pair *qp = xqp;
   3354       1.1  yamaguch 	struct ixl_softc *sc = qp->qp_sc;
   3355       1.1  yamaguch 	struct ixl_tx_ring *txr = qp->qp_txr;
   3356       1.1  yamaguch 	struct ixl_rx_ring *rxr = qp->qp_rxr;
   3357       1.1  yamaguch 	u_int txlimit, rxlimit;
   3358       1.1  yamaguch 	int more;
   3359       1.1  yamaguch 
   3360       1.1  yamaguch 	txlimit = sc->sc_tx_process_limit;
   3361       1.1  yamaguch 	rxlimit = sc->sc_rx_process_limit;
   3362       1.1  yamaguch 
   3363       1.1  yamaguch 	more = ixl_handle_queue_common(sc, qp,
   3364       1.1  yamaguch 	    txlimit, &txr->txr_defer, rxlimit, &rxr->rxr_defer);
   3365       1.1  yamaguch 
   3366       1.1  yamaguch 	if (more != 0)
   3367       1.1  yamaguch 		ixl_sched_handle_queue(sc, qp);
   3368       1.1  yamaguch 	else
   3369       1.1  yamaguch 		ixl_enable_queue_intr(sc, qp);
   3370       1.1  yamaguch }
   3371       1.1  yamaguch 
   3372       1.1  yamaguch static inline void
   3373       1.1  yamaguch ixl_print_hmc_error(struct ixl_softc *sc, uint32_t reg)
   3374       1.1  yamaguch {
   3375       1.1  yamaguch 	uint32_t hmc_idx, hmc_isvf;
   3376       1.1  yamaguch 	uint32_t hmc_errtype, hmc_objtype, hmc_data;
   3377       1.1  yamaguch 
   3378       1.1  yamaguch 	hmc_idx = reg & I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK;
   3379       1.1  yamaguch 	hmc_idx = hmc_idx >> I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT;
   3380       1.1  yamaguch 	hmc_isvf = reg & I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK;
   3381       1.1  yamaguch 	hmc_isvf = hmc_isvf >> I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT;
   3382       1.1  yamaguch 	hmc_errtype = reg & I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK;
   3383       1.1  yamaguch 	hmc_errtype = hmc_errtype >> I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT;
   3384       1.1  yamaguch 	hmc_objtype = reg & I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK;
   3385       1.1  yamaguch 	hmc_objtype = hmc_objtype >> I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT;
   3386       1.1  yamaguch 	hmc_data = ixl_rd(sc, I40E_PFHMC_ERRORDATA);
   3387       1.1  yamaguch 
   3388       1.1  yamaguch 	device_printf(sc->sc_dev,
   3389       1.1  yamaguch 	    "HMC Error (idx=0x%x, isvf=0x%x, err=0x%x, obj=0x%x, data=0x%x)\n",
   3390       1.1  yamaguch 	    hmc_idx, hmc_isvf, hmc_errtype, hmc_objtype, hmc_data);
   3391       1.1  yamaguch }
   3392       1.1  yamaguch 
   3393       1.1  yamaguch static int
   3394       1.1  yamaguch ixl_other_intr(void *xsc)
   3395       1.1  yamaguch {
   3396       1.1  yamaguch 	struct ixl_softc *sc = xsc;
   3397       1.1  yamaguch 	uint32_t icr, mask, reg;
   3398       1.1  yamaguch 	int rv;
   3399       1.1  yamaguch 
   3400       1.1  yamaguch 	icr = ixl_rd(sc, I40E_PFINT_ICR0);
   3401       1.1  yamaguch 	mask = ixl_rd(sc, I40E_PFINT_ICR0_ENA);
   3402       1.1  yamaguch 
   3403       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_ADMINQ_MASK)) {
   3404       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_atq.ev_count);
   3405       1.1  yamaguch 		ixl_atq_done(sc);
   3406       1.1  yamaguch 		ixl_work_add(sc->sc_workq, &sc->sc_arq_task);
   3407       1.1  yamaguch 		rv = 1;
   3408       1.1  yamaguch 	}
   3409       1.1  yamaguch 
   3410       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK)) {
   3411       1.1  yamaguch 		if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG))
   3412       1.1  yamaguch 			device_printf(sc->sc_dev, "link stat changed\n");
   3413       1.1  yamaguch 
   3414       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_link.ev_count);
   3415       1.1  yamaguch 		ixl_work_add(sc->sc_workq, &sc->sc_link_state_task);
   3416       1.1  yamaguch 		rv = 1;
   3417       1.1  yamaguch 	}
   3418       1.1  yamaguch 
   3419       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_GRST_MASK)) {
   3420       1.1  yamaguch 		CLR(mask, I40E_PFINT_ICR0_ENA_GRST_MASK);
   3421       1.1  yamaguch 		reg = ixl_rd(sc, I40E_GLGEN_RSTAT);
   3422       1.1  yamaguch 		reg = reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK;
   3423       1.1  yamaguch 		reg = reg >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
   3424       1.1  yamaguch 
   3425       1.1  yamaguch 		device_printf(sc->sc_dev, "GRST: %s\n",
   3426       1.1  yamaguch 		    reg == I40E_RESET_CORER ? "CORER" :
   3427       1.1  yamaguch 		    reg == I40E_RESET_GLOBR ? "GLOBR" :
   3428       1.1  yamaguch 		    reg == I40E_RESET_EMPR ? "EMPR" :
   3429       1.1  yamaguch 		    "POR");
   3430       1.1  yamaguch 	}
   3431       1.1  yamaguch 
   3432       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_ECC_ERR_MASK))
   3433       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_ecc_err.ev_count);
   3434       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_PCI_EXCEPTION_MASK))
   3435       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_pci_exception.ev_count);
   3436       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_PE_CRITERR_MASK))
   3437       1.1  yamaguch 		atomic_inc_64(&sc->sc_event_crit_err.ev_count);
   3438       1.1  yamaguch 
   3439       1.1  yamaguch 	if (ISSET(icr, IXL_ICR0_CRIT_ERR_MASK)) {
   3440       1.1  yamaguch 		CLR(mask, IXL_ICR0_CRIT_ERR_MASK);
   3441       1.1  yamaguch 		device_printf(sc->sc_dev, "critical error\n");
   3442       1.1  yamaguch 	}
   3443       1.1  yamaguch 
   3444       1.1  yamaguch 	if (ISSET(icr, I40E_PFINT_ICR0_HMC_ERR_MASK)) {
   3445       1.1  yamaguch 		reg = ixl_rd(sc, I40E_PFHMC_ERRORINFO);
   3446       1.1  yamaguch 		if (ISSET(reg, I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK))
   3447       1.1  yamaguch 			ixl_print_hmc_error(sc, reg);
   3448       1.1  yamaguch 		ixl_wr(sc, I40E_PFHMC_ERRORINFO, 0);
   3449       1.1  yamaguch 	}
   3450       1.1  yamaguch 
   3451       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ICR0_ENA, mask);
   3452       1.1  yamaguch 	ixl_flush(sc);
   3453       1.1  yamaguch 	ixl_enable_other_intr(sc);
   3454       1.1  yamaguch 	return rv;
   3455       1.1  yamaguch }
   3456       1.1  yamaguch 
   3457       1.1  yamaguch static void
   3458       1.4  yamaguch ixl_get_link_status_done(struct ixl_softc *sc,
   3459       1.4  yamaguch     const struct ixl_aq_desc *iaq)
   3460       1.1  yamaguch {
   3461       1.1  yamaguch 
   3462       1.4  yamaguch 	ixl_link_state_update(sc, iaq);
   3463       1.1  yamaguch }
   3464       1.1  yamaguch 
   3465       1.1  yamaguch static void
   3466       1.4  yamaguch ixl_get_link_status(void *xsc)
   3467       1.1  yamaguch {
   3468       1.1  yamaguch 	struct ixl_softc *sc = xsc;
   3469       1.1  yamaguch 	struct ixl_aq_desc *iaq;
   3470       1.1  yamaguch 	struct ixl_aq_link_param *param;
   3471       1.1  yamaguch 
   3472       1.1  yamaguch 	memset(&sc->sc_link_state_atq, 0, sizeof(sc->sc_link_state_atq));
   3473       1.1  yamaguch 	iaq = &sc->sc_link_state_atq.iatq_desc;
   3474       1.1  yamaguch 	iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS);
   3475       1.1  yamaguch 	param = (struct ixl_aq_link_param *)iaq->iaq_param;
   3476       1.1  yamaguch 	param->notify = IXL_AQ_LINK_NOTIFY;
   3477       1.1  yamaguch 
   3478       1.4  yamaguch 	ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done);
   3479       1.1  yamaguch 	(void)ixl_atq_post(sc, &sc->sc_link_state_atq);
   3480       1.1  yamaguch }
   3481       1.1  yamaguch 
   3482       1.1  yamaguch static void
   3483       1.4  yamaguch ixl_link_state_update(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
   3484       1.1  yamaguch {
   3485       1.1  yamaguch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   3486       1.1  yamaguch 	int link_state;
   3487       1.1  yamaguch 
   3488      1.16  yamaguch 	KASSERT(kpreempt_disabled());
   3489      1.16  yamaguch 
   3490       1.1  yamaguch 	link_state = ixl_set_link_status(sc, iaq);
   3491       1.1  yamaguch 
   3492       1.1  yamaguch 	if (ifp->if_link_state != link_state)
   3493       1.1  yamaguch 		if_link_state_change(ifp, link_state);
   3494       1.1  yamaguch 
   3495       1.1  yamaguch 	if (link_state != LINK_STATE_DOWN) {
   3496       1.1  yamaguch 		if_schedule_deferred_start(ifp);
   3497       1.1  yamaguch 	}
   3498       1.1  yamaguch }
   3499       1.1  yamaguch 
   3500       1.1  yamaguch static void
   3501       1.4  yamaguch ixl_aq_dump(const struct ixl_softc *sc, const struct ixl_aq_desc *iaq,
   3502       1.4  yamaguch     const char *msg)
   3503       1.1  yamaguch {
   3504       1.1  yamaguch 	char	 buf[512];
   3505       1.1  yamaguch 	size_t	 len;
   3506       1.1  yamaguch 
   3507       1.1  yamaguch 	len = sizeof(buf);
   3508       1.1  yamaguch 	buf[--len] = '\0';
   3509       1.1  yamaguch 
   3510       1.4  yamaguch 	device_printf(sc->sc_dev, "%s\n", msg);
   3511       1.1  yamaguch 	snprintb(buf, len, IXL_AQ_FLAGS_FMT, le16toh(iaq->iaq_flags));
   3512       1.1  yamaguch 	device_printf(sc->sc_dev, "flags %s opcode %04x\n",
   3513       1.1  yamaguch 	    buf, le16toh(iaq->iaq_opcode));
   3514       1.1  yamaguch 	device_printf(sc->sc_dev, "datalen %u retval %u\n",
   3515       1.1  yamaguch 	    le16toh(iaq->iaq_datalen), le16toh(iaq->iaq_retval));
   3516       1.1  yamaguch 	device_printf(sc->sc_dev, "cookie %016" PRIx64 "\n", iaq->iaq_cookie);
   3517       1.1  yamaguch 	device_printf(sc->sc_dev, "%08x %08x %08x %08x\n",
   3518       1.1  yamaguch 	    le32toh(iaq->iaq_param[0]), le32toh(iaq->iaq_param[1]),
   3519       1.1  yamaguch 	    le32toh(iaq->iaq_param[2]), le32toh(iaq->iaq_param[3]));
   3520       1.1  yamaguch }
   3521       1.1  yamaguch 
   3522       1.1  yamaguch static void
   3523       1.1  yamaguch ixl_arq(void *xsc)
   3524       1.1  yamaguch {
   3525       1.1  yamaguch 	struct ixl_softc *sc = xsc;
   3526       1.1  yamaguch 	struct ixl_aq_desc *arq, *iaq;
   3527       1.1  yamaguch 	struct ixl_aq_buf *aqb;
   3528       1.1  yamaguch 	unsigned int cons = sc->sc_arq_cons;
   3529       1.1  yamaguch 	unsigned int prod;
   3530       1.1  yamaguch 	int done = 0;
   3531       1.1  yamaguch 
   3532       1.1  yamaguch 	prod = ixl_rd(sc, sc->sc_aq_regs->arq_head) &
   3533       1.1  yamaguch 	    sc->sc_aq_regs->arq_head_mask;
   3534       1.1  yamaguch 
   3535       1.1  yamaguch 	if (cons == prod)
   3536       1.1  yamaguch 		goto done;
   3537       1.1  yamaguch 
   3538       1.1  yamaguch 	arq = IXL_DMA_KVA(&sc->sc_arq);
   3539       1.1  yamaguch 
   3540       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   3541       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_arq),
   3542       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   3543       1.1  yamaguch 
   3544       1.1  yamaguch 	do {
   3545       1.1  yamaguch 		iaq = &arq[cons];
   3546       1.1  yamaguch 		aqb = sc->sc_arq_live[cons];
   3547       1.1  yamaguch 
   3548       1.1  yamaguch 		KASSERT(aqb != NULL);
   3549       1.1  yamaguch 
   3550       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, IXL_AQ_BUFLEN,
   3551       1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   3552       1.1  yamaguch 
   3553       1.1  yamaguch 		if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG))
   3554       1.4  yamaguch 			ixl_aq_dump(sc, iaq, "arq event");
   3555       1.1  yamaguch 
   3556       1.1  yamaguch 		switch (iaq->iaq_opcode) {
   3557       1.1  yamaguch 		case htole16(IXL_AQ_OP_PHY_LINK_STATUS):
   3558      1.16  yamaguch 			kpreempt_disable();
   3559       1.4  yamaguch 			ixl_link_state_update(sc, iaq);
   3560      1.16  yamaguch 			kpreempt_enable();
   3561       1.1  yamaguch 			break;
   3562       1.1  yamaguch 		}
   3563       1.1  yamaguch 
   3564       1.1  yamaguch 		memset(iaq, 0, sizeof(*iaq));
   3565       1.1  yamaguch 		sc->sc_arq_live[cons] = NULL;
   3566       1.1  yamaguch 		SIMPLEQ_INSERT_TAIL(&sc->sc_arq_idle, aqb, aqb_entry);
   3567       1.1  yamaguch 
   3568       1.1  yamaguch 		cons++;
   3569       1.1  yamaguch 		cons &= IXL_AQ_MASK;
   3570       1.1  yamaguch 
   3571       1.1  yamaguch 		done = 1;
   3572       1.1  yamaguch 	} while (cons != prod);
   3573       1.1  yamaguch 
   3574       1.1  yamaguch 	if (done) {
   3575       1.1  yamaguch 		sc->sc_arq_cons = cons;
   3576       1.1  yamaguch 		ixl_arq_fill(sc);
   3577       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq),
   3578       1.1  yamaguch 		    0, IXL_DMA_LEN(&sc->sc_arq),
   3579       1.1  yamaguch 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   3580       1.1  yamaguch 	}
   3581       1.1  yamaguch 
   3582       1.1  yamaguch done:
   3583       1.1  yamaguch 	ixl_enable_other_intr(sc);
   3584       1.1  yamaguch }
   3585       1.1  yamaguch 
   3586       1.1  yamaguch static void
   3587       1.4  yamaguch ixl_atq_set(struct ixl_atq *iatq,
   3588       1.4  yamaguch     void (*fn)(struct ixl_softc *, const struct ixl_aq_desc *))
   3589       1.1  yamaguch {
   3590       1.4  yamaguch 
   3591       1.1  yamaguch 	iatq->iatq_fn = fn;
   3592       1.1  yamaguch }
   3593       1.1  yamaguch 
   3594       1.1  yamaguch static int
   3595       1.1  yamaguch ixl_atq_post_locked(struct ixl_softc *sc, struct ixl_atq *iatq)
   3596       1.1  yamaguch {
   3597       1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   3598       1.1  yamaguch 	unsigned int prod, cons, prod_next;
   3599       1.1  yamaguch 
   3600       1.1  yamaguch 	/* assert locked */
   3601       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_atq_lock));
   3602       1.1  yamaguch 
   3603       1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   3604       1.1  yamaguch 	prod = sc->sc_atq_prod;
   3605       1.1  yamaguch 	cons = sc->sc_atq_cons;
   3606       1.1  yamaguch 	prod_next = (prod +1) & IXL_AQ_MASK;
   3607       1.1  yamaguch 
   3608       1.1  yamaguch 	if (cons == prod_next)
   3609       1.1  yamaguch 		return ENOMEM;
   3610       1.1  yamaguch 
   3611       1.1  yamaguch 	slot = &atq[prod];
   3612       1.1  yamaguch 
   3613       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3614       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE);
   3615       1.1  yamaguch 
   3616       1.1  yamaguch 	*slot = iatq->iatq_desc;
   3617       1.1  yamaguch 	slot->iaq_cookie = (uint64_t)((intptr_t)iatq);
   3618       1.1  yamaguch 
   3619       1.1  yamaguch 	if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG))
   3620       1.4  yamaguch 		ixl_aq_dump(sc, slot, "atq command");
   3621       1.1  yamaguch 
   3622       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3623       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE);
   3624       1.1  yamaguch 
   3625       1.1  yamaguch 	sc->sc_atq_prod = prod_next;
   3626       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_tail, sc->sc_atq_prod);
   3627       1.1  yamaguch 
   3628       1.1  yamaguch 	return 0;
   3629       1.1  yamaguch }
   3630       1.1  yamaguch 
   3631       1.1  yamaguch static int
   3632       1.1  yamaguch ixl_atq_post(struct ixl_softc *sc, struct ixl_atq *iatq)
   3633       1.1  yamaguch {
   3634       1.1  yamaguch 	int rv;
   3635       1.1  yamaguch 
   3636       1.1  yamaguch 	mutex_enter(&sc->sc_atq_lock);
   3637       1.1  yamaguch 	rv = ixl_atq_post_locked(sc, iatq);
   3638       1.1  yamaguch 	mutex_exit(&sc->sc_atq_lock);
   3639       1.1  yamaguch 
   3640       1.1  yamaguch 	return rv;
   3641       1.1  yamaguch }
   3642       1.1  yamaguch 
   3643       1.1  yamaguch static void
   3644       1.1  yamaguch ixl_atq_done_locked(struct ixl_softc *sc)
   3645       1.1  yamaguch {
   3646       1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   3647       1.1  yamaguch 	struct ixl_atq *iatq;
   3648       1.1  yamaguch 	unsigned int cons;
   3649       1.1  yamaguch 	unsigned int prod;
   3650       1.1  yamaguch 
   3651       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_atq_lock));
   3652       1.1  yamaguch 
   3653       1.1  yamaguch 	prod = sc->sc_atq_prod;
   3654       1.1  yamaguch 	cons = sc->sc_atq_cons;
   3655       1.1  yamaguch 
   3656       1.1  yamaguch 	if (prod == cons)
   3657       1.1  yamaguch 		return;
   3658       1.1  yamaguch 
   3659       1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   3660       1.1  yamaguch 
   3661       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3662       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   3663       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   3664       1.1  yamaguch 
   3665       1.1  yamaguch 	do {
   3666       1.1  yamaguch 		slot = &atq[cons];
   3667       1.1  yamaguch 		if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD)))
   3668       1.1  yamaguch 			break;
   3669       1.1  yamaguch 
   3670       1.1  yamaguch 		iatq = (struct ixl_atq *)((intptr_t)slot->iaq_cookie);
   3671       1.1  yamaguch 		iatq->iatq_desc = *slot;
   3672       1.1  yamaguch 
   3673       1.1  yamaguch 		memset(slot, 0, sizeof(*slot));
   3674       1.1  yamaguch 
   3675       1.4  yamaguch 		if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG))
   3676       1.4  yamaguch 			ixl_aq_dump(sc, &iatq->iatq_desc, "atq response");
   3677       1.4  yamaguch 
   3678       1.4  yamaguch 		(*iatq->iatq_fn)(sc, &iatq->iatq_desc);
   3679       1.1  yamaguch 
   3680       1.1  yamaguch 		cons++;
   3681       1.1  yamaguch 		cons &= IXL_AQ_MASK;
   3682       1.1  yamaguch 	} while (cons != prod);
   3683       1.1  yamaguch 
   3684       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3685       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq),
   3686       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   3687       1.1  yamaguch 
   3688       1.1  yamaguch 	sc->sc_atq_cons = cons;
   3689       1.1  yamaguch }
   3690       1.1  yamaguch 
   3691       1.1  yamaguch static void
   3692       1.1  yamaguch ixl_atq_done(struct ixl_softc *sc)
   3693       1.1  yamaguch {
   3694       1.1  yamaguch 
   3695       1.1  yamaguch 	mutex_enter(&sc->sc_atq_lock);
   3696       1.1  yamaguch 	ixl_atq_done_locked(sc);
   3697       1.1  yamaguch 	mutex_exit(&sc->sc_atq_lock);
   3698       1.1  yamaguch }
   3699       1.1  yamaguch 
   3700       1.1  yamaguch static void
   3701       1.4  yamaguch ixl_wakeup(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
   3702       1.1  yamaguch {
   3703       1.1  yamaguch 
   3704       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_atq_lock));
   3705       1.1  yamaguch 
   3706       1.1  yamaguch 	cv_signal(&sc->sc_atq_cv);
   3707       1.1  yamaguch }
   3708       1.1  yamaguch 
   3709       1.1  yamaguch static int
   3710       1.1  yamaguch ixl_atq_exec(struct ixl_softc *sc, struct ixl_atq *iatq)
   3711       1.1  yamaguch {
   3712       1.1  yamaguch 	int error;
   3713       1.1  yamaguch 
   3714       1.1  yamaguch 	KASSERT(iatq->iatq_desc.iaq_cookie == 0);
   3715       1.1  yamaguch 
   3716       1.1  yamaguch 	ixl_atq_set(iatq, ixl_wakeup);
   3717       1.1  yamaguch 
   3718       1.1  yamaguch 	mutex_enter(&sc->sc_atq_lock);
   3719       1.1  yamaguch 	error = ixl_atq_post_locked(sc, iatq);
   3720       1.1  yamaguch 	if (error) {
   3721       1.1  yamaguch 		mutex_exit(&sc->sc_atq_lock);
   3722       1.1  yamaguch 		return error;
   3723       1.1  yamaguch 	}
   3724       1.1  yamaguch 
   3725       1.1  yamaguch 	error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock,
   3726       1.1  yamaguch 	    IXL_ATQ_EXEC_TIMEOUT);
   3727       1.1  yamaguch 	mutex_exit(&sc->sc_atq_lock);
   3728       1.1  yamaguch 
   3729       1.1  yamaguch 	return error;
   3730       1.1  yamaguch }
   3731       1.1  yamaguch 
   3732       1.1  yamaguch static int
   3733       1.1  yamaguch ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm)
   3734       1.1  yamaguch {
   3735       1.1  yamaguch 	struct ixl_aq_desc *atq, *slot;
   3736       1.1  yamaguch 	unsigned int prod;
   3737       1.1  yamaguch 	unsigned int t = 0;
   3738       1.1  yamaguch 
   3739       1.9  yamaguch 	mutex_enter(&sc->sc_atq_lock);
   3740       1.9  yamaguch 
   3741       1.1  yamaguch 	atq = IXL_DMA_KVA(&sc->sc_atq);
   3742       1.1  yamaguch 	prod = sc->sc_atq_prod;
   3743       1.1  yamaguch 	slot = atq + prod;
   3744       1.1  yamaguch 
   3745       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3746       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE);
   3747       1.1  yamaguch 
   3748       1.1  yamaguch 	*slot = *iaq;
   3749       1.1  yamaguch 	slot->iaq_flags |= htole16(IXL_AQ_SI);
   3750       1.1  yamaguch 
   3751       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3752       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE);
   3753       1.1  yamaguch 
   3754       1.1  yamaguch 	prod++;
   3755       1.1  yamaguch 	prod &= IXL_AQ_MASK;
   3756       1.1  yamaguch 	sc->sc_atq_prod = prod;
   3757       1.1  yamaguch 	ixl_wr(sc, sc->sc_aq_regs->atq_tail, prod);
   3758       1.1  yamaguch 
   3759       1.1  yamaguch 	while (ixl_rd(sc, sc->sc_aq_regs->atq_head) != prod) {
   3760       1.1  yamaguch 		delaymsec(1);
   3761       1.1  yamaguch 
   3762       1.9  yamaguch 		if (t++ > tm) {
   3763       1.9  yamaguch 			mutex_exit(&sc->sc_atq_lock);
   3764       1.1  yamaguch 			return ETIMEDOUT;
   3765       1.9  yamaguch 		}
   3766       1.1  yamaguch 	}
   3767       1.1  yamaguch 
   3768       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3769       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTREAD);
   3770       1.1  yamaguch 	*iaq = *slot;
   3771       1.1  yamaguch 	memset(slot, 0, sizeof(*slot));
   3772       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
   3773       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREREAD);
   3774       1.1  yamaguch 
   3775       1.1  yamaguch 	sc->sc_atq_cons = prod;
   3776       1.1  yamaguch 
   3777       1.9  yamaguch 	mutex_exit(&sc->sc_atq_lock);
   3778       1.9  yamaguch 
   3779       1.1  yamaguch 	return 0;
   3780       1.1  yamaguch }
   3781       1.1  yamaguch 
   3782       1.1  yamaguch static int
   3783       1.1  yamaguch ixl_get_version(struct ixl_softc *sc)
   3784       1.1  yamaguch {
   3785       1.1  yamaguch 	struct ixl_aq_desc iaq;
   3786       1.1  yamaguch 	uint32_t fwbuild, fwver, apiver;
   3787       1.1  yamaguch 	uint16_t api_maj_ver, api_min_ver;
   3788       1.1  yamaguch 
   3789       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   3790       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_GET_VERSION);
   3791       1.1  yamaguch 
   3792       1.1  yamaguch 	iaq.iaq_retval = le16toh(23);
   3793       1.1  yamaguch 
   3794       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 2000) != 0)
   3795       1.1  yamaguch 		return ETIMEDOUT;
   3796       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK))
   3797       1.1  yamaguch 		return EIO;
   3798       1.1  yamaguch 
   3799       1.1  yamaguch 	fwbuild = le32toh(iaq.iaq_param[1]);
   3800       1.1  yamaguch 	fwver = le32toh(iaq.iaq_param[2]);
   3801       1.1  yamaguch 	apiver = le32toh(iaq.iaq_param[3]);
   3802       1.1  yamaguch 
   3803       1.1  yamaguch 	api_maj_ver = (uint16_t)apiver;
   3804       1.1  yamaguch 	api_min_ver = (uint16_t)(apiver >> 16);
   3805       1.1  yamaguch 
   3806       1.1  yamaguch 	aprint_normal(", FW %hu.%hu.%05u API %hu.%hu", (uint16_t)fwver,
   3807       1.1  yamaguch 	    (uint16_t)(fwver >> 16), fwbuild, api_maj_ver, api_min_ver);
   3808       1.1  yamaguch 
   3809       1.1  yamaguch 	if (sc->sc_mac_type == I40E_MAC_X722) {
   3810  1.16.2.1        ad 		SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK |
   3811  1.16.2.1        ad 		    IXL_SC_AQ_FLAG_NVMREAD);
   3812  1.16.2.1        ad 	}
   3813  1.16.2.1        ad 
   3814  1.16.2.1        ad #define IXL_API_VER(maj, min)	(((uint32_t)(maj) << 16) | (min))
   3815  1.16.2.1        ad 	if (IXL_API_VER(api_maj_ver, api_min_ver) >= IXL_API_VER(1, 5)) {
   3816  1.16.2.1        ad 		if (sc->sc_mac_type == I40E_MAC_X722) {
   3817  1.16.2.1        ad 			SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL);
   3818       1.1  yamaguch 		}
   3819  1.16.2.1        ad 		SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK);
   3820       1.1  yamaguch 	}
   3821  1.16.2.1        ad #undef IXL_API_VER
   3822  1.16.2.1        ad 
   3823  1.16.2.1        ad 	return 0;
   3824  1.16.2.1        ad }
   3825  1.16.2.1        ad 
   3826  1.16.2.1        ad static int
   3827  1.16.2.1        ad ixl_get_nvm_version(struct ixl_softc *sc)
   3828  1.16.2.1        ad {
   3829  1.16.2.1        ad 	uint16_t nvmver, cfg_ptr, eetrack_hi, eetrack_lo, oem_hi, oem_lo;
   3830  1.16.2.1        ad 	uint32_t eetrack, oem;
   3831  1.16.2.1        ad 	uint16_t nvm_maj_ver, nvm_min_ver, oem_build;
   3832  1.16.2.1        ad 	uint8_t oem_ver, oem_patch;
   3833  1.16.2.1        ad 
   3834  1.16.2.1        ad 	nvmver = cfg_ptr = eetrack_hi = eetrack_lo = oem_hi = oem_lo = 0;
   3835  1.16.2.1        ad 	ixl_rd16_nvm(sc, I40E_SR_NVM_DEV_STARTER_VERSION, &nvmver);
   3836  1.16.2.1        ad 	ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
   3837  1.16.2.1        ad 	ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
   3838  1.16.2.1        ad 	ixl_rd16_nvm(sc, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
   3839  1.16.2.1        ad 	ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF, &oem_hi);
   3840  1.16.2.1        ad 	ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF + 1, &oem_lo);
   3841  1.16.2.1        ad 
   3842  1.16.2.1        ad 	nvm_maj_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_HI_MASK);
   3843  1.16.2.1        ad 	nvm_min_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_LO_MASK);
   3844  1.16.2.1        ad 	eetrack = ((uint32_t)eetrack_hi << 16) | eetrack_lo;
   3845  1.16.2.1        ad 	oem = ((uint32_t)oem_hi << 16) | oem_lo;
   3846  1.16.2.1        ad 	oem_ver = __SHIFTOUT(oem, IXL_NVM_OEMVERSION_MASK);
   3847  1.16.2.1        ad 	oem_build = __SHIFTOUT(oem, IXL_NVM_OEMBUILD_MASK);
   3848  1.16.2.1        ad 	oem_patch = __SHIFTOUT(oem, IXL_NVM_OEMPATCH_MASK);
   3849  1.16.2.1        ad 
   3850  1.16.2.1        ad 	aprint_normal(" nvm %x.%02x etid %08x oem %d.%d.%d",
   3851  1.16.2.1        ad 	    nvm_maj_ver, nvm_min_ver, eetrack,
   3852  1.16.2.1        ad 	    oem_ver, oem_build, oem_patch);
   3853       1.1  yamaguch 
   3854       1.1  yamaguch 	return 0;
   3855       1.1  yamaguch }
   3856       1.1  yamaguch 
   3857       1.1  yamaguch static int
   3858       1.1  yamaguch ixl_pxe_clear(struct ixl_softc *sc)
   3859       1.1  yamaguch {
   3860       1.1  yamaguch 	struct ixl_aq_desc iaq;
   3861       1.1  yamaguch 	int rv;
   3862       1.1  yamaguch 
   3863       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   3864       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_CLEAR_PXE_MODE);
   3865       1.1  yamaguch 	iaq.iaq_param[0] = htole32(0x2);
   3866       1.1  yamaguch 
   3867       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   3868       1.1  yamaguch 
   3869       1.1  yamaguch 	ixl_wr(sc, I40E_GLLAN_RCTL_0, 0x1);
   3870       1.1  yamaguch 
   3871       1.1  yamaguch 	if (rv != 0)
   3872       1.1  yamaguch 		return ETIMEDOUT;
   3873       1.1  yamaguch 
   3874       1.1  yamaguch 	switch (iaq.iaq_retval) {
   3875       1.1  yamaguch 	case htole16(IXL_AQ_RC_OK):
   3876       1.1  yamaguch 	case htole16(IXL_AQ_RC_EEXIST):
   3877       1.1  yamaguch 		break;
   3878       1.1  yamaguch 	default:
   3879       1.1  yamaguch 		return EIO;
   3880       1.1  yamaguch 	}
   3881       1.1  yamaguch 
   3882       1.1  yamaguch 	return 0;
   3883       1.1  yamaguch }
   3884       1.1  yamaguch 
   3885       1.1  yamaguch static int
   3886       1.1  yamaguch ixl_lldp_shut(struct ixl_softc *sc)
   3887       1.1  yamaguch {
   3888       1.1  yamaguch 	struct ixl_aq_desc iaq;
   3889       1.1  yamaguch 
   3890       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   3891       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_LLDP_STOP_AGENT);
   3892       1.1  yamaguch 	iaq.iaq_param[0] = htole32(IXL_LLDP_SHUTDOWN);
   3893       1.1  yamaguch 
   3894       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   3895       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "STOP LLDP AGENT timeout\n");
   3896       1.1  yamaguch 		return -1;
   3897       1.1  yamaguch 	}
   3898       1.1  yamaguch 
   3899       1.1  yamaguch 	switch (iaq.iaq_retval) {
   3900       1.1  yamaguch 	case htole16(IXL_AQ_RC_EMODE):
   3901       1.1  yamaguch 	case htole16(IXL_AQ_RC_EPERM):
   3902       1.1  yamaguch 		/* ignore silently */
   3903       1.1  yamaguch 	default:
   3904       1.1  yamaguch 		break;
   3905       1.1  yamaguch 	}
   3906       1.1  yamaguch 
   3907       1.1  yamaguch 	return 0;
   3908       1.1  yamaguch }
   3909       1.1  yamaguch 
   3910       1.1  yamaguch static void
   3911       1.1  yamaguch ixl_parse_hw_capability(struct ixl_softc *sc, struct ixl_aq_capability *cap)
   3912       1.1  yamaguch {
   3913       1.1  yamaguch 	uint16_t id;
   3914       1.1  yamaguch 	uint32_t number, logical_id;
   3915       1.1  yamaguch 
   3916       1.1  yamaguch 	id = le16toh(cap->cap_id);
   3917       1.1  yamaguch 	number = le32toh(cap->number);
   3918       1.1  yamaguch 	logical_id = le32toh(cap->logical_id);
   3919       1.1  yamaguch 
   3920       1.1  yamaguch 	switch (id) {
   3921       1.1  yamaguch 	case IXL_AQ_CAP_RSS:
   3922       1.1  yamaguch 		sc->sc_rss_table_size = number;
   3923       1.1  yamaguch 		sc->sc_rss_table_entry_width = logical_id;
   3924       1.1  yamaguch 		break;
   3925       1.1  yamaguch 	case IXL_AQ_CAP_RXQ:
   3926       1.1  yamaguch 	case IXL_AQ_CAP_TXQ:
   3927       1.1  yamaguch 		sc->sc_nqueue_pairs_device = MIN(number,
   3928       1.1  yamaguch 		    sc->sc_nqueue_pairs_device);
   3929       1.1  yamaguch 		break;
   3930       1.1  yamaguch 	}
   3931       1.1  yamaguch }
   3932       1.1  yamaguch 
   3933       1.1  yamaguch static int
   3934       1.1  yamaguch ixl_get_hw_capabilities(struct ixl_softc *sc)
   3935       1.1  yamaguch {
   3936       1.1  yamaguch 	struct ixl_dmamem idm;
   3937       1.1  yamaguch 	struct ixl_aq_desc iaq;
   3938       1.1  yamaguch 	struct ixl_aq_capability *caps;
   3939       1.1  yamaguch 	size_t i, ncaps;
   3940       1.1  yamaguch 	bus_size_t caps_size;
   3941       1.1  yamaguch 	uint16_t status;
   3942       1.1  yamaguch 	int rv;
   3943       1.1  yamaguch 
   3944       1.1  yamaguch 	caps_size = sizeof(caps[0]) * 40;
   3945       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   3946       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_LIST_FUNC_CAP);
   3947       1.1  yamaguch 
   3948       1.1  yamaguch 	do {
   3949       1.1  yamaguch 		if (ixl_dmamem_alloc(sc, &idm, caps_size, 0) != 0) {
   3950       1.1  yamaguch 			return -1;
   3951       1.1  yamaguch 		}
   3952       1.1  yamaguch 
   3953       1.1  yamaguch 		iaq.iaq_flags = htole16(IXL_AQ_BUF |
   3954       1.1  yamaguch 		    (caps_size > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0));
   3955       1.1  yamaguch 		iaq.iaq_datalen = htole16(caps_size);
   3956       1.1  yamaguch 		ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm));
   3957       1.1  yamaguch 
   3958       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0,
   3959       1.1  yamaguch 		    IXL_DMA_LEN(&idm), BUS_DMASYNC_PREREAD);
   3960       1.1  yamaguch 
   3961       1.1  yamaguch 		rv = ixl_atq_poll(sc, &iaq, 250);
   3962       1.1  yamaguch 
   3963       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0,
   3964       1.1  yamaguch 		    IXL_DMA_LEN(&idm), BUS_DMASYNC_POSTREAD);
   3965       1.1  yamaguch 
   3966       1.1  yamaguch 		if (rv != 0) {
   3967       1.1  yamaguch 			aprint_error(", HW capabilities timeout\n");
   3968       1.1  yamaguch 			goto done;
   3969       1.1  yamaguch 		}
   3970       1.1  yamaguch 
   3971       1.1  yamaguch 		status = le16toh(iaq.iaq_retval);
   3972       1.1  yamaguch 
   3973       1.1  yamaguch 		if (status == IXL_AQ_RC_ENOMEM) {
   3974       1.1  yamaguch 			caps_size = le16toh(iaq.iaq_datalen);
   3975       1.1  yamaguch 			ixl_dmamem_free(sc, &idm);
   3976       1.1  yamaguch 		}
   3977       1.1  yamaguch 	} while (status == IXL_AQ_RC_ENOMEM);
   3978       1.1  yamaguch 
   3979       1.1  yamaguch 	if (status != IXL_AQ_RC_OK) {
   3980       1.1  yamaguch 		aprint_error(", HW capabilities error\n");
   3981       1.1  yamaguch 		goto done;
   3982       1.1  yamaguch 	}
   3983       1.1  yamaguch 
   3984       1.1  yamaguch 	caps = IXL_DMA_KVA(&idm);
   3985       1.1  yamaguch 	ncaps = le16toh(iaq.iaq_param[1]);
   3986       1.1  yamaguch 
   3987       1.1  yamaguch 	for (i = 0; i < ncaps; i++) {
   3988       1.1  yamaguch 		ixl_parse_hw_capability(sc, &caps[i]);
   3989       1.1  yamaguch 	}
   3990       1.1  yamaguch 
   3991       1.1  yamaguch done:
   3992       1.1  yamaguch 	ixl_dmamem_free(sc, &idm);
   3993       1.1  yamaguch 	return rv;
   3994       1.1  yamaguch }
   3995       1.1  yamaguch 
   3996       1.1  yamaguch static int
   3997       1.1  yamaguch ixl_get_mac(struct ixl_softc *sc)
   3998       1.1  yamaguch {
   3999       1.1  yamaguch 	struct ixl_dmamem idm;
   4000       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4001       1.1  yamaguch 	struct ixl_aq_mac_addresses *addrs;
   4002       1.1  yamaguch 	int rv;
   4003       1.1  yamaguch 
   4004       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &idm, sizeof(*addrs), 0) != 0) {
   4005       1.1  yamaguch 		aprint_error(", unable to allocate mac addresses\n");
   4006       1.1  yamaguch 		return -1;
   4007       1.1  yamaguch 	}
   4008       1.1  yamaguch 
   4009       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4010       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF);
   4011       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_MAC_ADDRESS_READ);
   4012       1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*addrs));
   4013       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm));
   4014       1.1  yamaguch 
   4015       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm),
   4016       1.1  yamaguch 	    BUS_DMASYNC_PREREAD);
   4017       1.1  yamaguch 
   4018       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   4019       1.1  yamaguch 
   4020       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm),
   4021       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   4022       1.1  yamaguch 
   4023       1.1  yamaguch 	if (rv != 0) {
   4024       1.1  yamaguch 		aprint_error(", MAC ADDRESS READ timeout\n");
   4025       1.1  yamaguch 		rv = -1;
   4026       1.1  yamaguch 		goto done;
   4027       1.1  yamaguch 	}
   4028       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4029       1.1  yamaguch 		aprint_error(", MAC ADDRESS READ error\n");
   4030       1.1  yamaguch 		rv = -1;
   4031       1.1  yamaguch 		goto done;
   4032       1.1  yamaguch 	}
   4033       1.1  yamaguch 
   4034       1.1  yamaguch 	addrs = IXL_DMA_KVA(&idm);
   4035       1.1  yamaguch 	if (!ISSET(iaq.iaq_param[0], htole32(IXL_AQ_MAC_PORT_VALID))) {
   4036       1.1  yamaguch 		printf(", port address is not valid\n");
   4037       1.1  yamaguch 		goto done;
   4038       1.1  yamaguch 	}
   4039       1.1  yamaguch 
   4040       1.1  yamaguch 	memcpy(sc->sc_enaddr, addrs->port, ETHER_ADDR_LEN);
   4041       1.1  yamaguch 	rv = 0;
   4042       1.1  yamaguch 
   4043       1.1  yamaguch done:
   4044       1.1  yamaguch 	ixl_dmamem_free(sc, &idm);
   4045       1.1  yamaguch 	return rv;
   4046       1.1  yamaguch }
   4047       1.1  yamaguch 
   4048       1.1  yamaguch static int
   4049       1.1  yamaguch ixl_get_switch_config(struct ixl_softc *sc)
   4050       1.1  yamaguch {
   4051       1.1  yamaguch 	struct ixl_dmamem idm;
   4052       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4053       1.1  yamaguch 	struct ixl_aq_switch_config *hdr;
   4054       1.1  yamaguch 	struct ixl_aq_switch_config_element *elms, *elm;
   4055       1.1  yamaguch 	unsigned int nelm, i;
   4056       1.1  yamaguch 	int rv;
   4057       1.1  yamaguch 
   4058       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &idm, IXL_AQ_BUFLEN, 0) != 0) {
   4059       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   4060       1.1  yamaguch 		    "unable to allocate switch config buffer\n");
   4061       1.1  yamaguch 		return -1;
   4062       1.1  yamaguch 	}
   4063       1.1  yamaguch 
   4064       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4065       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF |
   4066       1.1  yamaguch 	    (IXL_AQ_BUFLEN > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0));
   4067       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_SWITCH_GET_CONFIG);
   4068       1.1  yamaguch 	iaq.iaq_datalen = htole16(IXL_AQ_BUFLEN);
   4069       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm));
   4070       1.1  yamaguch 
   4071       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm),
   4072       1.1  yamaguch 	    BUS_DMASYNC_PREREAD);
   4073       1.1  yamaguch 
   4074       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   4075       1.1  yamaguch 
   4076       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm),
   4077       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   4078       1.1  yamaguch 
   4079       1.1  yamaguch 	if (rv != 0) {
   4080       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "GET SWITCH CONFIG timeout\n");
   4081       1.1  yamaguch 		rv = -1;
   4082       1.1  yamaguch 		goto done;
   4083       1.1  yamaguch 	}
   4084       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4085       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "GET SWITCH CONFIG error\n");
   4086       1.1  yamaguch 		rv = -1;
   4087       1.1  yamaguch 		goto done;
   4088       1.1  yamaguch 	}
   4089       1.1  yamaguch 
   4090       1.1  yamaguch 	hdr = IXL_DMA_KVA(&idm);
   4091       1.1  yamaguch 	elms = (struct ixl_aq_switch_config_element *)(hdr + 1);
   4092       1.1  yamaguch 
   4093       1.1  yamaguch 	nelm = le16toh(hdr->num_reported);
   4094       1.1  yamaguch 	if (nelm < 1) {
   4095       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "no switch config available\n");
   4096       1.1  yamaguch 		rv = -1;
   4097       1.1  yamaguch 		goto done;
   4098       1.1  yamaguch 	}
   4099       1.1  yamaguch 
   4100       1.1  yamaguch 	for (i = 0; i < nelm; i++) {
   4101       1.1  yamaguch 		elm = &elms[i];
   4102       1.1  yamaguch 
   4103       1.1  yamaguch 		aprint_debug_dev(sc->sc_dev,
   4104       1.1  yamaguch 		    "type %x revision %u seid %04x\n",
   4105       1.1  yamaguch 		    elm->type, elm->revision, le16toh(elm->seid));
   4106       1.1  yamaguch 		aprint_debug_dev(sc->sc_dev,
   4107       1.1  yamaguch 		    "uplink %04x downlink %04x\n",
   4108       1.1  yamaguch 		    le16toh(elm->uplink_seid),
   4109       1.1  yamaguch 		    le16toh(elm->downlink_seid));
   4110       1.1  yamaguch 		aprint_debug_dev(sc->sc_dev,
   4111       1.1  yamaguch 		    "conntype %x scheduler %04x extra %04x\n",
   4112       1.1  yamaguch 		    elm->connection_type,
   4113       1.1  yamaguch 		    le16toh(elm->scheduler_id),
   4114       1.1  yamaguch 		    le16toh(elm->element_info));
   4115       1.1  yamaguch 	}
   4116       1.1  yamaguch 
   4117       1.1  yamaguch 	elm = &elms[0];
   4118       1.1  yamaguch 
   4119       1.1  yamaguch 	sc->sc_uplink_seid = elm->uplink_seid;
   4120       1.1  yamaguch 	sc->sc_downlink_seid = elm->downlink_seid;
   4121       1.1  yamaguch 	sc->sc_seid = elm->seid;
   4122       1.1  yamaguch 
   4123       1.1  yamaguch 	if ((sc->sc_uplink_seid == htole16(0)) !=
   4124       1.1  yamaguch 	    (sc->sc_downlink_seid == htole16(0))) {
   4125       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "SEIDs are misconfigured\n");
   4126       1.1  yamaguch 		rv = -1;
   4127       1.1  yamaguch 		goto done;
   4128       1.1  yamaguch 	}
   4129       1.1  yamaguch 
   4130       1.1  yamaguch done:
   4131       1.1  yamaguch 	ixl_dmamem_free(sc, &idm);
   4132       1.1  yamaguch 	return rv;
   4133       1.1  yamaguch }
   4134       1.1  yamaguch 
   4135       1.1  yamaguch static int
   4136       1.1  yamaguch ixl_phy_mask_ints(struct ixl_softc *sc)
   4137       1.1  yamaguch {
   4138       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4139       1.1  yamaguch 
   4140       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4141       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_SET_EVENT_MASK);
   4142       1.1  yamaguch 	iaq.iaq_param[2] = htole32(IXL_AQ_PHY_EV_MASK &
   4143       1.1  yamaguch 	    ~(IXL_AQ_PHY_EV_LINK_UPDOWN | IXL_AQ_PHY_EV_MODULE_QUAL_FAIL |
   4144       1.1  yamaguch 	      IXL_AQ_PHY_EV_MEDIA_NA));
   4145       1.1  yamaguch 
   4146       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   4147       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "SET PHY EVENT MASK timeout\n");
   4148       1.1  yamaguch 		return -1;
   4149       1.1  yamaguch 	}
   4150       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4151       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "SET PHY EVENT MASK error\n");
   4152       1.1  yamaguch 		return -1;
   4153       1.1  yamaguch 	}
   4154       1.1  yamaguch 
   4155       1.1  yamaguch 	return 0;
   4156       1.1  yamaguch }
   4157       1.1  yamaguch 
   4158       1.1  yamaguch static int
   4159       1.1  yamaguch ixl_get_phy_abilities(struct ixl_softc *sc,struct ixl_dmamem *idm)
   4160       1.1  yamaguch {
   4161       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4162       1.1  yamaguch 	int rv;
   4163       1.1  yamaguch 
   4164       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4165       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF |
   4166       1.1  yamaguch 	    (IXL_DMA_LEN(idm) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0));
   4167       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_GET_ABILITIES);
   4168       1.1  yamaguch 	iaq.iaq_datalen = htole16(IXL_DMA_LEN(idm));
   4169       1.1  yamaguch 	iaq.iaq_param[0] = htole32(IXL_AQ_PHY_REPORT_INIT);
   4170       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(idm));
   4171       1.1  yamaguch 
   4172       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm),
   4173       1.1  yamaguch 	    BUS_DMASYNC_PREREAD);
   4174       1.1  yamaguch 
   4175       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   4176       1.1  yamaguch 
   4177       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm),
   4178       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   4179       1.1  yamaguch 
   4180       1.1  yamaguch 	if (rv != 0)
   4181       1.1  yamaguch 		return -1;
   4182       1.1  yamaguch 
   4183       1.1  yamaguch 	return le16toh(iaq.iaq_retval);
   4184       1.1  yamaguch }
   4185       1.1  yamaguch 
   4186       1.1  yamaguch static int
   4187       1.1  yamaguch ixl_get_phy_types(struct ixl_softc *sc, uint64_t *phy_types_ptr)
   4188       1.1  yamaguch {
   4189       1.1  yamaguch 	struct ixl_dmamem idm;
   4190       1.1  yamaguch 	struct ixl_aq_phy_abilities *phy;
   4191       1.1  yamaguch 	uint64_t phy_types;
   4192       1.1  yamaguch 	int rv;
   4193       1.1  yamaguch 
   4194       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &idm, IXL_AQ_BUFLEN, 0) != 0) {
   4195       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   4196       1.1  yamaguch 		    "unable to allocate switch config buffer\n");
   4197       1.1  yamaguch 		return -1;
   4198       1.1  yamaguch 	}
   4199       1.1  yamaguch 
   4200       1.1  yamaguch 	rv = ixl_get_phy_abilities(sc, &idm);
   4201       1.1  yamaguch 	switch (rv) {
   4202       1.1  yamaguch 	case -1:
   4203       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "GET PHY ABILITIES timeout\n");
   4204       1.1  yamaguch 		goto done;
   4205       1.1  yamaguch 	case IXL_AQ_RC_OK:
   4206       1.1  yamaguch 		break;
   4207       1.1  yamaguch 	case IXL_AQ_RC_EIO:
   4208       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,"unable to query phy types\n");
   4209       1.1  yamaguch 		break;
   4210       1.1  yamaguch 	default:
   4211       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   4212       1.1  yamaguch 		    "GET PHY ABILITIIES error %u\n", rv);
   4213       1.1  yamaguch 		goto done;
   4214       1.1  yamaguch 	}
   4215       1.1  yamaguch 
   4216       1.1  yamaguch 	phy = IXL_DMA_KVA(&idm);
   4217       1.1  yamaguch 
   4218       1.1  yamaguch 	phy_types = le32toh(phy->phy_type);
   4219       1.1  yamaguch 	phy_types |= (uint64_t)le32toh(phy->phy_type_ext) << 32;
   4220       1.1  yamaguch 
   4221       1.1  yamaguch 	*phy_types_ptr = phy_types;
   4222       1.1  yamaguch 
   4223       1.1  yamaguch 	rv = 0;
   4224       1.1  yamaguch 
   4225       1.1  yamaguch done:
   4226       1.1  yamaguch 	ixl_dmamem_free(sc, &idm);
   4227       1.1  yamaguch 	return rv;
   4228       1.1  yamaguch }
   4229       1.1  yamaguch 
   4230       1.1  yamaguch static int
   4231       1.4  yamaguch ixl_get_link_status_poll(struct ixl_softc *sc)
   4232       1.1  yamaguch {
   4233       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4234       1.1  yamaguch 	struct ixl_aq_link_param *param;
   4235       1.1  yamaguch 	int link;
   4236       1.1  yamaguch 
   4237       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4238       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS);
   4239       1.1  yamaguch 	param = (struct ixl_aq_link_param *)iaq.iaq_param;
   4240       1.1  yamaguch 	param->notify = IXL_AQ_LINK_NOTIFY;
   4241       1.1  yamaguch 
   4242       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   4243       1.1  yamaguch 		return ETIMEDOUT;
   4244       1.1  yamaguch 	}
   4245       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4246       1.1  yamaguch 		return EIO;
   4247       1.1  yamaguch 	}
   4248       1.1  yamaguch 
   4249       1.1  yamaguch 	link = ixl_set_link_status(sc, &iaq);
   4250       1.1  yamaguch 	sc->sc_ec.ec_if.if_link_state = link;
   4251       1.1  yamaguch 
   4252       1.1  yamaguch 	return 0;
   4253       1.1  yamaguch }
   4254       1.1  yamaguch 
   4255       1.1  yamaguch static int
   4256       1.1  yamaguch ixl_get_vsi(struct ixl_softc *sc)
   4257       1.1  yamaguch {
   4258       1.1  yamaguch 	struct ixl_dmamem *vsi = &sc->sc_scratch;
   4259       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4260       1.1  yamaguch 	struct ixl_aq_vsi_param *param;
   4261       1.1  yamaguch 	struct ixl_aq_vsi_reply *reply;
   4262  1.16.2.1        ad 	struct ixl_aq_vsi_data *data;
   4263       1.1  yamaguch 	int rv;
   4264       1.1  yamaguch 
   4265       1.1  yamaguch 	/* grumble, vsi info isn't "known" at compile time */
   4266       1.1  yamaguch 
   4267       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4268       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF |
   4269       1.1  yamaguch 	    (IXL_DMA_LEN(vsi) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0));
   4270       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_GET_VSI_PARAMS);
   4271       1.1  yamaguch 	iaq.iaq_datalen = htole16(IXL_DMA_LEN(vsi));
   4272       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(vsi));
   4273       1.1  yamaguch 
   4274       1.1  yamaguch 	param = (struct ixl_aq_vsi_param *)iaq.iaq_param;
   4275       1.1  yamaguch 	param->uplink_seid = sc->sc_seid;
   4276       1.1  yamaguch 
   4277       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi),
   4278       1.1  yamaguch 	    BUS_DMASYNC_PREREAD);
   4279       1.1  yamaguch 
   4280       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   4281       1.1  yamaguch 
   4282       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi),
   4283       1.1  yamaguch 	    BUS_DMASYNC_POSTREAD);
   4284       1.1  yamaguch 
   4285       1.1  yamaguch 	if (rv != 0) {
   4286      1.11  yamaguch 		return ETIMEDOUT;
   4287       1.1  yamaguch 	}
   4288       1.1  yamaguch 
   4289      1.12  yamaguch 	switch (le16toh(iaq.iaq_retval)) {
   4290      1.12  yamaguch 	case IXL_AQ_RC_OK:
   4291      1.12  yamaguch 		break;
   4292      1.12  yamaguch 	case IXL_AQ_RC_ENOENT:
   4293      1.12  yamaguch 		return ENOENT;
   4294      1.12  yamaguch 	case IXL_AQ_RC_EACCES:
   4295      1.12  yamaguch 		return EACCES;
   4296      1.12  yamaguch 	default:
   4297      1.11  yamaguch 		return EIO;
   4298       1.1  yamaguch 	}
   4299       1.1  yamaguch 
   4300       1.1  yamaguch 	reply = (struct ixl_aq_vsi_reply *)iaq.iaq_param;
   4301       1.1  yamaguch 	sc->sc_vsi_number = reply->vsi_number;
   4302  1.16.2.1        ad 	data = IXL_DMA_KVA(vsi);
   4303  1.16.2.1        ad 	sc->sc_vsi_stat_counter_idx = le16toh(data->stat_counter_idx);
   4304       1.1  yamaguch 
   4305       1.1  yamaguch 	return 0;
   4306       1.1  yamaguch }
   4307       1.1  yamaguch 
   4308       1.1  yamaguch static int
   4309       1.1  yamaguch ixl_set_vsi(struct ixl_softc *sc)
   4310       1.1  yamaguch {
   4311       1.1  yamaguch 	struct ixl_dmamem *vsi = &sc->sc_scratch;
   4312       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4313       1.1  yamaguch 	struct ixl_aq_vsi_param *param;
   4314       1.1  yamaguch 	struct ixl_aq_vsi_data *data = IXL_DMA_KVA(vsi);
   4315       1.1  yamaguch 	unsigned int qnum;
   4316      1.11  yamaguch 	uint16_t val;
   4317       1.1  yamaguch 	int rv;
   4318       1.1  yamaguch 
   4319       1.1  yamaguch 	qnum = sc->sc_nqueue_pairs - 1;
   4320       1.1  yamaguch 
   4321       1.1  yamaguch 	data->valid_sections = htole16(IXL_AQ_VSI_VALID_QUEUE_MAP |
   4322       1.1  yamaguch 	    IXL_AQ_VSI_VALID_VLAN);
   4323       1.1  yamaguch 
   4324       1.1  yamaguch 	CLR(data->mapping_flags, htole16(IXL_AQ_VSI_QUE_MAP_MASK));
   4325       1.1  yamaguch 	SET(data->mapping_flags, htole16(IXL_AQ_VSI_QUE_MAP_CONTIG));
   4326       1.1  yamaguch 	data->queue_mapping[0] = htole16(0);
   4327       1.1  yamaguch 	data->tc_mapping[0] = htole16((0 << IXL_AQ_VSI_TC_Q_OFFSET_SHIFT) |
   4328       1.1  yamaguch 	    (qnum << IXL_AQ_VSI_TC_Q_NUMBER_SHIFT));
   4329       1.1  yamaguch 
   4330      1.11  yamaguch 	val = le16toh(data->port_vlan_flags);
   4331      1.11  yamaguch 	CLR(val, IXL_AQ_VSI_PVLAN_MODE_MASK | IXL_AQ_VSI_PVLAN_EMOD_MASK);
   4332      1.11  yamaguch 	SET(val, IXL_AQ_VSI_PVLAN_MODE_ALL);
   4333      1.11  yamaguch 
   4334      1.11  yamaguch 	if (ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWTAGGING)) {
   4335      1.11  yamaguch 		SET(val, IXL_AQ_VSI_PVLAN_EMOD_STR_BOTH);
   4336      1.11  yamaguch 	} else {
   4337      1.11  yamaguch 		SET(val, IXL_AQ_VSI_PVLAN_EMOD_NOTHING);
   4338      1.11  yamaguch 	}
   4339      1.11  yamaguch 
   4340      1.11  yamaguch 	data->port_vlan_flags = htole16(val);
   4341       1.1  yamaguch 
   4342       1.1  yamaguch 	/* grumble, vsi info isn't "known" at compile time */
   4343       1.1  yamaguch 
   4344       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4345       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD |
   4346       1.1  yamaguch 	    (IXL_DMA_LEN(vsi) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0));
   4347       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_UPD_VSI_PARAMS);
   4348       1.1  yamaguch 	iaq.iaq_datalen = htole16(IXL_DMA_LEN(vsi));
   4349       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(vsi));
   4350       1.1  yamaguch 
   4351       1.1  yamaguch 	param = (struct ixl_aq_vsi_param *)iaq.iaq_param;
   4352       1.1  yamaguch 	param->uplink_seid = sc->sc_seid;
   4353       1.1  yamaguch 
   4354       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi),
   4355       1.1  yamaguch 	    BUS_DMASYNC_PREWRITE);
   4356       1.1  yamaguch 
   4357       1.1  yamaguch 	rv = ixl_atq_poll(sc, &iaq, 250);
   4358       1.1  yamaguch 
   4359       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi),
   4360       1.1  yamaguch 	    BUS_DMASYNC_POSTWRITE);
   4361       1.1  yamaguch 
   4362       1.1  yamaguch 	if (rv != 0) {
   4363      1.11  yamaguch 		return ETIMEDOUT;
   4364       1.1  yamaguch 	}
   4365       1.1  yamaguch 
   4366      1.12  yamaguch 	switch (le16toh(iaq.iaq_retval)) {
   4367      1.12  yamaguch 	case IXL_AQ_RC_OK:
   4368      1.12  yamaguch 		break;
   4369      1.12  yamaguch 	case IXL_AQ_RC_ENOENT:
   4370      1.12  yamaguch 		return ENOENT;
   4371      1.12  yamaguch 	case IXL_AQ_RC_EACCES:
   4372      1.12  yamaguch 		return EACCES;
   4373      1.12  yamaguch 	default:
   4374      1.11  yamaguch 		return EIO;
   4375       1.1  yamaguch 	}
   4376       1.1  yamaguch 
   4377       1.1  yamaguch 	return 0;
   4378       1.1  yamaguch }
   4379       1.1  yamaguch 
   4380       1.1  yamaguch static void
   4381       1.1  yamaguch ixl_set_filter_control(struct ixl_softc *sc)
   4382       1.1  yamaguch {
   4383       1.1  yamaguch 	uint32_t reg;
   4384       1.1  yamaguch 
   4385       1.1  yamaguch 	reg = ixl_rd_rx_csr(sc, I40E_PFQF_CTL_0);
   4386       1.1  yamaguch 
   4387       1.1  yamaguch 	CLR(reg, I40E_PFQF_CTL_0_HASHLUTSIZE_MASK);
   4388       1.1  yamaguch 	SET(reg, I40E_HASH_LUT_SIZE_128 << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT);
   4389       1.1  yamaguch 
   4390       1.1  yamaguch 	SET(reg, I40E_PFQF_CTL_0_FD_ENA_MASK);
   4391       1.1  yamaguch 	SET(reg, I40E_PFQF_CTL_0_ETYPE_ENA_MASK);
   4392       1.1  yamaguch 	SET(reg, I40E_PFQF_CTL_0_MACVLAN_ENA_MASK);
   4393       1.1  yamaguch 
   4394       1.1  yamaguch 	ixl_wr_rx_csr(sc, I40E_PFQF_CTL_0, reg);
   4395       1.1  yamaguch }
   4396       1.1  yamaguch 
   4397       1.1  yamaguch static inline void
   4398       1.1  yamaguch ixl_get_default_rss_key(uint32_t *buf, size_t len)
   4399       1.1  yamaguch {
   4400       1.1  yamaguch 	size_t cplen;
   4401       1.1  yamaguch 	uint8_t rss_seed[RSS_KEYSIZE];
   4402       1.1  yamaguch 
   4403       1.1  yamaguch 	rss_getkey(rss_seed);
   4404       1.1  yamaguch 	memset(buf, 0, len);
   4405       1.1  yamaguch 
   4406       1.1  yamaguch 	cplen = MIN(len, sizeof(rss_seed));
   4407       1.1  yamaguch 	memcpy(buf, rss_seed, cplen);
   4408       1.1  yamaguch }
   4409       1.1  yamaguch 
   4410       1.1  yamaguch static void
   4411       1.1  yamaguch ixl_set_rss_key(struct ixl_softc *sc)
   4412       1.1  yamaguch {
   4413       1.1  yamaguch 	uint32_t rss_seed[IXL_RSS_KEY_SIZE_REG];
   4414       1.1  yamaguch 	size_t i;
   4415       1.1  yamaguch 
   4416       1.1  yamaguch 	ixl_get_default_rss_key(rss_seed, sizeof(rss_seed));
   4417       1.1  yamaguch 
   4418       1.1  yamaguch 	for (i = 0; i < IXL_RSS_KEY_SIZE_REG; i++) {
   4419       1.1  yamaguch 		ixl_wr_rx_csr(sc, I40E_PFQF_HKEY(i), rss_seed[i]);
   4420       1.1  yamaguch 	}
   4421       1.1  yamaguch }
   4422       1.1  yamaguch 
   4423       1.1  yamaguch static void
   4424       1.1  yamaguch ixl_set_rss_pctype(struct ixl_softc *sc)
   4425       1.1  yamaguch {
   4426       1.1  yamaguch 	uint64_t set_hena = 0;
   4427       1.1  yamaguch 	uint32_t hena0, hena1;
   4428       1.1  yamaguch 
   4429       1.1  yamaguch 	if (sc->sc_mac_type == I40E_MAC_X722)
   4430       1.1  yamaguch 		set_hena = IXL_RSS_HENA_DEFAULT_X722;
   4431       1.1  yamaguch 	else
   4432       1.1  yamaguch 		set_hena = IXL_RSS_HENA_DEFAULT_XL710;
   4433       1.1  yamaguch 
   4434       1.1  yamaguch 	hena0 = ixl_rd_rx_csr(sc, I40E_PFQF_HENA(0));
   4435       1.1  yamaguch 	hena1 = ixl_rd_rx_csr(sc, I40E_PFQF_HENA(1));
   4436       1.1  yamaguch 
   4437       1.1  yamaguch 	SET(hena0, set_hena);
   4438       1.1  yamaguch 	SET(hena1, set_hena >> 32);
   4439       1.1  yamaguch 
   4440       1.1  yamaguch 	ixl_wr_rx_csr(sc, I40E_PFQF_HENA(0), hena0);
   4441       1.1  yamaguch 	ixl_wr_rx_csr(sc, I40E_PFQF_HENA(1), hena1);
   4442       1.1  yamaguch }
   4443       1.1  yamaguch 
   4444       1.1  yamaguch static void
   4445       1.1  yamaguch ixl_set_rss_hlut(struct ixl_softc *sc)
   4446       1.1  yamaguch {
   4447       1.1  yamaguch 	unsigned int qid;
   4448       1.1  yamaguch 	uint8_t hlut_buf[512], lut_mask;
   4449       1.1  yamaguch 	uint32_t *hluts;
   4450       1.1  yamaguch 	size_t i, hluts_num;
   4451       1.1  yamaguch 
   4452       1.1  yamaguch 	lut_mask = (0x01 << sc->sc_rss_table_entry_width) - 1;
   4453       1.1  yamaguch 
   4454       1.1  yamaguch 	for (i = 0; i < sc->sc_rss_table_size; i++) {
   4455       1.1  yamaguch 		qid = i % sc->sc_nqueue_pairs;
   4456       1.1  yamaguch 		hlut_buf[i] = qid & lut_mask;
   4457       1.1  yamaguch 	}
   4458       1.1  yamaguch 
   4459       1.1  yamaguch 	hluts = (uint32_t *)hlut_buf;
   4460       1.1  yamaguch 	hluts_num = sc->sc_rss_table_size >> 2;
   4461       1.1  yamaguch 	for (i = 0; i < hluts_num; i++) {
   4462       1.1  yamaguch 		ixl_wr(sc, I40E_PFQF_HLUT(i), hluts[i]);
   4463       1.1  yamaguch 	}
   4464       1.1  yamaguch 	ixl_flush(sc);
   4465       1.1  yamaguch }
   4466       1.1  yamaguch 
   4467       1.1  yamaguch static void
   4468       1.1  yamaguch ixl_config_rss(struct ixl_softc *sc)
   4469       1.1  yamaguch {
   4470       1.1  yamaguch 
   4471       1.1  yamaguch 	KASSERT(mutex_owned(&sc->sc_cfg_lock));
   4472       1.1  yamaguch 
   4473       1.1  yamaguch 	ixl_set_rss_key(sc);
   4474       1.1  yamaguch 	ixl_set_rss_pctype(sc);
   4475       1.1  yamaguch 	ixl_set_rss_hlut(sc);
   4476       1.1  yamaguch }
   4477       1.1  yamaguch 
   4478       1.1  yamaguch static const struct ixl_phy_type *
   4479       1.1  yamaguch ixl_search_phy_type(uint8_t phy_type)
   4480       1.1  yamaguch {
   4481       1.1  yamaguch 	const struct ixl_phy_type *itype;
   4482       1.1  yamaguch 	uint64_t mask;
   4483       1.1  yamaguch 	unsigned int i;
   4484       1.1  yamaguch 
   4485       1.1  yamaguch 	if (phy_type >= 64)
   4486       1.1  yamaguch 		return NULL;
   4487       1.1  yamaguch 
   4488       1.1  yamaguch 	mask = 1ULL << phy_type;
   4489       1.1  yamaguch 
   4490       1.1  yamaguch 	for (i = 0; i < __arraycount(ixl_phy_type_map); i++) {
   4491       1.1  yamaguch 		itype = &ixl_phy_type_map[i];
   4492       1.1  yamaguch 
   4493       1.1  yamaguch 		if (ISSET(itype->phy_type, mask))
   4494       1.1  yamaguch 			return itype;
   4495       1.1  yamaguch 	}
   4496       1.1  yamaguch 
   4497       1.1  yamaguch 	return NULL;
   4498       1.1  yamaguch }
   4499       1.1  yamaguch 
   4500       1.1  yamaguch static uint64_t
   4501       1.1  yamaguch ixl_search_link_speed(uint8_t link_speed)
   4502       1.1  yamaguch {
   4503       1.1  yamaguch 	const struct ixl_speed_type *type;
   4504       1.1  yamaguch 	unsigned int i;
   4505       1.1  yamaguch 
   4506       1.1  yamaguch 	for (i = 0; i < __arraycount(ixl_speed_type_map); i++) {
   4507       1.1  yamaguch 		type = &ixl_speed_type_map[i];
   4508       1.1  yamaguch 
   4509       1.1  yamaguch 		if (ISSET(type->dev_speed, link_speed))
   4510       1.1  yamaguch 			return type->net_speed;
   4511       1.1  yamaguch 	}
   4512       1.1  yamaguch 
   4513       1.1  yamaguch 	return 0;
   4514       1.1  yamaguch }
   4515       1.1  yamaguch 
   4516       1.1  yamaguch static int
   4517       1.1  yamaguch ixl_restart_an(struct ixl_softc *sc)
   4518       1.1  yamaguch {
   4519       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4520       1.1  yamaguch 
   4521       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4522       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_RESTART_AN);
   4523       1.1  yamaguch 	iaq.iaq_param[0] =
   4524       1.1  yamaguch 	    htole32(IXL_AQ_PHY_RESTART_AN | IXL_AQ_PHY_LINK_ENABLE);
   4525       1.1  yamaguch 
   4526       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   4527       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "RESTART AN timeout\n");
   4528       1.1  yamaguch 		return -1;
   4529       1.1  yamaguch 	}
   4530       1.1  yamaguch 	if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
   4531       1.1  yamaguch 		aprint_error_dev(sc->sc_dev, "RESTART AN error\n");
   4532       1.1  yamaguch 		return -1;
   4533       1.1  yamaguch 	}
   4534       1.1  yamaguch 
   4535       1.1  yamaguch 	return 0;
   4536       1.1  yamaguch }
   4537       1.1  yamaguch 
   4538       1.1  yamaguch static int
   4539       1.1  yamaguch ixl_add_macvlan(struct ixl_softc *sc, const uint8_t *macaddr,
   4540       1.1  yamaguch     uint16_t vlan, uint16_t flags)
   4541       1.1  yamaguch {
   4542       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4543       1.1  yamaguch 	struct ixl_aq_add_macvlan *param;
   4544       1.1  yamaguch 	struct ixl_aq_add_macvlan_elem *elem;
   4545       1.1  yamaguch 
   4546       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4547       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4548       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_ADD_MACVLAN);
   4549       1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*elem));
   4550       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(&sc->sc_scratch));
   4551       1.1  yamaguch 
   4552       1.1  yamaguch 	param = (struct ixl_aq_add_macvlan *)&iaq.iaq_param;
   4553       1.1  yamaguch 	param->num_addrs = htole16(1);
   4554       1.1  yamaguch 	param->seid0 = htole16(0x8000) | sc->sc_seid;
   4555       1.1  yamaguch 	param->seid1 = 0;
   4556       1.1  yamaguch 	param->seid2 = 0;
   4557       1.1  yamaguch 
   4558       1.1  yamaguch 	elem = IXL_DMA_KVA(&sc->sc_scratch);
   4559       1.1  yamaguch 	memset(elem, 0, sizeof(*elem));
   4560       1.1  yamaguch 	memcpy(elem->macaddr, macaddr, ETHER_ADDR_LEN);
   4561       1.1  yamaguch 	elem->flags = htole16(IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH | flags);
   4562       1.1  yamaguch 	elem->vlan = htole16(vlan);
   4563       1.1  yamaguch 
   4564       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   4565       1.1  yamaguch 		return IXL_AQ_RC_EINVAL;
   4566       1.1  yamaguch 	}
   4567       1.1  yamaguch 
   4568       1.7  yamaguch 	switch (le16toh(iaq.iaq_retval)) {
   4569       1.7  yamaguch 	case IXL_AQ_RC_OK:
   4570       1.7  yamaguch 		break;
   4571       1.7  yamaguch 	case IXL_AQ_RC_ENOSPC:
   4572       1.7  yamaguch 		return ENOSPC;
   4573       1.7  yamaguch 	case IXL_AQ_RC_ENOENT:
   4574       1.7  yamaguch 		return ENOENT;
   4575       1.7  yamaguch 	case IXL_AQ_RC_EACCES:
   4576       1.7  yamaguch 		return EACCES;
   4577       1.7  yamaguch 	case IXL_AQ_RC_EEXIST:
   4578       1.7  yamaguch 		return EEXIST;
   4579       1.7  yamaguch 	case IXL_AQ_RC_EINVAL:
   4580       1.7  yamaguch 		return EINVAL;
   4581       1.7  yamaguch 	default:
   4582       1.7  yamaguch 		return EIO;
   4583       1.7  yamaguch 	}
   4584       1.7  yamaguch 
   4585       1.7  yamaguch 	return 0;
   4586       1.1  yamaguch }
   4587       1.1  yamaguch 
   4588       1.1  yamaguch static int
   4589      1.12  yamaguch ixl_remove_macvlan(struct ixl_softc *sc, const uint8_t *macaddr,
   4590       1.1  yamaguch     uint16_t vlan, uint16_t flags)
   4591       1.1  yamaguch {
   4592       1.1  yamaguch 	struct ixl_aq_desc iaq;
   4593       1.1  yamaguch 	struct ixl_aq_remove_macvlan *param;
   4594       1.1  yamaguch 	struct ixl_aq_remove_macvlan_elem *elem;
   4595       1.1  yamaguch 
   4596       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   4597       1.1  yamaguch 	iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD);
   4598       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_REMOVE_MACVLAN);
   4599       1.1  yamaguch 	iaq.iaq_datalen = htole16(sizeof(*elem));
   4600       1.1  yamaguch 	ixl_aq_dva(&iaq, IXL_DMA_DVA(&sc->sc_scratch));
   4601       1.1  yamaguch 
   4602       1.1  yamaguch 	param = (struct ixl_aq_remove_macvlan *)&iaq.iaq_param;
   4603       1.1  yamaguch 	param->num_addrs = htole16(1);
   4604       1.1  yamaguch 	param->seid0 = htole16(0x8000) | sc->sc_seid;
   4605       1.1  yamaguch 	param->seid1 = 0;
   4606       1.1  yamaguch 	param->seid2 = 0;
   4607       1.1  yamaguch 
   4608       1.1  yamaguch 	elem = IXL_DMA_KVA(&sc->sc_scratch);
   4609       1.1  yamaguch 	memset(elem, 0, sizeof(*elem));
   4610       1.1  yamaguch 	memcpy(elem->macaddr, macaddr, ETHER_ADDR_LEN);
   4611       1.1  yamaguch 	elem->flags = htole16(IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH | flags);
   4612       1.1  yamaguch 	elem->vlan = htole16(vlan);
   4613       1.1  yamaguch 
   4614       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0) {
   4615       1.7  yamaguch 		return EINVAL;
   4616       1.7  yamaguch 	}
   4617       1.7  yamaguch 
   4618       1.7  yamaguch 	switch (le16toh(iaq.iaq_retval)) {
   4619       1.7  yamaguch 	case IXL_AQ_RC_OK:
   4620       1.7  yamaguch 		break;
   4621       1.7  yamaguch 	case IXL_AQ_RC_ENOENT:
   4622       1.7  yamaguch 		return ENOENT;
   4623       1.7  yamaguch 	case IXL_AQ_RC_EACCES:
   4624       1.7  yamaguch 		return EACCES;
   4625       1.7  yamaguch 	case IXL_AQ_RC_EINVAL:
   4626       1.7  yamaguch 		return EINVAL;
   4627       1.7  yamaguch 	default:
   4628       1.7  yamaguch 		return EIO;
   4629       1.1  yamaguch 	}
   4630       1.1  yamaguch 
   4631       1.7  yamaguch 	return 0;
   4632       1.1  yamaguch }
   4633       1.1  yamaguch 
   4634       1.1  yamaguch static int
   4635       1.1  yamaguch ixl_hmc(struct ixl_softc *sc)
   4636       1.1  yamaguch {
   4637       1.1  yamaguch 	struct {
   4638       1.1  yamaguch 		uint32_t   count;
   4639       1.1  yamaguch 		uint32_t   minsize;
   4640       1.1  yamaguch 		bus_size_t objsiz;
   4641       1.1  yamaguch 		bus_size_t setoff;
   4642       1.1  yamaguch 		bus_size_t setcnt;
   4643       1.1  yamaguch 	} regs[] = {
   4644       1.1  yamaguch 		{
   4645       1.1  yamaguch 			0,
   4646       1.1  yamaguch 			IXL_HMC_TXQ_MINSIZE,
   4647       1.1  yamaguch 			I40E_GLHMC_LANTXOBJSZ,
   4648       1.1  yamaguch 			I40E_GLHMC_LANTXBASE(sc->sc_pf_id),
   4649       1.1  yamaguch 			I40E_GLHMC_LANTXCNT(sc->sc_pf_id),
   4650       1.1  yamaguch 		},
   4651       1.1  yamaguch 		{
   4652       1.1  yamaguch 			0,
   4653       1.1  yamaguch 			IXL_HMC_RXQ_MINSIZE,
   4654       1.1  yamaguch 			I40E_GLHMC_LANRXOBJSZ,
   4655       1.1  yamaguch 			I40E_GLHMC_LANRXBASE(sc->sc_pf_id),
   4656       1.1  yamaguch 			I40E_GLHMC_LANRXCNT(sc->sc_pf_id),
   4657       1.1  yamaguch 		},
   4658       1.1  yamaguch 		{
   4659       1.1  yamaguch 			0,
   4660       1.1  yamaguch 			0,
   4661       1.1  yamaguch 			I40E_GLHMC_FCOEDDPOBJSZ,
   4662       1.1  yamaguch 			I40E_GLHMC_FCOEDDPBASE(sc->sc_pf_id),
   4663       1.1  yamaguch 			I40E_GLHMC_FCOEDDPCNT(sc->sc_pf_id),
   4664       1.1  yamaguch 		},
   4665       1.1  yamaguch 		{
   4666       1.1  yamaguch 			0,
   4667       1.1  yamaguch 			0,
   4668       1.1  yamaguch 			I40E_GLHMC_FCOEFOBJSZ,
   4669       1.1  yamaguch 			I40E_GLHMC_FCOEFBASE(sc->sc_pf_id),
   4670       1.1  yamaguch 			I40E_GLHMC_FCOEFCNT(sc->sc_pf_id),
   4671       1.1  yamaguch 		},
   4672       1.1  yamaguch 	};
   4673       1.1  yamaguch 	struct ixl_hmc_entry *e;
   4674       1.1  yamaguch 	uint64_t size, dva;
   4675       1.1  yamaguch 	uint8_t *kva;
   4676       1.1  yamaguch 	uint64_t *sdpage;
   4677       1.1  yamaguch 	unsigned int i;
   4678       1.1  yamaguch 	int npages, tables;
   4679       1.1  yamaguch 	uint32_t reg;
   4680       1.1  yamaguch 
   4681       1.1  yamaguch 	CTASSERT(__arraycount(regs) <= __arraycount(sc->sc_hmc_entries));
   4682       1.1  yamaguch 
   4683       1.1  yamaguch 	regs[IXL_HMC_LAN_TX].count = regs[IXL_HMC_LAN_RX].count =
   4684       1.1  yamaguch 	    ixl_rd(sc, I40E_GLHMC_LANQMAX);
   4685       1.1  yamaguch 
   4686       1.1  yamaguch 	size = 0;
   4687       1.1  yamaguch 	for (i = 0; i < __arraycount(regs); i++) {
   4688       1.1  yamaguch 		e = &sc->sc_hmc_entries[i];
   4689       1.1  yamaguch 
   4690       1.1  yamaguch 		e->hmc_count = regs[i].count;
   4691       1.1  yamaguch 		reg = ixl_rd(sc, regs[i].objsiz);
   4692       1.1  yamaguch 		e->hmc_size = BIT_ULL(0x3F & reg);
   4693       1.1  yamaguch 		e->hmc_base = size;
   4694       1.1  yamaguch 
   4695       1.1  yamaguch 		if ((e->hmc_size * 8) < regs[i].minsize) {
   4696       1.1  yamaguch 			aprint_error_dev(sc->sc_dev,
   4697       1.1  yamaguch 			    "kernel hmc entry is too big\n");
   4698       1.1  yamaguch 			return -1;
   4699       1.1  yamaguch 		}
   4700       1.1  yamaguch 
   4701       1.1  yamaguch 		size += roundup(e->hmc_size * e->hmc_count, IXL_HMC_ROUNDUP);
   4702       1.1  yamaguch 	}
   4703       1.1  yamaguch 	size = roundup(size, IXL_HMC_PGSIZE);
   4704       1.1  yamaguch 	npages = size / IXL_HMC_PGSIZE;
   4705       1.1  yamaguch 
   4706       1.1  yamaguch 	tables = roundup(size, IXL_HMC_L2SZ) / IXL_HMC_L2SZ;
   4707       1.1  yamaguch 
   4708       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &sc->sc_hmc_pd, size, IXL_HMC_PGSIZE) != 0) {
   4709       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   4710       1.1  yamaguch 		    "unable to allocate hmc pd memory\n");
   4711       1.1  yamaguch 		return -1;
   4712       1.1  yamaguch 	}
   4713       1.1  yamaguch 
   4714       1.1  yamaguch 	if (ixl_dmamem_alloc(sc, &sc->sc_hmc_sd, tables * IXL_HMC_PGSIZE,
   4715       1.1  yamaguch 	    IXL_HMC_PGSIZE) != 0) {
   4716       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   4717       1.1  yamaguch 		    "unable to allocate hmc sd memory\n");
   4718       1.1  yamaguch 		ixl_dmamem_free(sc, &sc->sc_hmc_pd);
   4719       1.1  yamaguch 		return -1;
   4720       1.1  yamaguch 	}
   4721       1.1  yamaguch 
   4722       1.1  yamaguch 	kva = IXL_DMA_KVA(&sc->sc_hmc_pd);
   4723       1.1  yamaguch 	memset(kva, 0, IXL_DMA_LEN(&sc->sc_hmc_pd));
   4724       1.1  yamaguch 
   4725       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd),
   4726       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_hmc_pd),
   4727       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   4728       1.1  yamaguch 
   4729       1.1  yamaguch 	dva = IXL_DMA_DVA(&sc->sc_hmc_pd);
   4730       1.1  yamaguch 	sdpage = IXL_DMA_KVA(&sc->sc_hmc_sd);
   4731       1.1  yamaguch 	memset(sdpage, 0, IXL_DMA_LEN(&sc->sc_hmc_sd));
   4732       1.1  yamaguch 
   4733       1.1  yamaguch 	for (i = 0; (int)i < npages; i++) {
   4734       1.1  yamaguch 		*sdpage = htole64(dva | IXL_HMC_PDVALID);
   4735       1.1  yamaguch 		sdpage++;
   4736       1.1  yamaguch 
   4737       1.1  yamaguch 		dva += IXL_HMC_PGSIZE;
   4738       1.1  yamaguch 	}
   4739       1.1  yamaguch 
   4740       1.1  yamaguch 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_sd),
   4741       1.1  yamaguch 	    0, IXL_DMA_LEN(&sc->sc_hmc_sd),
   4742       1.1  yamaguch 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   4743       1.1  yamaguch 
   4744       1.1  yamaguch 	dva = IXL_DMA_DVA(&sc->sc_hmc_sd);
   4745       1.1  yamaguch 	for (i = 0; (int)i < tables; i++) {
   4746       1.1  yamaguch 		uint32_t count;
   4747       1.1  yamaguch 
   4748       1.1  yamaguch 		KASSERT(npages >= 0);
   4749       1.1  yamaguch 
   4750       1.1  yamaguch 		count = ((unsigned int)npages > IXL_HMC_PGS) ?
   4751       1.1  yamaguch 		    IXL_HMC_PGS : (unsigned int)npages;
   4752       1.1  yamaguch 
   4753       1.1  yamaguch 		ixl_wr(sc, I40E_PFHMC_SDDATAHIGH, dva >> 32);
   4754       1.1  yamaguch 		ixl_wr(sc, I40E_PFHMC_SDDATALOW, dva |
   4755       1.1  yamaguch 		    (count << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) |
   4756       1.1  yamaguch 		    (1U << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT));
   4757       1.1  yamaguch 		ixl_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE);
   4758       1.1  yamaguch 		ixl_wr(sc, I40E_PFHMC_SDCMD,
   4759       1.1  yamaguch 		    (1U << I40E_PFHMC_SDCMD_PMSDWR_SHIFT) | i);
   4760       1.1  yamaguch 
   4761       1.1  yamaguch 		npages -= IXL_HMC_PGS;
   4762       1.1  yamaguch 		dva += IXL_HMC_PGSIZE;
   4763       1.1  yamaguch 	}
   4764       1.1  yamaguch 
   4765       1.1  yamaguch 	for (i = 0; i < __arraycount(regs); i++) {
   4766       1.1  yamaguch 		e = &sc->sc_hmc_entries[i];
   4767       1.1  yamaguch 
   4768       1.1  yamaguch 		ixl_wr(sc, regs[i].setoff, e->hmc_base / IXL_HMC_ROUNDUP);
   4769       1.1  yamaguch 		ixl_wr(sc, regs[i].setcnt, e->hmc_count);
   4770       1.1  yamaguch 	}
   4771       1.1  yamaguch 
   4772       1.1  yamaguch 	return 0;
   4773       1.1  yamaguch }
   4774       1.1  yamaguch 
   4775       1.1  yamaguch static void
   4776       1.1  yamaguch ixl_hmc_free(struct ixl_softc *sc)
   4777       1.1  yamaguch {
   4778       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_hmc_sd);
   4779       1.1  yamaguch 	ixl_dmamem_free(sc, &sc->sc_hmc_pd);
   4780       1.1  yamaguch }
   4781       1.1  yamaguch 
   4782       1.1  yamaguch static void
   4783       1.1  yamaguch ixl_hmc_pack(void *d, const void *s, const struct ixl_hmc_pack *packing,
   4784       1.1  yamaguch     unsigned int npacking)
   4785       1.1  yamaguch {
   4786       1.1  yamaguch 	uint8_t *dst = d;
   4787       1.1  yamaguch 	const uint8_t *src = s;
   4788       1.1  yamaguch 	unsigned int i;
   4789       1.1  yamaguch 
   4790       1.1  yamaguch 	for (i = 0; i < npacking; i++) {
   4791       1.1  yamaguch 		const struct ixl_hmc_pack *pack = &packing[i];
   4792       1.1  yamaguch 		unsigned int offset = pack->lsb / 8;
   4793       1.1  yamaguch 		unsigned int align = pack->lsb % 8;
   4794       1.1  yamaguch 		const uint8_t *in = src + pack->offset;
   4795       1.1  yamaguch 		uint8_t *out = dst + offset;
   4796       1.1  yamaguch 		int width = pack->width;
   4797       1.1  yamaguch 		unsigned int inbits = 0;
   4798       1.1  yamaguch 
   4799       1.1  yamaguch 		if (align) {
   4800       1.1  yamaguch 			inbits = (*in++) << align;
   4801       1.1  yamaguch 			*out++ |= (inbits & 0xff);
   4802       1.1  yamaguch 			inbits >>= 8;
   4803       1.1  yamaguch 
   4804       1.1  yamaguch 			width -= 8 - align;
   4805       1.1  yamaguch 		}
   4806       1.1  yamaguch 
   4807       1.1  yamaguch 		while (width >= 8) {
   4808       1.1  yamaguch 			inbits |= (*in++) << align;
   4809       1.1  yamaguch 			*out++ = (inbits & 0xff);
   4810       1.1  yamaguch 			inbits >>= 8;
   4811       1.1  yamaguch 
   4812       1.1  yamaguch 			width -= 8;
   4813       1.1  yamaguch 		}
   4814       1.1  yamaguch 
   4815       1.1  yamaguch 		if (width > 0) {
   4816       1.1  yamaguch 			inbits |= (*in) << align;
   4817       1.1  yamaguch 			*out |= (inbits & ((1 << width) - 1));
   4818       1.1  yamaguch 		}
   4819       1.1  yamaguch 	}
   4820       1.1  yamaguch }
   4821       1.1  yamaguch 
   4822       1.1  yamaguch static struct ixl_aq_buf *
   4823       1.1  yamaguch ixl_aqb_alloc(struct ixl_softc *sc)
   4824       1.1  yamaguch {
   4825       1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4826       1.1  yamaguch 
   4827       1.1  yamaguch 	aqb = malloc(sizeof(*aqb), M_DEVBUF, M_WAITOK);
   4828       1.1  yamaguch 	if (aqb == NULL)
   4829       1.1  yamaguch 		return NULL;
   4830       1.1  yamaguch 
   4831       1.1  yamaguch 	aqb->aqb_size = IXL_AQ_BUFLEN;
   4832       1.1  yamaguch 
   4833       1.1  yamaguch 	if (bus_dmamap_create(sc->sc_dmat, aqb->aqb_size, 1,
   4834       1.1  yamaguch 	    aqb->aqb_size, 0,
   4835       1.1  yamaguch 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &aqb->aqb_map) != 0)
   4836       1.1  yamaguch 		goto free;
   4837       1.1  yamaguch 	if (bus_dmamem_alloc(sc->sc_dmat, aqb->aqb_size,
   4838       1.1  yamaguch 	    IXL_AQ_ALIGN, 0, &aqb->aqb_seg, 1, &aqb->aqb_nsegs,
   4839       1.1  yamaguch 	    BUS_DMA_WAITOK) != 0)
   4840       1.1  yamaguch 		goto destroy;
   4841       1.1  yamaguch 	if (bus_dmamem_map(sc->sc_dmat, &aqb->aqb_seg, aqb->aqb_nsegs,
   4842       1.1  yamaguch 	    aqb->aqb_size, &aqb->aqb_data, BUS_DMA_WAITOK) != 0)
   4843       1.1  yamaguch 		goto dma_free;
   4844       1.1  yamaguch 	if (bus_dmamap_load(sc->sc_dmat, aqb->aqb_map, aqb->aqb_data,
   4845       1.1  yamaguch 	    aqb->aqb_size, NULL, BUS_DMA_WAITOK) != 0)
   4846       1.1  yamaguch 		goto unmap;
   4847       1.1  yamaguch 
   4848       1.1  yamaguch 	return aqb;
   4849       1.1  yamaguch unmap:
   4850       1.1  yamaguch 	bus_dmamem_unmap(sc->sc_dmat, aqb->aqb_data, aqb->aqb_size);
   4851       1.1  yamaguch dma_free:
   4852       1.1  yamaguch 	bus_dmamem_free(sc->sc_dmat, &aqb->aqb_seg, 1);
   4853       1.1  yamaguch destroy:
   4854       1.1  yamaguch 	bus_dmamap_destroy(sc->sc_dmat, aqb->aqb_map);
   4855       1.1  yamaguch free:
   4856       1.1  yamaguch 	free(aqb, M_DEVBUF);
   4857       1.1  yamaguch 
   4858       1.1  yamaguch 	return NULL;
   4859       1.1  yamaguch }
   4860       1.1  yamaguch 
   4861       1.1  yamaguch static void
   4862       1.1  yamaguch ixl_aqb_free(struct ixl_softc *sc, struct ixl_aq_buf *aqb)
   4863       1.1  yamaguch {
   4864       1.1  yamaguch 	bus_dmamap_unload(sc->sc_dmat, aqb->aqb_map);
   4865       1.1  yamaguch 	bus_dmamem_unmap(sc->sc_dmat, aqb->aqb_data, aqb->aqb_size);
   4866       1.1  yamaguch 	bus_dmamem_free(sc->sc_dmat, &aqb->aqb_seg, 1);
   4867       1.1  yamaguch 	bus_dmamap_destroy(sc->sc_dmat, aqb->aqb_map);
   4868       1.1  yamaguch 	free(aqb, M_DEVBUF);
   4869       1.1  yamaguch }
   4870       1.1  yamaguch 
   4871       1.1  yamaguch static int
   4872       1.1  yamaguch ixl_arq_fill(struct ixl_softc *sc)
   4873       1.1  yamaguch {
   4874       1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4875       1.1  yamaguch 	struct ixl_aq_desc *arq, *iaq;
   4876       1.1  yamaguch 	unsigned int prod = sc->sc_arq_prod;
   4877       1.1  yamaguch 	unsigned int n;
   4878       1.1  yamaguch 	int post = 0;
   4879       1.1  yamaguch 
   4880       1.1  yamaguch 	n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons,
   4881       1.1  yamaguch 	    IXL_AQ_NUM);
   4882       1.1  yamaguch 	arq = IXL_DMA_KVA(&sc->sc_arq);
   4883       1.1  yamaguch 
   4884       1.1  yamaguch 	if (__predict_false(n <= 0))
   4885       1.1  yamaguch 		return 0;
   4886       1.1  yamaguch 
   4887       1.1  yamaguch 	do {
   4888       1.1  yamaguch 		aqb = sc->sc_arq_live[prod];
   4889       1.1  yamaguch 		iaq = &arq[prod];
   4890       1.1  yamaguch 
   4891       1.1  yamaguch 		if (aqb == NULL) {
   4892       1.1  yamaguch 			aqb = SIMPLEQ_FIRST(&sc->sc_arq_idle);
   4893       1.1  yamaguch 			if (aqb != NULL) {
   4894       1.1  yamaguch 				SIMPLEQ_REMOVE(&sc->sc_arq_idle, aqb,
   4895       1.1  yamaguch 				    ixl_aq_buf, aqb_entry);
   4896       1.1  yamaguch 			} else if ((aqb = ixl_aqb_alloc(sc)) == NULL) {
   4897       1.1  yamaguch 				break;
   4898       1.1  yamaguch 			}
   4899       1.1  yamaguch 
   4900       1.1  yamaguch 			sc->sc_arq_live[prod] = aqb;
   4901       1.1  yamaguch 			memset(aqb->aqb_data, 0, aqb->aqb_size);
   4902       1.1  yamaguch 
   4903       1.1  yamaguch 			bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0,
   4904       1.1  yamaguch 			    aqb->aqb_size, BUS_DMASYNC_PREREAD);
   4905       1.1  yamaguch 
   4906       1.1  yamaguch 			iaq->iaq_flags = htole16(IXL_AQ_BUF |
   4907       1.1  yamaguch 			    (IXL_AQ_BUFLEN > I40E_AQ_LARGE_BUF ?
   4908       1.1  yamaguch 			    IXL_AQ_LB : 0));
   4909       1.1  yamaguch 			iaq->iaq_opcode = 0;
   4910       1.1  yamaguch 			iaq->iaq_datalen = htole16(aqb->aqb_size);
   4911       1.1  yamaguch 			iaq->iaq_retval = 0;
   4912       1.1  yamaguch 			iaq->iaq_cookie = 0;
   4913       1.1  yamaguch 			iaq->iaq_param[0] = 0;
   4914       1.1  yamaguch 			iaq->iaq_param[1] = 0;
   4915       1.1  yamaguch 			ixl_aq_dva(iaq, aqb->aqb_map->dm_segs[0].ds_addr);
   4916       1.1  yamaguch 		}
   4917       1.1  yamaguch 
   4918       1.1  yamaguch 		prod++;
   4919       1.1  yamaguch 		prod &= IXL_AQ_MASK;
   4920       1.1  yamaguch 
   4921       1.1  yamaguch 		post = 1;
   4922       1.1  yamaguch 
   4923       1.1  yamaguch 	} while (--n);
   4924       1.1  yamaguch 
   4925       1.1  yamaguch 	if (post) {
   4926       1.1  yamaguch 		sc->sc_arq_prod = prod;
   4927       1.1  yamaguch 		ixl_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod);
   4928       1.1  yamaguch 	}
   4929       1.1  yamaguch 
   4930       1.1  yamaguch 	return post;
   4931       1.1  yamaguch }
   4932       1.1  yamaguch 
   4933       1.1  yamaguch static void
   4934       1.1  yamaguch ixl_arq_unfill(struct ixl_softc *sc)
   4935       1.1  yamaguch {
   4936       1.1  yamaguch 	struct ixl_aq_buf *aqb;
   4937       1.1  yamaguch 	unsigned int i;
   4938       1.1  yamaguch 
   4939       1.1  yamaguch 	for (i = 0; i < __arraycount(sc->sc_arq_live); i++) {
   4940       1.1  yamaguch 		aqb = sc->sc_arq_live[i];
   4941       1.1  yamaguch 		if (aqb == NULL)
   4942       1.1  yamaguch 			continue;
   4943       1.1  yamaguch 
   4944       1.1  yamaguch 		sc->sc_arq_live[i] = NULL;
   4945       1.1  yamaguch 		bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size,
   4946       1.1  yamaguch 		    BUS_DMASYNC_POSTREAD);
   4947       1.1  yamaguch 		ixl_aqb_free(sc, aqb);
   4948       1.1  yamaguch 	}
   4949       1.1  yamaguch 
   4950       1.1  yamaguch 	while ((aqb = SIMPLEQ_FIRST(&sc->sc_arq_idle)) != NULL) {
   4951       1.1  yamaguch 		SIMPLEQ_REMOVE(&sc->sc_arq_idle, aqb,
   4952       1.1  yamaguch 		    ixl_aq_buf, aqb_entry);
   4953       1.1  yamaguch 		ixl_aqb_free(sc, aqb);
   4954       1.1  yamaguch 	}
   4955       1.1  yamaguch }
   4956       1.1  yamaguch 
   4957       1.1  yamaguch static void
   4958       1.1  yamaguch ixl_clear_hw(struct ixl_softc *sc)
   4959       1.1  yamaguch {
   4960       1.1  yamaguch 	uint32_t num_queues, base_queue;
   4961       1.1  yamaguch 	uint32_t num_pf_int;
   4962       1.1  yamaguch 	uint32_t num_vf_int;
   4963       1.1  yamaguch 	uint32_t num_vfs;
   4964       1.1  yamaguch 	uint32_t i, j;
   4965       1.1  yamaguch 	uint32_t val;
   4966       1.1  yamaguch 	uint32_t eol = 0x7ff;
   4967       1.1  yamaguch 
   4968       1.1  yamaguch 	/* get number of interrupts, queues, and vfs */
   4969       1.1  yamaguch 	val = ixl_rd(sc, I40E_GLPCI_CNF2);
   4970       1.1  yamaguch 	num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
   4971       1.1  yamaguch 	    I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
   4972       1.1  yamaguch 	num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
   4973       1.1  yamaguch 	    I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
   4974       1.1  yamaguch 
   4975       1.1  yamaguch 	val = ixl_rd(sc, I40E_PFLAN_QALLOC);
   4976       1.1  yamaguch 	base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
   4977       1.1  yamaguch 	    I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
   4978       1.1  yamaguch 	j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
   4979       1.1  yamaguch 	    I40E_PFLAN_QALLOC_LASTQ_SHIFT;
   4980       1.1  yamaguch 	if (val & I40E_PFLAN_QALLOC_VALID_MASK)
   4981       1.1  yamaguch 		num_queues = (j - base_queue) + 1;
   4982       1.1  yamaguch 	else
   4983       1.1  yamaguch 		num_queues = 0;
   4984       1.1  yamaguch 
   4985       1.1  yamaguch 	val = ixl_rd(sc, I40E_PF_VT_PFALLOC);
   4986       1.1  yamaguch 	i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
   4987       1.1  yamaguch 	    I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
   4988       1.1  yamaguch 	j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
   4989       1.1  yamaguch 	    I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
   4990       1.1  yamaguch 	if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
   4991       1.1  yamaguch 		num_vfs = (j - i) + 1;
   4992       1.1  yamaguch 	else
   4993       1.1  yamaguch 		num_vfs = 0;
   4994       1.1  yamaguch 
   4995       1.1  yamaguch 	/* stop all the interrupts */
   4996       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ICR0_ENA, 0);
   4997       1.1  yamaguch 	ixl_flush(sc);
   4998       1.1  yamaguch 	val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
   4999       1.1  yamaguch 	for (i = 0; i < num_pf_int - 2; i++)
   5000       1.1  yamaguch 		ixl_wr(sc, I40E_PFINT_DYN_CTLN(i), val);
   5001       1.1  yamaguch 	ixl_flush(sc);
   5002       1.1  yamaguch 
   5003       1.1  yamaguch 	/* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
   5004       1.1  yamaguch 	val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
   5005       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_LNKLST0, val);
   5006       1.1  yamaguch 	for (i = 0; i < num_pf_int - 2; i++)
   5007       1.1  yamaguch 		ixl_wr(sc, I40E_PFINT_LNKLSTN(i), val);
   5008       1.1  yamaguch 	val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
   5009       1.1  yamaguch 	for (i = 0; i < num_vfs; i++)
   5010       1.1  yamaguch 		ixl_wr(sc, I40E_VPINT_LNKLST0(i), val);
   5011       1.1  yamaguch 	for (i = 0; i < num_vf_int - 2; i++)
   5012       1.1  yamaguch 		ixl_wr(sc, I40E_VPINT_LNKLSTN(i), val);
   5013       1.1  yamaguch 
   5014       1.1  yamaguch 	/* warn the HW of the coming Tx disables */
   5015       1.1  yamaguch 	for (i = 0; i < num_queues; i++) {
   5016       1.1  yamaguch 		uint32_t abs_queue_idx = base_queue + i;
   5017       1.1  yamaguch 		uint32_t reg_block = 0;
   5018       1.1  yamaguch 
   5019       1.1  yamaguch 		if (abs_queue_idx >= 128) {
   5020       1.1  yamaguch 			reg_block = abs_queue_idx / 128;
   5021       1.1  yamaguch 			abs_queue_idx %= 128;
   5022       1.1  yamaguch 		}
   5023       1.1  yamaguch 
   5024       1.1  yamaguch 		val = ixl_rd(sc, I40E_GLLAN_TXPRE_QDIS(reg_block));
   5025       1.1  yamaguch 		val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
   5026       1.1  yamaguch 		val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
   5027       1.1  yamaguch 		val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
   5028       1.1  yamaguch 
   5029       1.1  yamaguch 		ixl_wr(sc, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
   5030       1.1  yamaguch 	}
   5031       1.1  yamaguch 	delaymsec(400);
   5032       1.1  yamaguch 
   5033       1.1  yamaguch 	/* stop all the queues */
   5034       1.1  yamaguch 	for (i = 0; i < num_queues; i++) {
   5035       1.1  yamaguch 		ixl_wr(sc, I40E_QINT_TQCTL(i), 0);
   5036       1.1  yamaguch 		ixl_wr(sc, I40E_QTX_ENA(i), 0);
   5037       1.1  yamaguch 		ixl_wr(sc, I40E_QINT_RQCTL(i), 0);
   5038       1.1  yamaguch 		ixl_wr(sc, I40E_QRX_ENA(i), 0);
   5039       1.1  yamaguch 	}
   5040       1.1  yamaguch 
   5041       1.1  yamaguch 	/* short wait for all queue disables to settle */
   5042       1.1  yamaguch 	delaymsec(50);
   5043       1.1  yamaguch }
   5044       1.1  yamaguch 
   5045       1.1  yamaguch static int
   5046       1.1  yamaguch ixl_pf_reset(struct ixl_softc *sc)
   5047       1.1  yamaguch {
   5048       1.1  yamaguch 	uint32_t cnt = 0;
   5049       1.1  yamaguch 	uint32_t cnt1 = 0;
   5050       1.1  yamaguch 	uint32_t reg = 0, reg0 = 0;
   5051       1.1  yamaguch 	uint32_t grst_del;
   5052       1.1  yamaguch 
   5053       1.1  yamaguch 	/*
   5054       1.1  yamaguch 	 * Poll for Global Reset steady state in case of recent GRST.
   5055       1.1  yamaguch 	 * The grst delay value is in 100ms units, and we'll wait a
   5056       1.1  yamaguch 	 * couple counts longer to be sure we don't just miss the end.
   5057       1.1  yamaguch 	 */
   5058       1.1  yamaguch 	grst_del = ixl_rd(sc, I40E_GLGEN_RSTCTL);
   5059       1.1  yamaguch 	grst_del &= I40E_GLGEN_RSTCTL_GRSTDEL_MASK;
   5060       1.1  yamaguch 	grst_del >>= I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
   5061       1.1  yamaguch 
   5062       1.1  yamaguch 	grst_del = grst_del * 20;
   5063       1.1  yamaguch 
   5064       1.1  yamaguch 	for (cnt = 0; cnt < grst_del; cnt++) {
   5065       1.1  yamaguch 		reg = ixl_rd(sc, I40E_GLGEN_RSTAT);
   5066       1.1  yamaguch 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
   5067       1.1  yamaguch 			break;
   5068       1.1  yamaguch 		delaymsec(100);
   5069       1.1  yamaguch 	}
   5070       1.1  yamaguch 	if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
   5071       1.1  yamaguch 		aprint_error(", Global reset polling failed to complete\n");
   5072       1.1  yamaguch 		return -1;
   5073       1.1  yamaguch 	}
   5074       1.1  yamaguch 
   5075       1.1  yamaguch 	/* Now Wait for the FW to be ready */
   5076       1.1  yamaguch 	for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
   5077       1.1  yamaguch 		reg = ixl_rd(sc, I40E_GLNVM_ULD);
   5078       1.1  yamaguch 		reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
   5079       1.1  yamaguch 		    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
   5080       1.1  yamaguch 		if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
   5081       1.1  yamaguch 		    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))
   5082       1.1  yamaguch 			break;
   5083       1.1  yamaguch 
   5084       1.1  yamaguch 		delaymsec(10);
   5085       1.1  yamaguch 	}
   5086       1.1  yamaguch 	if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
   5087       1.1  yamaguch 	    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
   5088       1.1  yamaguch 		aprint_error(", wait for FW Reset complete timed out "
   5089       1.1  yamaguch 		    "(I40E_GLNVM_ULD = 0x%x)\n", reg);
   5090       1.1  yamaguch 		return -1;
   5091       1.1  yamaguch 	}
   5092       1.1  yamaguch 
   5093       1.1  yamaguch 	/*
   5094       1.1  yamaguch 	 * If there was a Global Reset in progress when we got here,
   5095       1.1  yamaguch 	 * we don't need to do the PF Reset
   5096       1.1  yamaguch 	 */
   5097       1.1  yamaguch 	if (cnt == 0) {
   5098       1.1  yamaguch 		reg = ixl_rd(sc, I40E_PFGEN_CTRL);
   5099       1.1  yamaguch 		ixl_wr(sc, I40E_PFGEN_CTRL, reg | I40E_PFGEN_CTRL_PFSWR_MASK);
   5100       1.1  yamaguch 		for (cnt = 0; cnt < I40E_PF_RESET_WAIT_COUNT; cnt++) {
   5101       1.1  yamaguch 			reg = ixl_rd(sc, I40E_PFGEN_CTRL);
   5102       1.1  yamaguch 			if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
   5103       1.1  yamaguch 				break;
   5104       1.1  yamaguch 			delaymsec(1);
   5105       1.1  yamaguch 
   5106       1.1  yamaguch 			reg0 = ixl_rd(sc, I40E_GLGEN_RSTAT);
   5107       1.1  yamaguch 			if (reg0 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
   5108       1.1  yamaguch 				aprint_error(", Core reset upcoming."
   5109       1.1  yamaguch 				    " Skipping PF reset reset request\n");
   5110       1.1  yamaguch 				return -1;
   5111       1.1  yamaguch 			}
   5112       1.1  yamaguch 		}
   5113       1.1  yamaguch 		if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
   5114       1.1  yamaguch 			aprint_error(", PF reset polling failed to complete"
   5115       1.1  yamaguch 			    "(I40E_PFGEN_CTRL= 0x%x)\n", reg);
   5116       1.1  yamaguch 			return -1;
   5117       1.1  yamaguch 		}
   5118       1.1  yamaguch 	}
   5119       1.1  yamaguch 
   5120       1.1  yamaguch 	return 0;
   5121       1.1  yamaguch }
   5122       1.1  yamaguch 
   5123       1.1  yamaguch static int
   5124       1.1  yamaguch ixl_dmamem_alloc(struct ixl_softc *sc, struct ixl_dmamem *ixm,
   5125       1.1  yamaguch     bus_size_t size, bus_size_t align)
   5126       1.1  yamaguch {
   5127       1.1  yamaguch 	ixm->ixm_size = size;
   5128       1.1  yamaguch 
   5129       1.1  yamaguch 	if (bus_dmamap_create(sc->sc_dmat, ixm->ixm_size, 1,
   5130       1.1  yamaguch 	    ixm->ixm_size, 0,
   5131       1.1  yamaguch 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
   5132       1.1  yamaguch 	    &ixm->ixm_map) != 0)
   5133       1.1  yamaguch 		return 1;
   5134       1.1  yamaguch 	if (bus_dmamem_alloc(sc->sc_dmat, ixm->ixm_size,
   5135       1.1  yamaguch 	    align, 0, &ixm->ixm_seg, 1, &ixm->ixm_nsegs,
   5136       1.1  yamaguch 	    BUS_DMA_WAITOK) != 0)
   5137       1.1  yamaguch 		goto destroy;
   5138       1.1  yamaguch 	if (bus_dmamem_map(sc->sc_dmat, &ixm->ixm_seg, ixm->ixm_nsegs,
   5139       1.1  yamaguch 	    ixm->ixm_size, &ixm->ixm_kva, BUS_DMA_WAITOK) != 0)
   5140       1.1  yamaguch 		goto free;
   5141       1.1  yamaguch 	if (bus_dmamap_load(sc->sc_dmat, ixm->ixm_map, ixm->ixm_kva,
   5142       1.1  yamaguch 	    ixm->ixm_size, NULL, BUS_DMA_WAITOK) != 0)
   5143       1.1  yamaguch 		goto unmap;
   5144       1.1  yamaguch 
   5145       1.1  yamaguch 	memset(ixm->ixm_kva, 0, ixm->ixm_size);
   5146       1.1  yamaguch 
   5147       1.1  yamaguch 	return 0;
   5148       1.1  yamaguch unmap:
   5149       1.1  yamaguch 	bus_dmamem_unmap(sc->sc_dmat, ixm->ixm_kva, ixm->ixm_size);
   5150       1.1  yamaguch free:
   5151       1.1  yamaguch 	bus_dmamem_free(sc->sc_dmat, &ixm->ixm_seg, 1);
   5152       1.1  yamaguch destroy:
   5153       1.1  yamaguch 	bus_dmamap_destroy(sc->sc_dmat, ixm->ixm_map);
   5154       1.1  yamaguch 	return 1;
   5155       1.1  yamaguch }
   5156       1.1  yamaguch 
   5157       1.1  yamaguch static void
   5158       1.1  yamaguch ixl_dmamem_free(struct ixl_softc *sc, struct ixl_dmamem *ixm)
   5159       1.1  yamaguch {
   5160       1.1  yamaguch 	bus_dmamap_unload(sc->sc_dmat, ixm->ixm_map);
   5161       1.1  yamaguch 	bus_dmamem_unmap(sc->sc_dmat, ixm->ixm_kva, ixm->ixm_size);
   5162       1.1  yamaguch 	bus_dmamem_free(sc->sc_dmat, &ixm->ixm_seg, 1);
   5163       1.1  yamaguch 	bus_dmamap_destroy(sc->sc_dmat, ixm->ixm_map);
   5164       1.1  yamaguch }
   5165       1.1  yamaguch 
   5166       1.1  yamaguch static int
   5167      1.12  yamaguch ixl_setup_vlan_hwfilter(struct ixl_softc *sc)
   5168       1.1  yamaguch {
   5169      1.12  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   5170      1.12  yamaguch 	struct vlanid_list *vlanidp;
   5171      1.12  yamaguch 	int rv;
   5172      1.12  yamaguch 
   5173      1.12  yamaguch 	ixl_remove_macvlan(sc, sc->sc_enaddr, 0,
   5174      1.12  yamaguch 	    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   5175      1.12  yamaguch 	ixl_remove_macvlan(sc, etherbroadcastaddr, 0,
   5176      1.12  yamaguch 	    IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN);
   5177       1.1  yamaguch 
   5178      1.12  yamaguch 	rv = ixl_add_macvlan(sc, sc->sc_enaddr, 0,
   5179      1.12  yamaguch 	    IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   5180      1.12  yamaguch 	if (rv != 0)
   5181      1.12  yamaguch 		return rv;
   5182      1.12  yamaguch 	rv = ixl_add_macvlan(sc, etherbroadcastaddr, 0,
   5183      1.12  yamaguch 	    IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   5184      1.12  yamaguch 	if (rv != 0)
   5185      1.12  yamaguch 		return rv;
   5186       1.1  yamaguch 
   5187      1.12  yamaguch 	ETHER_LOCK(ec);
   5188      1.12  yamaguch 	SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
   5189      1.12  yamaguch 		rv = ixl_add_macvlan(sc, sc->sc_enaddr,
   5190      1.12  yamaguch 		    vlanidp->vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   5191      1.12  yamaguch 		if (rv != 0)
   5192      1.12  yamaguch 			break;
   5193      1.12  yamaguch 		rv = ixl_add_macvlan(sc, etherbroadcastaddr,
   5194      1.12  yamaguch 		    vlanidp->vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH);
   5195      1.12  yamaguch 		if (rv != 0)
   5196      1.12  yamaguch 			break;
   5197       1.1  yamaguch 	}
   5198      1.12  yamaguch 	ETHER_UNLOCK(ec);
   5199       1.1  yamaguch 
   5200      1.12  yamaguch 	return rv;
   5201      1.12  yamaguch }
   5202      1.12  yamaguch 
   5203      1.12  yamaguch static void
   5204      1.12  yamaguch ixl_teardown_vlan_hwfilter(struct ixl_softc *sc)
   5205      1.12  yamaguch {
   5206      1.12  yamaguch 	struct vlanid_list *vlanidp;
   5207      1.12  yamaguch 	struct ethercom *ec = &sc->sc_ec;
   5208      1.12  yamaguch 
   5209      1.12  yamaguch 	ixl_remove_macvlan(sc, sc->sc_enaddr, 0,
   5210      1.12  yamaguch 	    IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   5211      1.12  yamaguch 	ixl_remove_macvlan(sc, etherbroadcastaddr, 0,
   5212      1.12  yamaguch 	    IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   5213      1.12  yamaguch 
   5214      1.12  yamaguch 	ETHER_LOCK(ec);
   5215      1.12  yamaguch 	SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
   5216      1.12  yamaguch 		ixl_remove_macvlan(sc, sc->sc_enaddr,
   5217      1.12  yamaguch 		    vlanidp->vid, IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   5218      1.12  yamaguch 		ixl_remove_macvlan(sc, etherbroadcastaddr,
   5219      1.12  yamaguch 		    vlanidp->vid, IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH);
   5220       1.1  yamaguch 	}
   5221      1.12  yamaguch 	ETHER_UNLOCK(ec);
   5222       1.1  yamaguch 
   5223      1.12  yamaguch 	ixl_add_macvlan(sc, sc->sc_enaddr, 0,
   5224       1.1  yamaguch 	    IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN);
   5225      1.12  yamaguch 	ixl_add_macvlan(sc, etherbroadcastaddr, 0,
   5226      1.12  yamaguch 	    IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN);
   5227      1.12  yamaguch }
   5228      1.12  yamaguch 
   5229      1.12  yamaguch static int
   5230      1.12  yamaguch ixl_update_macvlan(struct ixl_softc *sc)
   5231      1.12  yamaguch {
   5232      1.12  yamaguch 	int rv = 0;
   5233      1.12  yamaguch 	int next_ec_capenable = sc->sc_ec.ec_capenable;
   5234       1.1  yamaguch 
   5235      1.12  yamaguch 	if (ISSET(next_ec_capenable, ETHERCAP_VLAN_HWFILTER)) {
   5236      1.12  yamaguch 		rv = ixl_setup_vlan_hwfilter(sc);
   5237      1.12  yamaguch 		if (rv != 0)
   5238      1.12  yamaguch 			ixl_teardown_vlan_hwfilter(sc);
   5239      1.12  yamaguch 	} else {
   5240      1.12  yamaguch 		ixl_teardown_vlan_hwfilter(sc);
   5241       1.1  yamaguch 	}
   5242       1.1  yamaguch 
   5243       1.1  yamaguch 	return rv;
   5244       1.1  yamaguch }
   5245       1.1  yamaguch 
   5246       1.1  yamaguch static int
   5247       1.1  yamaguch ixl_ifflags_cb(struct ethercom *ec)
   5248       1.1  yamaguch {
   5249       1.9  yamaguch 	struct ifnet *ifp = &ec->ec_if;
   5250       1.9  yamaguch 	struct ixl_softc *sc = ifp->if_softc;
   5251      1.11  yamaguch 	int rv, change;
   5252       1.9  yamaguch 
   5253       1.9  yamaguch 	mutex_enter(&sc->sc_cfg_lock);
   5254      1.11  yamaguch 
   5255      1.11  yamaguch 	change = ec->ec_capenable ^ sc->sc_cur_ec_capenable;
   5256      1.11  yamaguch 
   5257      1.11  yamaguch 	if (ISSET(change, ETHERCAP_VLAN_HWTAGGING)) {
   5258      1.12  yamaguch 		sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWTAGGING;
   5259      1.11  yamaguch 		rv = ENETRESET;
   5260      1.11  yamaguch 		goto out;
   5261      1.11  yamaguch 	}
   5262      1.11  yamaguch 
   5263      1.12  yamaguch 	if (ISSET(change, ETHERCAP_VLAN_HWFILTER)) {
   5264      1.12  yamaguch 		rv = ixl_update_macvlan(sc);
   5265      1.12  yamaguch 		if (rv == 0) {
   5266      1.12  yamaguch 			sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWFILTER;
   5267      1.12  yamaguch 		} else {
   5268      1.12  yamaguch 			CLR(ec->ec_capenable, ETHERCAP_VLAN_HWFILTER);
   5269      1.12  yamaguch 			CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER);
   5270      1.12  yamaguch 		}
   5271      1.12  yamaguch 	}
   5272      1.12  yamaguch 
   5273       1.9  yamaguch 	rv = ixl_iff(sc);
   5274      1.11  yamaguch out:
   5275       1.9  yamaguch 	mutex_exit(&sc->sc_cfg_lock);
   5276       1.1  yamaguch 
   5277       1.9  yamaguch 	return rv;
   5278       1.1  yamaguch }
   5279       1.1  yamaguch 
   5280       1.1  yamaguch static int
   5281       1.1  yamaguch ixl_set_link_status(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
   5282       1.1  yamaguch {
   5283       1.1  yamaguch 	const struct ixl_aq_link_status *status;
   5284       1.1  yamaguch 	const struct ixl_phy_type *itype;
   5285       1.1  yamaguch 
   5286       1.1  yamaguch 	uint64_t ifm_active = IFM_ETHER;
   5287       1.1  yamaguch 	uint64_t ifm_status = IFM_AVALID;
   5288       1.1  yamaguch 	int link_state = LINK_STATE_DOWN;
   5289       1.1  yamaguch 	uint64_t baudrate = 0;
   5290       1.1  yamaguch 
   5291       1.1  yamaguch 	status = (const struct ixl_aq_link_status *)iaq->iaq_param;
   5292       1.1  yamaguch 	if (!ISSET(status->link_info, IXL_AQ_LINK_UP_FUNCTION))
   5293       1.1  yamaguch 		goto done;
   5294       1.1  yamaguch 
   5295       1.1  yamaguch 	ifm_active |= IFM_FDX;
   5296       1.1  yamaguch 	ifm_status |= IFM_ACTIVE;
   5297       1.1  yamaguch 	link_state = LINK_STATE_UP;
   5298       1.1  yamaguch 
   5299       1.1  yamaguch 	itype = ixl_search_phy_type(status->phy_type);
   5300       1.1  yamaguch 	if (itype != NULL)
   5301       1.1  yamaguch 		ifm_active |= itype->ifm_type;
   5302       1.1  yamaguch 
   5303       1.1  yamaguch 	if (ISSET(status->an_info, IXL_AQ_LINK_PAUSE_TX))
   5304       1.1  yamaguch 		ifm_active |= IFM_ETH_TXPAUSE;
   5305       1.1  yamaguch 	if (ISSET(status->an_info, IXL_AQ_LINK_PAUSE_RX))
   5306       1.1  yamaguch 		ifm_active |= IFM_ETH_RXPAUSE;
   5307       1.1  yamaguch 
   5308       1.1  yamaguch 	baudrate = ixl_search_link_speed(status->link_speed);
   5309       1.1  yamaguch 
   5310       1.1  yamaguch done:
   5311       1.1  yamaguch 	/* NET_ASSERT_LOCKED() except during attach */
   5312       1.1  yamaguch 	sc->sc_media_active = ifm_active;
   5313       1.1  yamaguch 	sc->sc_media_status = ifm_status;
   5314       1.1  yamaguch 
   5315       1.1  yamaguch 	sc->sc_ec.ec_if.if_baudrate = baudrate;
   5316       1.1  yamaguch 
   5317       1.1  yamaguch 	return link_state;
   5318       1.1  yamaguch }
   5319       1.1  yamaguch 
   5320       1.1  yamaguch static int
   5321       1.1  yamaguch ixl_establish_intx(struct ixl_softc *sc)
   5322       1.1  yamaguch {
   5323       1.1  yamaguch 	pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
   5324       1.1  yamaguch 	pci_intr_handle_t *intr;
   5325       1.1  yamaguch 	char xnamebuf[32];
   5326       1.1  yamaguch 	char intrbuf[PCI_INTRSTR_LEN];
   5327       1.1  yamaguch 	char const *intrstr;
   5328       1.1  yamaguch 
   5329       1.1  yamaguch 	KASSERT(sc->sc_nintrs == 1);
   5330       1.1  yamaguch 
   5331       1.1  yamaguch 	intr = &sc->sc_ihp[0];
   5332       1.1  yamaguch 
   5333       1.1  yamaguch 	intrstr = pci_intr_string(pc, *intr, intrbuf, sizeof(intrbuf));
   5334       1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s:legacy",
   5335       1.1  yamaguch 	    device_xname(sc->sc_dev));
   5336       1.1  yamaguch 
   5337       1.1  yamaguch 	sc->sc_ihs[0] = pci_intr_establish_xname(pc, *intr, IPL_NET, ixl_intr,
   5338       1.1  yamaguch 	    sc, xnamebuf);
   5339       1.1  yamaguch 
   5340       1.1  yamaguch 	if (sc->sc_ihs[0] == NULL) {
   5341       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   5342       1.1  yamaguch 		    "unable to establish interrupt at %s\n", intrstr);
   5343       1.1  yamaguch 		return -1;
   5344       1.1  yamaguch 	}
   5345       1.1  yamaguch 
   5346       1.1  yamaguch 	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
   5347       1.1  yamaguch 	return 0;
   5348       1.1  yamaguch }
   5349       1.1  yamaguch 
   5350       1.1  yamaguch static int
   5351       1.1  yamaguch ixl_establish_msix(struct ixl_softc *sc)
   5352       1.1  yamaguch {
   5353       1.1  yamaguch 	pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
   5354  1.16.2.1        ad 	kcpuset_t *affinity;
   5355       1.1  yamaguch 	unsigned int vector = 0;
   5356       1.1  yamaguch 	unsigned int i;
   5357  1.16.2.1        ad 	int affinity_to, r;
   5358       1.1  yamaguch 	char xnamebuf[32];
   5359       1.1  yamaguch 	char intrbuf[PCI_INTRSTR_LEN];
   5360       1.1  yamaguch 	char const *intrstr;
   5361       1.1  yamaguch 
   5362  1.16.2.1        ad 	kcpuset_create(&affinity, false);
   5363  1.16.2.1        ad 
   5364       1.1  yamaguch 	/* the "other" intr is mapped to vector 0 */
   5365       1.1  yamaguch 	vector = 0;
   5366       1.1  yamaguch 	intrstr = pci_intr_string(pc, sc->sc_ihp[vector],
   5367       1.1  yamaguch 	    intrbuf, sizeof(intrbuf));
   5368       1.1  yamaguch 	snprintf(xnamebuf, sizeof(xnamebuf), "%s others",
   5369       1.1  yamaguch 	    device_xname(sc->sc_dev));
   5370       1.1  yamaguch 	sc->sc_ihs[vector] = pci_intr_establish_xname(pc,
   5371       1.1  yamaguch 	    sc->sc_ihp[vector], IPL_NET, ixl_other_intr,
   5372       1.1  yamaguch 	    sc, xnamebuf);
   5373       1.1  yamaguch 	if (sc->sc_ihs[vector] == NULL) {
   5374       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   5375       1.1  yamaguch 		    "unable to establish interrupt at %s\n", intrstr);
   5376       1.1  yamaguch 		goto fail;
   5377       1.1  yamaguch 	}
   5378  1.16.2.1        ad 
   5379  1.16.2.1        ad 	aprint_normal_dev(sc->sc_dev, "other interrupt at %s", intrstr);
   5380  1.16.2.1        ad 
   5381  1.16.2.1        ad 	affinity_to = ncpu > (int)sc->sc_nqueue_pairs_max ? 1 : 0;
   5382  1.16.2.1        ad 	affinity_to = (affinity_to + sc->sc_nqueue_pairs_max) % ncpu;
   5383  1.16.2.1        ad 
   5384  1.16.2.1        ad 	kcpuset_zero(affinity);
   5385  1.16.2.1        ad 	kcpuset_set(affinity, affinity_to);
   5386  1.16.2.1        ad 	r = interrupt_distribute(sc->sc_ihs[vector], affinity, NULL);
   5387  1.16.2.1        ad 	if (r == 0) {
   5388  1.16.2.1        ad 		aprint_normal(", affinity to %u", affinity_to);
   5389  1.16.2.1        ad 	}
   5390  1.16.2.1        ad 	aprint_normal("\n");
   5391       1.1  yamaguch 	vector++;
   5392       1.1  yamaguch 
   5393       1.1  yamaguch 	sc->sc_msix_vector_queue = vector;
   5394  1.16.2.1        ad 	affinity_to = ncpu > (int)sc->sc_nqueue_pairs_max ? 1 : 0;
   5395       1.1  yamaguch 
   5396       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   5397       1.1  yamaguch 		intrstr = pci_intr_string(pc, sc->sc_ihp[vector],
   5398       1.1  yamaguch 		    intrbuf, sizeof(intrbuf));
   5399       1.1  yamaguch 		snprintf(xnamebuf, sizeof(xnamebuf), "%s TXRX%d",
   5400       1.1  yamaguch 		    device_xname(sc->sc_dev), i);
   5401       1.1  yamaguch 
   5402       1.1  yamaguch 		sc->sc_ihs[vector] = pci_intr_establish_xname(pc,
   5403       1.1  yamaguch 		    sc->sc_ihp[vector], IPL_NET, ixl_queue_intr,
   5404       1.1  yamaguch 		    (void *)&sc->sc_qps[i], xnamebuf);
   5405       1.1  yamaguch 
   5406       1.1  yamaguch 		if (sc->sc_ihs[vector] == NULL) {
   5407       1.1  yamaguch 			aprint_error_dev(sc->sc_dev,
   5408       1.1  yamaguch 			    "unable to establish interrupt at %s\n", intrstr);
   5409       1.1  yamaguch 			goto fail;
   5410       1.1  yamaguch 		}
   5411  1.16.2.1        ad 
   5412       1.1  yamaguch 		aprint_normal_dev(sc->sc_dev,
   5413  1.16.2.1        ad 		    "for TXRX%d interrupt at %s",i , intrstr);
   5414  1.16.2.1        ad 
   5415  1.16.2.1        ad 		kcpuset_zero(affinity);
   5416  1.16.2.1        ad 		kcpuset_set(affinity, affinity_to);
   5417  1.16.2.1        ad 		r = interrupt_distribute(sc->sc_ihs[vector], affinity, NULL);
   5418  1.16.2.1        ad 		if (r == 0) {
   5419  1.16.2.1        ad 			aprint_normal(", affinity to %u", affinity_to);
   5420  1.16.2.1        ad 			affinity_to = (affinity_to + 1) % ncpu;
   5421  1.16.2.1        ad 		}
   5422  1.16.2.1        ad 		aprint_normal("\n");
   5423  1.16.2.1        ad 		vector++;
   5424       1.1  yamaguch 	}
   5425       1.1  yamaguch 
   5426  1.16.2.1        ad 	kcpuset_destroy(affinity);
   5427  1.16.2.1        ad 
   5428       1.1  yamaguch 	return 0;
   5429       1.1  yamaguch fail:
   5430       1.1  yamaguch 	for (i = 0; i < vector; i++) {
   5431       1.1  yamaguch 		pci_intr_disestablish(pc, sc->sc_ihs[i]);
   5432       1.1  yamaguch 	}
   5433       1.1  yamaguch 
   5434       1.1  yamaguch 	sc->sc_msix_vector_queue = 0;
   5435       1.1  yamaguch 	sc->sc_msix_vector_queue = 0;
   5436  1.16.2.1        ad 	kcpuset_destroy(affinity);
   5437       1.1  yamaguch 
   5438       1.1  yamaguch 	return -1;
   5439       1.1  yamaguch }
   5440       1.1  yamaguch 
   5441       1.1  yamaguch static void
   5442       1.1  yamaguch ixl_config_queue_intr(struct ixl_softc *sc)
   5443       1.1  yamaguch {
   5444       1.1  yamaguch 	unsigned int i, vector;
   5445       1.1  yamaguch 
   5446       1.1  yamaguch 	if (sc->sc_intrtype == PCI_INTR_TYPE_MSIX) {
   5447       1.1  yamaguch 		vector = sc->sc_msix_vector_queue;
   5448       1.1  yamaguch 	} else {
   5449       1.1  yamaguch 		vector = I40E_INTR_NOTX_INTR;
   5450       1.1  yamaguch 
   5451       1.1  yamaguch 		ixl_wr(sc, I40E_PFINT_LNKLST0,
   5452       1.1  yamaguch 		    (I40E_INTR_NOTX_QUEUE <<
   5453       1.1  yamaguch 		     I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT) |
   5454       1.1  yamaguch 		    (I40E_QUEUE_TYPE_RX <<
   5455       1.1  yamaguch 		     I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT));
   5456       1.1  yamaguch 	}
   5457       1.1  yamaguch 
   5458       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs; i++) {
   5459       1.1  yamaguch 		ixl_wr(sc, I40E_PFINT_DYN_CTLN(i), 0);
   5460       1.1  yamaguch 		ixl_flush(sc);
   5461       1.1  yamaguch 
   5462       1.1  yamaguch 		ixl_wr(sc, I40E_PFINT_LNKLSTN(i),
   5463       1.1  yamaguch 		    ((i) << I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT) |
   5464       1.1  yamaguch 		    (I40E_QUEUE_TYPE_RX <<
   5465       1.1  yamaguch 		     I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT));
   5466       1.1  yamaguch 
   5467       1.1  yamaguch 		ixl_wr(sc, I40E_QINT_RQCTL(i),
   5468       1.1  yamaguch 		    (vector << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) |
   5469       1.1  yamaguch 		    (I40E_ITR_INDEX_RX <<
   5470       1.1  yamaguch 		     I40E_QINT_RQCTL_ITR_INDX_SHIFT) |
   5471       1.1  yamaguch 		    (I40E_INTR_NOTX_RX_QUEUE <<
   5472       1.1  yamaguch 		     I40E_QINT_RQCTL_MSIX0_INDX_SHIFT) |
   5473       1.1  yamaguch 		    (i << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) |
   5474       1.1  yamaguch 		    (I40E_QUEUE_TYPE_TX <<
   5475       1.1  yamaguch 		     I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) |
   5476       1.1  yamaguch 		    I40E_QINT_RQCTL_CAUSE_ENA_MASK);
   5477       1.1  yamaguch 
   5478       1.1  yamaguch 		ixl_wr(sc, I40E_QINT_TQCTL(i),
   5479       1.1  yamaguch 		    (vector << I40E_QINT_TQCTL_MSIX_INDX_SHIFT) |
   5480       1.1  yamaguch 		    (I40E_ITR_INDEX_TX <<
   5481       1.1  yamaguch 		     I40E_QINT_TQCTL_ITR_INDX_SHIFT) |
   5482       1.1  yamaguch 		    (I40E_INTR_NOTX_TX_QUEUE <<
   5483       1.1  yamaguch 		     I40E_QINT_TQCTL_MSIX0_INDX_SHIFT) |
   5484       1.1  yamaguch 		    (I40E_QUEUE_TYPE_EOL <<
   5485       1.1  yamaguch 		     I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT) |
   5486       1.1  yamaguch 		    (I40E_QUEUE_TYPE_RX <<
   5487       1.1  yamaguch 		     I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT) |
   5488       1.1  yamaguch 		     I40E_QINT_TQCTL_CAUSE_ENA_MASK);
   5489       1.1  yamaguch 
   5490       1.1  yamaguch 		if (sc->sc_intrtype == PCI_INTR_TYPE_MSIX)
   5491       1.1  yamaguch 			vector++;
   5492       1.1  yamaguch 	}
   5493       1.1  yamaguch 	ixl_flush(sc);
   5494       1.1  yamaguch 
   5495       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_RX), 0x7a);
   5496       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_TX), 0x7a);
   5497       1.1  yamaguch 	ixl_flush(sc);
   5498       1.1  yamaguch }
   5499       1.1  yamaguch 
   5500       1.1  yamaguch static void
   5501       1.1  yamaguch ixl_config_other_intr(struct ixl_softc *sc)
   5502       1.1  yamaguch {
   5503       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ICR0_ENA, 0);
   5504       1.1  yamaguch 	(void)ixl_rd(sc, I40E_PFINT_ICR0);
   5505       1.1  yamaguch 
   5506       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ICR0_ENA,
   5507       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_ECC_ERR_MASK |
   5508       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_GRST_MASK |
   5509       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_ADMINQ_MASK |
   5510       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK |
   5511       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_HMC_ERR_MASK |
   5512       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_VFLR_MASK |
   5513       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK |
   5514       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK |
   5515       1.1  yamaguch 	    I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK);
   5516       1.1  yamaguch 
   5517       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_LNKLST0, 0x7FF);
   5518       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_OTHER), 0);
   5519       1.1  yamaguch 	ixl_wr(sc, I40E_PFINT_STAT_CTL0,
   5520       1.1  yamaguch 	    (I40E_ITR_INDEX_OTHER <<
   5521       1.1  yamaguch 	     I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT));
   5522       1.1  yamaguch 	ixl_flush(sc);
   5523       1.1  yamaguch }
   5524       1.1  yamaguch 
   5525       1.1  yamaguch static int
   5526       1.1  yamaguch ixl_setup_interrupts(struct ixl_softc *sc)
   5527       1.1  yamaguch {
   5528       1.1  yamaguch 	struct pci_attach_args *pa = &sc->sc_pa;
   5529       1.1  yamaguch 	pci_intr_type_t max_type, intr_type;
   5530       1.1  yamaguch 	int counts[PCI_INTR_TYPE_SIZE];
   5531       1.1  yamaguch 	int error;
   5532       1.1  yamaguch 	unsigned int i;
   5533  1.16.2.1        ad 	bool retry;
   5534       1.1  yamaguch 
   5535       1.1  yamaguch 	memset(counts, 0, sizeof(counts));
   5536       1.1  yamaguch 	max_type = PCI_INTR_TYPE_MSIX;
   5537       1.1  yamaguch 	/* QPs + other interrupt */
   5538       1.1  yamaguch 	counts[PCI_INTR_TYPE_MSIX] = sc->sc_nqueue_pairs_max + 1;
   5539       1.1  yamaguch 	counts[PCI_INTR_TYPE_INTX] = 1;
   5540       1.1  yamaguch 
   5541  1.16.2.1        ad 	if (ixl_param_nomsix)
   5542       1.1  yamaguch 		counts[PCI_INTR_TYPE_MSIX] = 0;
   5543       1.1  yamaguch 
   5544       1.1  yamaguch 	do {
   5545       1.1  yamaguch 		retry = false;
   5546       1.1  yamaguch 		error = pci_intr_alloc(pa, &sc->sc_ihp, counts, max_type);
   5547       1.1  yamaguch 		if (error != 0) {
   5548       1.1  yamaguch 			aprint_error_dev(sc->sc_dev,
   5549       1.1  yamaguch 			    "couldn't map interrupt\n");
   5550       1.1  yamaguch 			break;
   5551       1.1  yamaguch 		}
   5552       1.1  yamaguch 		for (i = 0; i < sc->sc_nintrs; i++) {
   5553       1.1  yamaguch 			pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[i],
   5554       1.1  yamaguch 			    PCI_INTR_MPSAFE, true);
   5555       1.1  yamaguch 		}
   5556       1.1  yamaguch 
   5557       1.1  yamaguch 		intr_type = pci_intr_type(pa->pa_pc, sc->sc_ihp[0]);
   5558       1.1  yamaguch 		sc->sc_nintrs = counts[intr_type];
   5559       1.1  yamaguch 		KASSERT(sc->sc_nintrs > 0);
   5560       1.1  yamaguch 
   5561       1.1  yamaguch 		sc->sc_ihs = kmem_alloc(sizeof(sc->sc_ihs[0]) * sc->sc_nintrs,
   5562       1.1  yamaguch 		    KM_SLEEP);
   5563       1.1  yamaguch 
   5564       1.1  yamaguch 		if (intr_type == PCI_INTR_TYPE_MSIX) {
   5565       1.1  yamaguch 			error = ixl_establish_msix(sc);
   5566       1.1  yamaguch 			if (error) {
   5567       1.1  yamaguch 				counts[PCI_INTR_TYPE_MSIX] = 0;
   5568       1.1  yamaguch 				retry = true;
   5569       1.1  yamaguch 			}
   5570       1.1  yamaguch 		} else if (intr_type == PCI_INTR_TYPE_INTX) {
   5571       1.1  yamaguch 			error = ixl_establish_intx(sc);
   5572       1.1  yamaguch 		} else {
   5573       1.1  yamaguch 			error = -1;
   5574       1.1  yamaguch 		}
   5575       1.1  yamaguch 
   5576       1.1  yamaguch 		if (error) {
   5577       1.1  yamaguch 			kmem_free(sc->sc_ihs,
   5578       1.1  yamaguch 			    sizeof(sc->sc_ihs[0]) * sc->sc_nintrs);
   5579       1.1  yamaguch 			pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs);
   5580       1.1  yamaguch 		} else {
   5581       1.1  yamaguch 			sc->sc_intrtype = intr_type;
   5582       1.1  yamaguch 		}
   5583       1.1  yamaguch 	} while (retry);
   5584       1.1  yamaguch 
   5585       1.1  yamaguch 	return error;
   5586       1.1  yamaguch }
   5587       1.1  yamaguch 
   5588       1.1  yamaguch static void
   5589       1.1  yamaguch ixl_teardown_interrupts(struct ixl_softc *sc)
   5590       1.1  yamaguch {
   5591       1.1  yamaguch 	struct pci_attach_args *pa = &sc->sc_pa;
   5592       1.1  yamaguch 	unsigned int i;
   5593       1.1  yamaguch 
   5594       1.1  yamaguch 	for (i = 0; i < sc->sc_nintrs; i++) {
   5595       1.1  yamaguch 		pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[i]);
   5596       1.1  yamaguch 	}
   5597       1.1  yamaguch 
   5598       1.1  yamaguch 	pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs);
   5599       1.1  yamaguch 
   5600       1.1  yamaguch 	kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * sc->sc_nintrs);
   5601       1.1  yamaguch 	sc->sc_ihs = NULL;
   5602       1.1  yamaguch 	sc->sc_nintrs = 0;
   5603       1.1  yamaguch }
   5604       1.1  yamaguch 
   5605       1.1  yamaguch static int
   5606       1.1  yamaguch ixl_setup_stats(struct ixl_softc *sc)
   5607       1.1  yamaguch {
   5608       1.1  yamaguch 	struct ixl_queue_pair *qp;
   5609       1.1  yamaguch 	struct ixl_tx_ring *txr;
   5610       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   5611  1.16.2.1        ad 	struct ixl_stats_counters *isc;
   5612       1.1  yamaguch 	unsigned int i;
   5613       1.1  yamaguch 
   5614       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   5615       1.1  yamaguch 		qp = &sc->sc_qps[i];
   5616       1.1  yamaguch 		txr = qp->qp_txr;
   5617       1.1  yamaguch 		rxr = qp->qp_rxr;
   5618       1.1  yamaguch 
   5619       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_defragged, EVCNT_TYPE_MISC,
   5620       1.1  yamaguch 		    NULL, qp->qp_name, "m_defrag successed");
   5621       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_defrag_failed, EVCNT_TYPE_MISC,
   5622       1.1  yamaguch 		    NULL, qp->qp_name, "m_defrag_failed");
   5623       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_pcqdrop, EVCNT_TYPE_MISC,
   5624       1.1  yamaguch 		    NULL, qp->qp_name, "Dropped in pcq");
   5625       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_transmitdef, EVCNT_TYPE_MISC,
   5626       1.1  yamaguch 		    NULL, qp->qp_name, "Deferred transmit");
   5627       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_intr, EVCNT_TYPE_INTR,
   5628       1.1  yamaguch 		    NULL, qp->qp_name, "Interrupt on queue");
   5629       1.1  yamaguch 		evcnt_attach_dynamic(&txr->txr_defer, EVCNT_TYPE_MISC,
   5630       1.1  yamaguch 		    NULL, qp->qp_name, "Handled queue in softint/workqueue");
   5631       1.1  yamaguch 
   5632       1.1  yamaguch 		evcnt_attach_dynamic(&rxr->rxr_mgethdr_failed, EVCNT_TYPE_MISC,
   5633       1.1  yamaguch 		    NULL, qp->qp_name, "MGETHDR failed");
   5634       1.1  yamaguch 		evcnt_attach_dynamic(&rxr->rxr_mgetcl_failed, EVCNT_TYPE_MISC,
   5635       1.1  yamaguch 		    NULL, qp->qp_name, "MCLGET failed");
   5636       1.1  yamaguch 		evcnt_attach_dynamic(&rxr->rxr_mbuf_load_failed,
   5637       1.1  yamaguch 		    EVCNT_TYPE_MISC, NULL, qp->qp_name,
   5638       1.1  yamaguch 		    "bus_dmamap_load_mbuf failed");
   5639       1.1  yamaguch 		evcnt_attach_dynamic(&rxr->rxr_intr, EVCNT_TYPE_INTR,
   5640       1.1  yamaguch 		    NULL, qp->qp_name, "Interrupt on queue");
   5641       1.1  yamaguch 		evcnt_attach_dynamic(&rxr->rxr_defer, EVCNT_TYPE_MISC,
   5642       1.1  yamaguch 		    NULL, qp->qp_name, "Handled queue in softint/workqueue");
   5643       1.1  yamaguch 	}
   5644       1.1  yamaguch 
   5645       1.1  yamaguch 	evcnt_attach_dynamic(&sc->sc_event_atq, EVCNT_TYPE_INTR,
   5646       1.1  yamaguch 	    NULL, device_xname(sc->sc_dev), "Interrupt for other events");
   5647       1.1  yamaguch 	evcnt_attach_dynamic(&sc->sc_event_link, EVCNT_TYPE_MISC,
   5648       1.1  yamaguch 	    NULL, device_xname(sc->sc_dev), "Link status event");
   5649       1.1  yamaguch 	evcnt_attach_dynamic(&sc->sc_event_ecc_err, EVCNT_TYPE_MISC,
   5650       1.1  yamaguch 	    NULL, device_xname(sc->sc_dev), "ECC error");
   5651       1.1  yamaguch 	evcnt_attach_dynamic(&sc->sc_event_pci_exception, EVCNT_TYPE_MISC,
   5652       1.1  yamaguch 	    NULL, device_xname(sc->sc_dev), "PCI exception");
   5653       1.1  yamaguch 	evcnt_attach_dynamic(&sc->sc_event_crit_err, EVCNT_TYPE_MISC,
   5654       1.1  yamaguch 	    NULL, device_xname(sc->sc_dev), "Critical error");
   5655       1.1  yamaguch 
   5656  1.16.2.1        ad 	isc = &sc->sc_stats_counters;
   5657  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_crc_errors, EVCNT_TYPE_MISC,
   5658  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "CRC errors");
   5659  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_illegal_bytes, EVCNT_TYPE_MISC,
   5660  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Illegal bytes");
   5661  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_mac_local_faults, EVCNT_TYPE_MISC,
   5662  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Mac local faults");
   5663  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_mac_remote_faults, EVCNT_TYPE_MISC,
   5664  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Mac remote faults");
   5665  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_link_xon_rx, EVCNT_TYPE_MISC,
   5666  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx xon");
   5667  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_link_xon_tx, EVCNT_TYPE_MISC,
   5668  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx xon");
   5669  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_link_xoff_rx, EVCNT_TYPE_MISC,
   5670  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx xoff");
   5671  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_link_xoff_tx, EVCNT_TYPE_MISC,
   5672  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx xoff");
   5673  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_fragments, EVCNT_TYPE_MISC,
   5674  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx fragments");
   5675  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_jabber, EVCNT_TYPE_MISC,
   5676  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx jabber");
   5677  1.16.2.1        ad 
   5678  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_64, EVCNT_TYPE_MISC,
   5679  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 64");
   5680  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_127, EVCNT_TYPE_MISC,
   5681  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 127");
   5682  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_255, EVCNT_TYPE_MISC,
   5683  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 255");
   5684  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_511, EVCNT_TYPE_MISC,
   5685  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 511");
   5686  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_1023, EVCNT_TYPE_MISC,
   5687  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 1023");
   5688  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_1522, EVCNT_TYPE_MISC,
   5689  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx size 1522");
   5690  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_size_big, EVCNT_TYPE_MISC,
   5691  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx jumbo packets");
   5692  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_undersize, EVCNT_TYPE_MISC,
   5693  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx under size");
   5694  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_oversize, EVCNT_TYPE_MISC,
   5695  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx over size");
   5696  1.16.2.1        ad 
   5697  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_bytes, EVCNT_TYPE_MISC,
   5698  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx bytes / port");
   5699  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_discards, EVCNT_TYPE_MISC,
   5700  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx discards / port");
   5701  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_unicast, EVCNT_TYPE_MISC,
   5702  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx unicast / port");
   5703  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_multicast, EVCNT_TYPE_MISC,
   5704  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx multicast / port");
   5705  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_rx_broadcast, EVCNT_TYPE_MISC,
   5706  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx broadcast / port");
   5707  1.16.2.1        ad 
   5708  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_rx_bytes, EVCNT_TYPE_MISC,
   5709  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx bytes / vsi");
   5710  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_rx_discards, EVCNT_TYPE_MISC,
   5711  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx discard / vsi");
   5712  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_rx_unicast, EVCNT_TYPE_MISC,
   5713  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx unicast / vsi");
   5714  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_rx_multicast, EVCNT_TYPE_MISC,
   5715  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx multicast / vsi");
   5716  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_rx_broadcast, EVCNT_TYPE_MISC,
   5717  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Rx broadcast / vsi");
   5718  1.16.2.1        ad 
   5719  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_64, EVCNT_TYPE_MISC,
   5720  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 64");
   5721  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_127, EVCNT_TYPE_MISC,
   5722  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 127");
   5723  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_255, EVCNT_TYPE_MISC,
   5724  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 255");
   5725  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_511, EVCNT_TYPE_MISC,
   5726  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 511");
   5727  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_1023, EVCNT_TYPE_MISC,
   5728  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 1023");
   5729  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_1522, EVCNT_TYPE_MISC,
   5730  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx size 1522");
   5731  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_size_big, EVCNT_TYPE_MISC,
   5732  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx jumbo packets");
   5733  1.16.2.1        ad 
   5734  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_bytes, EVCNT_TYPE_MISC,
   5735  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx bytes / port");
   5736  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_dropped_link_down, EVCNT_TYPE_MISC,
   5737  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev),
   5738  1.16.2.1        ad 	    "Tx dropped due to link down / port");
   5739  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_unicast, EVCNT_TYPE_MISC,
   5740  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx unicast / port");
   5741  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_multicast, EVCNT_TYPE_MISC,
   5742  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx multicast / port");
   5743  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_tx_broadcast, EVCNT_TYPE_MISC,
   5744  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx broadcast / port");
   5745  1.16.2.1        ad 
   5746  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_tx_bytes, EVCNT_TYPE_MISC,
   5747  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx bytes / vsi");
   5748  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_tx_errors, EVCNT_TYPE_MISC,
   5749  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx errors / vsi");
   5750  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_tx_unicast, EVCNT_TYPE_MISC,
   5751  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx unicast / vsi");
   5752  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_tx_multicast, EVCNT_TYPE_MISC,
   5753  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx multicast / vsi");
   5754  1.16.2.1        ad 	evcnt_attach_dynamic(&isc->isc_vsi_tx_broadcast, EVCNT_TYPE_MISC,
   5755  1.16.2.1        ad 	    NULL, device_xname(sc->sc_dev), "Tx broadcast / vsi");
   5756  1.16.2.1        ad 
   5757  1.16.2.1        ad 	sc->sc_stats_intval = ixl_param_stats_interval;
   5758  1.16.2.1        ad 	callout_init(&sc->sc_stats_callout, CALLOUT_MPSAFE);
   5759  1.16.2.1        ad 	callout_setfunc(&sc->sc_stats_callout, ixl_stats_callout, sc);
   5760  1.16.2.1        ad 	ixl_work_set(&sc->sc_stats_task, ixl_stats_update, sc);
   5761  1.16.2.1        ad 
   5762       1.1  yamaguch 	return 0;
   5763       1.1  yamaguch }
   5764       1.1  yamaguch 
   5765       1.1  yamaguch static void
   5766       1.1  yamaguch ixl_teardown_stats(struct ixl_softc *sc)
   5767       1.1  yamaguch {
   5768       1.1  yamaguch 	struct ixl_tx_ring *txr;
   5769       1.1  yamaguch 	struct ixl_rx_ring *rxr;
   5770  1.16.2.1        ad 	struct ixl_stats_counters *isc;
   5771       1.1  yamaguch 	unsigned int i;
   5772       1.1  yamaguch 
   5773       1.1  yamaguch 	for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
   5774       1.1  yamaguch 		txr = sc->sc_qps[i].qp_txr;
   5775       1.1  yamaguch 		rxr = sc->sc_qps[i].qp_rxr;
   5776       1.1  yamaguch 
   5777       1.1  yamaguch 		evcnt_detach(&txr->txr_defragged);
   5778       1.1  yamaguch 		evcnt_detach(&txr->txr_defrag_failed);
   5779       1.1  yamaguch 		evcnt_detach(&txr->txr_pcqdrop);
   5780       1.1  yamaguch 		evcnt_detach(&txr->txr_transmitdef);
   5781       1.1  yamaguch 		evcnt_detach(&txr->txr_intr);
   5782       1.1  yamaguch 		evcnt_detach(&txr->txr_defer);
   5783       1.1  yamaguch 
   5784       1.1  yamaguch 		evcnt_detach(&rxr->rxr_mgethdr_failed);
   5785       1.1  yamaguch 		evcnt_detach(&rxr->rxr_mgetcl_failed);
   5786       1.1  yamaguch 		evcnt_detach(&rxr->rxr_mbuf_load_failed);
   5787       1.1  yamaguch 		evcnt_detach(&rxr->rxr_intr);
   5788       1.1  yamaguch 		evcnt_detach(&rxr->rxr_defer);
   5789       1.1  yamaguch 	}
   5790       1.1  yamaguch 
   5791  1.16.2.1        ad 	isc = &sc->sc_stats_counters;
   5792  1.16.2.1        ad 	evcnt_detach(&isc->isc_crc_errors);
   5793  1.16.2.1        ad 	evcnt_detach(&isc->isc_illegal_bytes);
   5794  1.16.2.1        ad 	evcnt_detach(&isc->isc_mac_local_faults);
   5795  1.16.2.1        ad 	evcnt_detach(&isc->isc_mac_remote_faults);
   5796  1.16.2.1        ad 	evcnt_detach(&isc->isc_link_xon_rx);
   5797  1.16.2.1        ad 	evcnt_detach(&isc->isc_link_xon_tx);
   5798  1.16.2.1        ad 	evcnt_detach(&isc->isc_link_xoff_rx);
   5799  1.16.2.1        ad 	evcnt_detach(&isc->isc_link_xoff_tx);
   5800  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_fragments);
   5801  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_jabber);
   5802  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_bytes);
   5803  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_discards);
   5804  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_unicast);
   5805  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_multicast);
   5806  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_broadcast);
   5807  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_64);
   5808  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_127);
   5809  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_255);
   5810  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_511);
   5811  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_1023);
   5812  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_1522);
   5813  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_size_big);
   5814  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_undersize);
   5815  1.16.2.1        ad 	evcnt_detach(&isc->isc_rx_oversize);
   5816  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_bytes);
   5817  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_dropped_link_down);
   5818  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_unicast);
   5819  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_multicast);
   5820  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_broadcast);
   5821  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_64);
   5822  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_127);
   5823  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_255);
   5824  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_511);
   5825  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_1023);
   5826  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_1522);
   5827  1.16.2.1        ad 	evcnt_detach(&isc->isc_tx_size_big);
   5828  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_rx_discards);
   5829  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_rx_bytes);
   5830  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_rx_unicast);
   5831  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_rx_multicast);
   5832  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_rx_broadcast);
   5833  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_tx_errors);
   5834  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_tx_bytes);
   5835  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_tx_unicast);
   5836  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_tx_multicast);
   5837  1.16.2.1        ad 	evcnt_detach(&isc->isc_vsi_tx_broadcast);
   5838  1.16.2.1        ad 
   5839       1.1  yamaguch 	evcnt_detach(&sc->sc_event_atq);
   5840       1.1  yamaguch 	evcnt_detach(&sc->sc_event_link);
   5841       1.1  yamaguch 	evcnt_detach(&sc->sc_event_ecc_err);
   5842       1.1  yamaguch 	evcnt_detach(&sc->sc_event_pci_exception);
   5843       1.1  yamaguch 	evcnt_detach(&sc->sc_event_crit_err);
   5844  1.16.2.1        ad 
   5845  1.16.2.1        ad 	callout_destroy(&sc->sc_stats_callout);
   5846  1.16.2.1        ad }
   5847  1.16.2.1        ad 
   5848  1.16.2.1        ad static void
   5849  1.16.2.1        ad ixl_stats_callout(void *xsc)
   5850  1.16.2.1        ad {
   5851  1.16.2.1        ad 	struct ixl_softc *sc = xsc;
   5852  1.16.2.1        ad 
   5853  1.16.2.1        ad 	ixl_work_add(sc->sc_workq, &sc->sc_stats_task);
   5854  1.16.2.1        ad 	callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval));
   5855  1.16.2.1        ad }
   5856  1.16.2.1        ad 
   5857  1.16.2.1        ad static uint64_t
   5858  1.16.2.1        ad ixl_stat_delta(struct ixl_softc *sc, uint32_t reg_hi, uint32_t reg_lo,
   5859  1.16.2.1        ad     uint64_t *offset, bool has_offset)
   5860  1.16.2.1        ad {
   5861  1.16.2.1        ad 	uint64_t value, delta;
   5862  1.16.2.1        ad 	int bitwidth;
   5863  1.16.2.1        ad 
   5864  1.16.2.1        ad 	bitwidth = reg_hi == 0 ? 32 : 48;
   5865  1.16.2.1        ad 
   5866  1.16.2.1        ad 	value = ixl_rd(sc, reg_lo);
   5867  1.16.2.1        ad 
   5868  1.16.2.1        ad 	if (bitwidth > 32) {
   5869  1.16.2.1        ad 		value |= ((uint64_t)ixl_rd(sc, reg_hi) << 32);
   5870  1.16.2.1        ad 	}
   5871  1.16.2.1        ad 
   5872  1.16.2.1        ad 	if (__predict_true(has_offset)) {
   5873  1.16.2.1        ad 		delta = value;
   5874  1.16.2.1        ad 		if (value < *offset)
   5875  1.16.2.1        ad 			delta += ((uint64_t)1 << bitwidth);
   5876  1.16.2.1        ad 		delta -= *offset;
   5877  1.16.2.1        ad 	} else {
   5878  1.16.2.1        ad 		delta = 0;
   5879  1.16.2.1        ad 	}
   5880  1.16.2.1        ad 	atomic_swap_64(offset, value);
   5881  1.16.2.1        ad 
   5882  1.16.2.1        ad 	return delta;
   5883  1.16.2.1        ad }
   5884  1.16.2.1        ad 
   5885  1.16.2.1        ad static void
   5886  1.16.2.1        ad ixl_stats_update(void *xsc)
   5887  1.16.2.1        ad {
   5888  1.16.2.1        ad 	struct ixl_softc *sc = xsc;
   5889  1.16.2.1        ad 	struct ixl_stats_counters *isc;
   5890  1.16.2.1        ad 	uint64_t delta;
   5891  1.16.2.1        ad 
   5892  1.16.2.1        ad 	isc = &sc->sc_stats_counters;
   5893  1.16.2.1        ad 
   5894  1.16.2.1        ad 	/* errors */
   5895  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5896  1.16.2.1        ad 	    0, I40E_GLPRT_CRCERRS(sc->sc_port),
   5897  1.16.2.1        ad 	    &isc->isc_crc_errors_offset, isc->isc_has_offset);
   5898  1.16.2.1        ad 	atomic_add_64(&isc->isc_crc_errors.ev_count, delta);
   5899  1.16.2.1        ad 
   5900  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5901  1.16.2.1        ad 	    0, I40E_GLPRT_ILLERRC(sc->sc_port),
   5902  1.16.2.1        ad 	    &isc->isc_illegal_bytes_offset, isc->isc_has_offset);
   5903  1.16.2.1        ad 	atomic_add_64(&isc->isc_illegal_bytes.ev_count, delta);
   5904  1.16.2.1        ad 
   5905  1.16.2.1        ad 	/* rx */
   5906  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5907  1.16.2.1        ad 	    I40E_GLPRT_GORCH(sc->sc_port), I40E_GLPRT_GORCL(sc->sc_port),
   5908  1.16.2.1        ad 	    &isc->isc_rx_bytes_offset, isc->isc_has_offset);
   5909  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_bytes.ev_count, delta);
   5910  1.16.2.1        ad 
   5911  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5912  1.16.2.1        ad 	    0, I40E_GLPRT_RDPC(sc->sc_port),
   5913  1.16.2.1        ad 	    &isc->isc_rx_discards_offset, isc->isc_has_offset);
   5914  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_discards.ev_count, delta);
   5915  1.16.2.1        ad 
   5916  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5917  1.16.2.1        ad 	    I40E_GLPRT_UPRCH(sc->sc_port), I40E_GLPRT_UPRCL(sc->sc_port),
   5918  1.16.2.1        ad 	    &isc->isc_rx_unicast_offset, isc->isc_has_offset);
   5919  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_unicast.ev_count, delta);
   5920  1.16.2.1        ad 
   5921  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5922  1.16.2.1        ad 	    I40E_GLPRT_MPRCH(sc->sc_port), I40E_GLPRT_MPRCL(sc->sc_port),
   5923  1.16.2.1        ad 	    &isc->isc_rx_multicast_offset, isc->isc_has_offset);
   5924  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_multicast.ev_count, delta);
   5925  1.16.2.1        ad 
   5926  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5927  1.16.2.1        ad 	    I40E_GLPRT_BPRCH(sc->sc_port), I40E_GLPRT_BPRCL(sc->sc_port),
   5928  1.16.2.1        ad 	    &isc->isc_rx_broadcast_offset, isc->isc_has_offset);
   5929  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_broadcast.ev_count, delta);
   5930  1.16.2.1        ad 
   5931  1.16.2.1        ad 	/* Packet size stats rx */
   5932  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5933  1.16.2.1        ad 	    I40E_GLPRT_PRC64H(sc->sc_port), I40E_GLPRT_PRC64L(sc->sc_port),
   5934  1.16.2.1        ad 	    &isc->isc_rx_size_64_offset, isc->isc_has_offset);
   5935  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_64.ev_count, delta);
   5936  1.16.2.1        ad 
   5937  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5938  1.16.2.1        ad 	    I40E_GLPRT_PRC127H(sc->sc_port), I40E_GLPRT_PRC127L(sc->sc_port),
   5939  1.16.2.1        ad 	    &isc->isc_rx_size_127_offset, isc->isc_has_offset);
   5940  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_127.ev_count, delta);
   5941  1.16.2.1        ad 
   5942  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5943  1.16.2.1        ad 	    I40E_GLPRT_PRC255H(sc->sc_port), I40E_GLPRT_PRC255L(sc->sc_port),
   5944  1.16.2.1        ad 	    &isc->isc_rx_size_255_offset, isc->isc_has_offset);
   5945  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_255.ev_count, delta);
   5946  1.16.2.1        ad 
   5947  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5948  1.16.2.1        ad 	    I40E_GLPRT_PRC511H(sc->sc_port), I40E_GLPRT_PRC511L(sc->sc_port),
   5949  1.16.2.1        ad 	    &isc->isc_rx_size_511_offset, isc->isc_has_offset);
   5950  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_511.ev_count, delta);
   5951  1.16.2.1        ad 
   5952  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5953  1.16.2.1        ad 	    I40E_GLPRT_PRC1023H(sc->sc_port), I40E_GLPRT_PRC1023L(sc->sc_port),
   5954  1.16.2.1        ad 	    &isc->isc_rx_size_1023_offset, isc->isc_has_offset);
   5955  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_1023.ev_count, delta);
   5956  1.16.2.1        ad 
   5957  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5958  1.16.2.1        ad 	    I40E_GLPRT_PRC1522H(sc->sc_port), I40E_GLPRT_PRC1522L(sc->sc_port),
   5959  1.16.2.1        ad 	    &isc->isc_rx_size_1522_offset, isc->isc_has_offset);
   5960  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_1522.ev_count, delta);
   5961  1.16.2.1        ad 
   5962  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5963  1.16.2.1        ad 	    I40E_GLPRT_PRC9522H(sc->sc_port), I40E_GLPRT_PRC9522L(sc->sc_port),
   5964  1.16.2.1        ad 	    &isc->isc_rx_size_big_offset, isc->isc_has_offset);
   5965  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_size_big.ev_count, delta);
   5966  1.16.2.1        ad 
   5967  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5968  1.16.2.1        ad 	    0, I40E_GLPRT_RUC(sc->sc_port),
   5969  1.16.2.1        ad 	    &isc->isc_rx_undersize_offset, isc->isc_has_offset);
   5970  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_undersize.ev_count, delta);
   5971  1.16.2.1        ad 
   5972  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5973  1.16.2.1        ad 	    0, I40E_GLPRT_ROC(sc->sc_port),
   5974  1.16.2.1        ad 	    &isc->isc_rx_oversize_offset, isc->isc_has_offset);
   5975  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_oversize.ev_count, delta);
   5976  1.16.2.1        ad 
   5977  1.16.2.1        ad 	/* tx */
   5978  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5979  1.16.2.1        ad 	    I40E_GLPRT_GOTCH(sc->sc_port), I40E_GLPRT_GOTCL(sc->sc_port),
   5980  1.16.2.1        ad 	    &isc->isc_tx_bytes_offset, isc->isc_has_offset);
   5981  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_bytes.ev_count, delta);
   5982  1.16.2.1        ad 
   5983  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5984  1.16.2.1        ad 	    0, I40E_GLPRT_TDOLD(sc->sc_port),
   5985  1.16.2.1        ad 	    &isc->isc_tx_dropped_link_down_offset, isc->isc_has_offset);
   5986  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_dropped_link_down.ev_count, delta);
   5987  1.16.2.1        ad 
   5988  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5989  1.16.2.1        ad 	    I40E_GLPRT_UPTCH(sc->sc_port), I40E_GLPRT_UPTCL(sc->sc_port),
   5990  1.16.2.1        ad 	    &isc->isc_tx_unicast_offset, isc->isc_has_offset);
   5991  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_unicast.ev_count, delta);
   5992  1.16.2.1        ad 
   5993  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5994  1.16.2.1        ad 	    I40E_GLPRT_MPTCH(sc->sc_port), I40E_GLPRT_MPTCL(sc->sc_port),
   5995  1.16.2.1        ad 	    &isc->isc_tx_multicast_offset, isc->isc_has_offset);
   5996  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_multicast.ev_count, delta);
   5997  1.16.2.1        ad 
   5998  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   5999  1.16.2.1        ad 	    I40E_GLPRT_BPTCH(sc->sc_port), I40E_GLPRT_BPTCL(sc->sc_port),
   6000  1.16.2.1        ad 	    &isc->isc_tx_broadcast_offset, isc->isc_has_offset);
   6001  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_broadcast.ev_count, delta);
   6002  1.16.2.1        ad 
   6003  1.16.2.1        ad 	/* Packet size stats tx */
   6004  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6005  1.16.2.1        ad 	    I40E_GLPRT_PTC64L(sc->sc_port), I40E_GLPRT_PTC64L(sc->sc_port),
   6006  1.16.2.1        ad 	    &isc->isc_tx_size_64_offset, isc->isc_has_offset);
   6007  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_64.ev_count, delta);
   6008  1.16.2.1        ad 
   6009  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6010  1.16.2.1        ad 	    I40E_GLPRT_PTC127H(sc->sc_port), I40E_GLPRT_PTC127L(sc->sc_port),
   6011  1.16.2.1        ad 	    &isc->isc_tx_size_127_offset, isc->isc_has_offset);
   6012  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_127.ev_count, delta);
   6013  1.16.2.1        ad 
   6014  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6015  1.16.2.1        ad 	    I40E_GLPRT_PTC255H(sc->sc_port), I40E_GLPRT_PTC255L(sc->sc_port),
   6016  1.16.2.1        ad 	    &isc->isc_tx_size_255_offset, isc->isc_has_offset);
   6017  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_255.ev_count, delta);
   6018  1.16.2.1        ad 
   6019  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6020  1.16.2.1        ad 	    I40E_GLPRT_PTC511H(sc->sc_port), I40E_GLPRT_PTC511L(sc->sc_port),
   6021  1.16.2.1        ad 	    &isc->isc_tx_size_511_offset, isc->isc_has_offset);
   6022  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_511.ev_count, delta);
   6023  1.16.2.1        ad 
   6024  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6025  1.16.2.1        ad 	    I40E_GLPRT_PTC1023H(sc->sc_port), I40E_GLPRT_PTC1023L(sc->sc_port),
   6026  1.16.2.1        ad 	    &isc->isc_tx_size_1023_offset, isc->isc_has_offset);
   6027  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_1023.ev_count, delta);
   6028  1.16.2.1        ad 
   6029  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6030  1.16.2.1        ad 	    I40E_GLPRT_PTC1522H(sc->sc_port), I40E_GLPRT_PTC1522L(sc->sc_port),
   6031  1.16.2.1        ad 	    &isc->isc_tx_size_1522_offset, isc->isc_has_offset);
   6032  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_1522.ev_count, delta);
   6033  1.16.2.1        ad 
   6034  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6035  1.16.2.1        ad 	    I40E_GLPRT_PTC9522H(sc->sc_port), I40E_GLPRT_PTC9522L(sc->sc_port),
   6036  1.16.2.1        ad 	    &isc->isc_tx_size_big_offset, isc->isc_has_offset);
   6037  1.16.2.1        ad 	atomic_add_64(&isc->isc_tx_size_big.ev_count, delta);
   6038  1.16.2.1        ad 
   6039  1.16.2.1        ad 	/* mac faults */
   6040  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6041  1.16.2.1        ad 	    0, I40E_GLPRT_MLFC(sc->sc_port),
   6042  1.16.2.1        ad 	    &isc->isc_mac_local_faults_offset, isc->isc_has_offset);
   6043  1.16.2.1        ad 	atomic_add_64(&isc->isc_mac_local_faults.ev_count, delta);
   6044  1.16.2.1        ad 
   6045  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6046  1.16.2.1        ad 	    0, I40E_GLPRT_MRFC(sc->sc_port),
   6047  1.16.2.1        ad 	    &isc->isc_mac_remote_faults_offset, isc->isc_has_offset);
   6048  1.16.2.1        ad 	atomic_add_64(&isc->isc_mac_remote_faults.ev_count, delta);
   6049  1.16.2.1        ad 
   6050  1.16.2.1        ad 	/* Flow control (LFC) stats */
   6051  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6052  1.16.2.1        ad 	    0, I40E_GLPRT_LXONRXC(sc->sc_port),
   6053  1.16.2.1        ad 	    &isc->isc_link_xon_rx_offset, isc->isc_has_offset);
   6054  1.16.2.1        ad 	atomic_add_64(&isc->isc_link_xon_rx.ev_count, delta);
   6055  1.16.2.1        ad 
   6056  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6057  1.16.2.1        ad 	    0, I40E_GLPRT_LXONTXC(sc->sc_port),
   6058  1.16.2.1        ad 	    &isc->isc_link_xon_tx_offset, isc->isc_has_offset);
   6059  1.16.2.1        ad 	atomic_add_64(&isc->isc_link_xon_tx.ev_count, delta);
   6060  1.16.2.1        ad 
   6061  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6062  1.16.2.1        ad 	    0, I40E_GLPRT_LXOFFRXC(sc->sc_port),
   6063  1.16.2.1        ad 	    &isc->isc_link_xoff_rx_offset, isc->isc_has_offset);
   6064  1.16.2.1        ad 	atomic_add_64(&isc->isc_link_xoff_rx.ev_count, delta);
   6065  1.16.2.1        ad 
   6066  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6067  1.16.2.1        ad 	    0, I40E_GLPRT_LXOFFTXC(sc->sc_port),
   6068  1.16.2.1        ad 	    &isc->isc_link_xoff_tx_offset, isc->isc_has_offset);
   6069  1.16.2.1        ad 	atomic_add_64(&isc->isc_link_xoff_tx.ev_count, delta);
   6070  1.16.2.1        ad 
   6071  1.16.2.1        ad 	/* fragments */
   6072  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6073  1.16.2.1        ad 	    0, I40E_GLPRT_RFC(sc->sc_port),
   6074  1.16.2.1        ad 	    &isc->isc_rx_fragments_offset, isc->isc_has_offset);
   6075  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_fragments.ev_count, delta);
   6076  1.16.2.1        ad 
   6077  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6078  1.16.2.1        ad 	    0, I40E_GLPRT_RJC(sc->sc_port),
   6079  1.16.2.1        ad 	    &isc->isc_rx_jabber_offset, isc->isc_has_offset);
   6080  1.16.2.1        ad 	atomic_add_64(&isc->isc_rx_jabber.ev_count, delta);
   6081  1.16.2.1        ad 
   6082  1.16.2.1        ad 	/* VSI rx counters */
   6083  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6084  1.16.2.1        ad 	    0, I40E_GLV_RDPC(sc->sc_vsi_stat_counter_idx),
   6085  1.16.2.1        ad 	    &isc->isc_vsi_rx_discards_offset, isc->isc_has_offset);
   6086  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_rx_discards.ev_count, delta);
   6087  1.16.2.1        ad 
   6088  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6089  1.16.2.1        ad 	    I40E_GLV_GORCH(sc->sc_vsi_stat_counter_idx),
   6090  1.16.2.1        ad 	    I40E_GLV_GORCL(sc->sc_vsi_stat_counter_idx),
   6091  1.16.2.1        ad 	    &isc->isc_vsi_rx_bytes_offset, isc->isc_has_offset);
   6092  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_rx_bytes.ev_count, delta);
   6093  1.16.2.1        ad 
   6094  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6095  1.16.2.1        ad 	    I40E_GLV_UPRCH(sc->sc_vsi_stat_counter_idx),
   6096  1.16.2.1        ad 	    I40E_GLV_UPRCL(sc->sc_vsi_stat_counter_idx),
   6097  1.16.2.1        ad 	    &isc->isc_vsi_rx_unicast_offset, isc->isc_has_offset);
   6098  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_rx_unicast.ev_count, delta);
   6099  1.16.2.1        ad 
   6100  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6101  1.16.2.1        ad 	    I40E_GLV_MPRCH(sc->sc_vsi_stat_counter_idx),
   6102  1.16.2.1        ad 	    I40E_GLV_MPRCL(sc->sc_vsi_stat_counter_idx),
   6103  1.16.2.1        ad 	    &isc->isc_vsi_rx_multicast_offset, isc->isc_has_offset);
   6104  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_rx_multicast.ev_count, delta);
   6105  1.16.2.1        ad 
   6106  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6107  1.16.2.1        ad 	    I40E_GLV_BPRCH(sc->sc_vsi_stat_counter_idx),
   6108  1.16.2.1        ad 	    I40E_GLV_BPRCL(sc->sc_vsi_stat_counter_idx),
   6109  1.16.2.1        ad 	    &isc->isc_vsi_rx_broadcast_offset, isc->isc_has_offset);
   6110  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_rx_broadcast.ev_count, delta);
   6111  1.16.2.1        ad 
   6112  1.16.2.1        ad 	/* VSI tx counters */
   6113  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6114  1.16.2.1        ad 	    0, I40E_GLV_TEPC(sc->sc_vsi_stat_counter_idx),
   6115  1.16.2.1        ad 	    &isc->isc_vsi_tx_errors_offset, isc->isc_has_offset);
   6116  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_tx_errors.ev_count, delta);
   6117  1.16.2.1        ad 
   6118  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6119  1.16.2.1        ad 	    I40E_GLV_GOTCH(sc->sc_vsi_stat_counter_idx),
   6120  1.16.2.1        ad 	    I40E_GLV_GOTCL(sc->sc_vsi_stat_counter_idx),
   6121  1.16.2.1        ad 	    &isc->isc_vsi_tx_bytes_offset, isc->isc_has_offset);
   6122  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_tx_bytes.ev_count, delta);
   6123  1.16.2.1        ad 
   6124  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6125  1.16.2.1        ad 	    I40E_GLV_UPTCH(sc->sc_vsi_stat_counter_idx),
   6126  1.16.2.1        ad 	    I40E_GLV_UPTCL(sc->sc_vsi_stat_counter_idx),
   6127  1.16.2.1        ad 	    &isc->isc_vsi_tx_unicast_offset, isc->isc_has_offset);
   6128  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_tx_unicast.ev_count, delta);
   6129  1.16.2.1        ad 
   6130  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6131  1.16.2.1        ad 	    I40E_GLV_MPTCH(sc->sc_vsi_stat_counter_idx),
   6132  1.16.2.1        ad 	    I40E_GLV_MPTCL(sc->sc_vsi_stat_counter_idx),
   6133  1.16.2.1        ad 	    &isc->isc_vsi_tx_multicast_offset, isc->isc_has_offset);
   6134  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_tx_multicast.ev_count, delta);
   6135  1.16.2.1        ad 
   6136  1.16.2.1        ad 	delta = ixl_stat_delta(sc,
   6137  1.16.2.1        ad 	    I40E_GLV_BPTCH(sc->sc_vsi_stat_counter_idx),
   6138  1.16.2.1        ad 	    I40E_GLV_BPTCL(sc->sc_vsi_stat_counter_idx),
   6139  1.16.2.1        ad 	    &isc->isc_vsi_tx_broadcast_offset, isc->isc_has_offset);
   6140  1.16.2.1        ad 	atomic_add_64(&isc->isc_vsi_tx_broadcast.ev_count, delta);
   6141       1.1  yamaguch }
   6142       1.1  yamaguch 
   6143       1.1  yamaguch static int
   6144       1.1  yamaguch ixl_setup_sysctls(struct ixl_softc *sc)
   6145       1.1  yamaguch {
   6146       1.1  yamaguch 	const char *devname;
   6147       1.1  yamaguch 	struct sysctllog **log;
   6148       1.1  yamaguch 	const struct sysctlnode *rnode, *rxnode, *txnode;
   6149       1.1  yamaguch 	int error;
   6150       1.1  yamaguch 
   6151       1.1  yamaguch 	log = &sc->sc_sysctllog;
   6152       1.1  yamaguch 	devname = device_xname(sc->sc_dev);
   6153       1.1  yamaguch 
   6154       1.1  yamaguch 	error = sysctl_createv(log, 0, NULL, &rnode,
   6155       1.1  yamaguch 	    0, CTLTYPE_NODE, devname,
   6156       1.1  yamaguch 	    SYSCTL_DESCR("ixl information and settings"),
   6157       1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
   6158       1.1  yamaguch 	if (error)
   6159       1.1  yamaguch 		goto out;
   6160       1.1  yamaguch 
   6161       1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, NULL,
   6162       1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue",
   6163       1.1  yamaguch 	    SYSCTL_DESCR("Use workqueue for packet processing"),
   6164       1.1  yamaguch 	    NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL);
   6165       1.1  yamaguch 	if (error)
   6166       1.1  yamaguch 		goto out;
   6167       1.1  yamaguch 
   6168  1.16.2.1        ad 	error = sysctl_createv(log, 0, &rnode, NULL,
   6169  1.16.2.1        ad 	    CTLFLAG_READONLY, CTLTYPE_INT, "stats_interval",
   6170  1.16.2.1        ad 	    SYSCTL_DESCR("Statistics collection interval in milliseconds"),
   6171  1.16.2.1        ad 	    NULL, 0, &sc->sc_stats_intval, 0, CTL_CREATE, CTL_EOL);
   6172  1.16.2.1        ad 
   6173       1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, &rxnode,
   6174       1.1  yamaguch 	    0, CTLTYPE_NODE, "rx",
   6175       1.1  yamaguch 	    SYSCTL_DESCR("ixl information and settings for Rx"),
   6176       1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   6177       1.1  yamaguch 	if (error)
   6178       1.1  yamaguch 		goto out;
   6179       1.1  yamaguch 
   6180       1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   6181       1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   6182       1.1  yamaguch 	    SYSCTL_DESCR("max number of Rx packets"
   6183       1.1  yamaguch 	    " to process for interrupt processing"),
   6184       1.1  yamaguch 	    NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   6185       1.1  yamaguch 	if (error)
   6186       1.1  yamaguch 		goto out;
   6187       1.1  yamaguch 
   6188       1.1  yamaguch 	error = sysctl_createv(log, 0, &rxnode, NULL,
   6189       1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   6190       1.1  yamaguch 	    SYSCTL_DESCR("max number of Rx packets"
   6191       1.1  yamaguch 	    " to process for deferred processing"),
   6192       1.1  yamaguch 	    NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL);
   6193       1.1  yamaguch 	if (error)
   6194       1.1  yamaguch 		goto out;
   6195       1.1  yamaguch 
   6196       1.1  yamaguch 	error = sysctl_createv(log, 0, &rnode, &txnode,
   6197       1.1  yamaguch 	    0, CTLTYPE_NODE, "tx",
   6198       1.1  yamaguch 	    SYSCTL_DESCR("ixl information and settings for Tx"),
   6199       1.1  yamaguch 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
   6200       1.1  yamaguch 	if (error)
   6201       1.1  yamaguch 		goto out;
   6202       1.1  yamaguch 
   6203       1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   6204       1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit",
   6205       1.1  yamaguch 	    SYSCTL_DESCR("max number of Tx packets"
   6206       1.1  yamaguch 	    " to process for interrupt processing"),
   6207       1.1  yamaguch 	    NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL);
   6208       1.1  yamaguch 	if (error)
   6209       1.1  yamaguch 		goto out;
   6210       1.1  yamaguch 
   6211       1.1  yamaguch 	error = sysctl_createv(log, 0, &txnode, NULL,
   6212       1.1  yamaguch 	    CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit",
   6213       1.1  yamaguch 	    SYSCTL_DESCR("max number of Tx packets"
   6214       1.1  yamaguch 	    " to process for deferred processing"),
   6215       1.1  yamaguch 	    NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL);
   6216       1.1  yamaguch 	if (error)
   6217       1.1  yamaguch 		goto out;
   6218       1.1  yamaguch 
   6219       1.1  yamaguch out:
   6220       1.1  yamaguch 	if (error) {
   6221       1.1  yamaguch 		aprint_error_dev(sc->sc_dev,
   6222       1.1  yamaguch 		    "unable to create sysctl node\n");
   6223       1.1  yamaguch 		sysctl_teardown(log);
   6224       1.1  yamaguch 	}
   6225       1.1  yamaguch 
   6226       1.1  yamaguch 	return error;
   6227       1.1  yamaguch }
   6228       1.1  yamaguch 
   6229       1.1  yamaguch static void
   6230       1.1  yamaguch ixl_teardown_sysctls(struct ixl_softc *sc)
   6231       1.1  yamaguch {
   6232       1.1  yamaguch 
   6233       1.1  yamaguch 	sysctl_teardown(&sc->sc_sysctllog);
   6234       1.1  yamaguch }
   6235       1.1  yamaguch 
   6236       1.1  yamaguch static struct workqueue *
   6237       1.1  yamaguch ixl_workq_create(const char *name, pri_t prio, int ipl, int flags)
   6238       1.1  yamaguch {
   6239       1.1  yamaguch 	struct workqueue *wq;
   6240       1.1  yamaguch 	int error;
   6241       1.1  yamaguch 
   6242       1.1  yamaguch 	error = workqueue_create(&wq, name, ixl_workq_work, NULL,
   6243       1.1  yamaguch 	    prio, ipl, flags);
   6244       1.1  yamaguch 
   6245       1.1  yamaguch 	if (error)
   6246       1.1  yamaguch 		return NULL;
   6247       1.1  yamaguch 
   6248       1.1  yamaguch 	return wq;
   6249       1.1  yamaguch }
   6250       1.1  yamaguch 
   6251       1.1  yamaguch static void
   6252       1.1  yamaguch ixl_workq_destroy(struct workqueue *wq)
   6253       1.1  yamaguch {
   6254       1.1  yamaguch 
   6255       1.1  yamaguch 	workqueue_destroy(wq);
   6256       1.1  yamaguch }
   6257       1.1  yamaguch 
   6258       1.1  yamaguch static void
   6259       1.1  yamaguch ixl_work_set(struct ixl_work *work, void (*func)(void *), void *arg)
   6260       1.1  yamaguch {
   6261       1.1  yamaguch 
   6262       1.1  yamaguch 	memset(work, 0, sizeof(*work));
   6263       1.1  yamaguch 	work->ixw_func = func;
   6264       1.1  yamaguch 	work->ixw_arg = arg;
   6265       1.1  yamaguch }
   6266       1.1  yamaguch 
   6267       1.1  yamaguch static void
   6268       1.1  yamaguch ixl_work_add(struct workqueue *wq, struct ixl_work *work)
   6269       1.1  yamaguch {
   6270       1.1  yamaguch 	if (atomic_cas_uint(&work->ixw_added, 0, 1) != 0)
   6271       1.1  yamaguch 		return;
   6272       1.1  yamaguch 
   6273       1.1  yamaguch 	workqueue_enqueue(wq, &work->ixw_cookie, NULL);
   6274       1.1  yamaguch }
   6275       1.1  yamaguch 
   6276       1.1  yamaguch static void
   6277       1.1  yamaguch ixl_work_wait(struct workqueue *wq, struct ixl_work *work)
   6278       1.1  yamaguch {
   6279       1.1  yamaguch 
   6280       1.1  yamaguch 	workqueue_wait(wq, &work->ixw_cookie);
   6281       1.1  yamaguch }
   6282       1.1  yamaguch 
   6283       1.1  yamaguch static void
   6284       1.1  yamaguch ixl_workq_work(struct work *wk, void *context)
   6285       1.1  yamaguch {
   6286       1.1  yamaguch 	struct ixl_work *work;
   6287       1.1  yamaguch 
   6288       1.1  yamaguch 	work = container_of(wk, struct ixl_work, ixw_cookie);
   6289       1.1  yamaguch 
   6290       1.1  yamaguch 	atomic_swap_uint(&work->ixw_added, 0);
   6291       1.1  yamaguch 	work->ixw_func(work->ixw_arg);
   6292       1.1  yamaguch }
   6293       1.1  yamaguch 
   6294       1.1  yamaguch static int
   6295       1.1  yamaguch ixl_rx_ctl_read(struct ixl_softc *sc, uint32_t reg, uint32_t *rv)
   6296       1.1  yamaguch {
   6297       1.1  yamaguch 	struct ixl_aq_desc iaq;
   6298       1.1  yamaguch 
   6299       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   6300       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_RX_CTL_REG_READ);
   6301       1.1  yamaguch 	iaq.iaq_param[1] = htole32(reg);
   6302       1.1  yamaguch 
   6303       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0)
   6304       1.1  yamaguch 		return ETIMEDOUT;
   6305       1.1  yamaguch 
   6306       1.1  yamaguch 	switch (htole16(iaq.iaq_retval)) {
   6307       1.1  yamaguch 	case IXL_AQ_RC_OK:
   6308       1.1  yamaguch 		/* success */
   6309       1.1  yamaguch 		break;
   6310       1.1  yamaguch 	case IXL_AQ_RC_EACCES:
   6311       1.1  yamaguch 		return EPERM;
   6312       1.1  yamaguch 	case IXL_AQ_RC_EAGAIN:
   6313       1.1  yamaguch 		return EAGAIN;
   6314       1.1  yamaguch 	default:
   6315       1.1  yamaguch 		return EIO;
   6316       1.1  yamaguch 	}
   6317       1.1  yamaguch 
   6318       1.1  yamaguch 	*rv = htole32(iaq.iaq_param[3]);
   6319       1.1  yamaguch 	return 0;
   6320       1.1  yamaguch }
   6321       1.1  yamaguch 
   6322       1.1  yamaguch static uint32_t
   6323       1.1  yamaguch ixl_rd_rx_csr(struct ixl_softc *sc, uint32_t reg)
   6324       1.1  yamaguch {
   6325       1.1  yamaguch 	uint32_t val;
   6326       1.1  yamaguch 	int rv, retry, retry_limit;
   6327       1.1  yamaguch 
   6328  1.16.2.1        ad 	if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL)) {
   6329  1.16.2.1        ad 		retry_limit = 5;
   6330  1.16.2.1        ad 	} else {
   6331  1.16.2.1        ad 		retry_limit = 0;
   6332  1.16.2.1        ad 	}
   6333       1.1  yamaguch 
   6334       1.1  yamaguch 	for (retry = 0; retry < retry_limit; retry++) {
   6335       1.1  yamaguch 		rv = ixl_rx_ctl_read(sc, reg, &val);
   6336       1.1  yamaguch 		if (rv == 0)
   6337       1.1  yamaguch 			return val;
   6338       1.1  yamaguch 		else if (rv == EAGAIN)
   6339       1.1  yamaguch 			delaymsec(1);
   6340       1.1  yamaguch 		else
   6341       1.1  yamaguch 			break;
   6342       1.1  yamaguch 	}
   6343       1.1  yamaguch 
   6344       1.1  yamaguch 	val = ixl_rd(sc, reg);
   6345       1.1  yamaguch 
   6346       1.1  yamaguch 	return val;
   6347       1.1  yamaguch }
   6348       1.1  yamaguch 
   6349       1.1  yamaguch static int
   6350       1.1  yamaguch ixl_rx_ctl_write(struct ixl_softc *sc, uint32_t reg, uint32_t value)
   6351       1.1  yamaguch {
   6352       1.1  yamaguch 	struct ixl_aq_desc iaq;
   6353       1.1  yamaguch 
   6354       1.1  yamaguch 	memset(&iaq, 0, sizeof(iaq));
   6355       1.1  yamaguch 	iaq.iaq_opcode = htole16(IXL_AQ_OP_RX_CTL_REG_WRITE);
   6356       1.1  yamaguch 	iaq.iaq_param[1] = htole32(reg);
   6357       1.1  yamaguch 	iaq.iaq_param[3] = htole32(value);
   6358       1.1  yamaguch 
   6359       1.1  yamaguch 	if (ixl_atq_poll(sc, &iaq, 250) != 0)
   6360       1.1  yamaguch 		return ETIMEDOUT;
   6361       1.1  yamaguch 
   6362       1.1  yamaguch 	switch (htole16(iaq.iaq_retval)) {
   6363       1.1  yamaguch 	case IXL_AQ_RC_OK:
   6364       1.1  yamaguch 		/* success */
   6365       1.1  yamaguch 		break;
   6366       1.1  yamaguch 	case IXL_AQ_RC_EACCES:
   6367       1.1  yamaguch 		return EPERM;
   6368       1.1  yamaguch 	case IXL_AQ_RC_EAGAIN:
   6369       1.1  yamaguch 		return EAGAIN;
   6370       1.1  yamaguch 	default:
   6371       1.1  yamaguch 		return EIO;
   6372       1.1  yamaguch 	}
   6373       1.1  yamaguch 
   6374       1.1  yamaguch 	return 0;
   6375       1.1  yamaguch }
   6376       1.1  yamaguch 
   6377       1.1  yamaguch static void
   6378       1.1  yamaguch ixl_wr_rx_csr(struct ixl_softc *sc, uint32_t reg, uint32_t value)
   6379       1.1  yamaguch {
   6380       1.1  yamaguch 	int rv, retry, retry_limit;
   6381       1.1  yamaguch 
   6382  1.16.2.1        ad 	if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL)) {
   6383  1.16.2.1        ad 		retry_limit = 5;
   6384  1.16.2.1        ad 	} else {
   6385  1.16.2.1        ad 		retry_limit = 0;
   6386  1.16.2.1        ad 	}
   6387       1.1  yamaguch 
   6388       1.1  yamaguch 	for (retry = 0; retry < retry_limit; retry++) {
   6389       1.1  yamaguch 		rv = ixl_rx_ctl_write(sc, reg, value);
   6390       1.1  yamaguch 		if (rv == 0)
   6391       1.1  yamaguch 			return;
   6392       1.1  yamaguch 		else if (rv == EAGAIN)
   6393       1.1  yamaguch 			delaymsec(1);
   6394       1.1  yamaguch 		else
   6395       1.1  yamaguch 			break;
   6396       1.1  yamaguch 	}
   6397       1.1  yamaguch 
   6398       1.1  yamaguch 	ixl_wr(sc, reg, value);
   6399       1.1  yamaguch }
   6400       1.1  yamaguch 
   6401  1.16.2.1        ad static int
   6402  1.16.2.1        ad ixl_nvm_lock(struct ixl_softc *sc, char rw)
   6403  1.16.2.1        ad {
   6404  1.16.2.1        ad 	struct ixl_aq_desc iaq;
   6405  1.16.2.1        ad 	struct ixl_aq_req_resource_param *param;
   6406  1.16.2.1        ad 	int rv;
   6407  1.16.2.1        ad 
   6408  1.16.2.1        ad 	if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK))
   6409  1.16.2.1        ad 		return 0;
   6410  1.16.2.1        ad 
   6411  1.16.2.1        ad 	memset(&iaq, 0, sizeof(iaq));
   6412  1.16.2.1        ad 	iaq.iaq_opcode = htole16(IXL_AQ_OP_REQUEST_RESOURCE);
   6413  1.16.2.1        ad 
   6414  1.16.2.1        ad 	param = (struct ixl_aq_req_resource_param *)&iaq.iaq_param;
   6415  1.16.2.1        ad 	param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM);
   6416  1.16.2.1        ad 	if (rw == 'R') {
   6417  1.16.2.1        ad 		param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_READ);
   6418  1.16.2.1        ad 	} else {
   6419  1.16.2.1        ad 		param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_WRITE);
   6420  1.16.2.1        ad 	}
   6421  1.16.2.1        ad 
   6422  1.16.2.1        ad 	rv = ixl_atq_poll(sc, &iaq, 250);
   6423  1.16.2.1        ad 
   6424  1.16.2.1        ad 	if (rv != 0)
   6425  1.16.2.1        ad 		return ETIMEDOUT;
   6426  1.16.2.1        ad 
   6427  1.16.2.1        ad 	switch (le16toh(iaq.iaq_retval)) {
   6428  1.16.2.1        ad 	case IXL_AQ_RC_OK:
   6429  1.16.2.1        ad 		break;
   6430  1.16.2.1        ad 	case IXL_AQ_RC_EACCES:
   6431  1.16.2.1        ad 		return EACCES;
   6432  1.16.2.1        ad 	case IXL_AQ_RC_EBUSY:
   6433  1.16.2.1        ad 		return EBUSY;
   6434  1.16.2.1        ad 	case IXL_AQ_RC_EPERM:
   6435  1.16.2.1        ad 		return EPERM;
   6436  1.16.2.1        ad 	}
   6437  1.16.2.1        ad 
   6438  1.16.2.1        ad 	return 0;
   6439  1.16.2.1        ad }
   6440  1.16.2.1        ad 
   6441  1.16.2.1        ad static int
   6442  1.16.2.1        ad ixl_nvm_unlock(struct ixl_softc *sc)
   6443  1.16.2.1        ad {
   6444  1.16.2.1        ad 	struct ixl_aq_desc iaq;
   6445  1.16.2.1        ad 	struct ixl_aq_rel_resource_param *param;
   6446  1.16.2.1        ad 	int rv;
   6447  1.16.2.1        ad 
   6448  1.16.2.1        ad 	if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK))
   6449  1.16.2.1        ad 		return 0;
   6450  1.16.2.1        ad 
   6451  1.16.2.1        ad 	memset(&iaq, 0, sizeof(iaq));
   6452  1.16.2.1        ad 	iaq.iaq_opcode = htole16(IXL_AQ_OP_RELEASE_RESOURCE);
   6453  1.16.2.1        ad 
   6454  1.16.2.1        ad 	param = (struct ixl_aq_rel_resource_param *)&iaq.iaq_param;
   6455  1.16.2.1        ad 	param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM);
   6456  1.16.2.1        ad 
   6457  1.16.2.1        ad 	rv = ixl_atq_poll(sc, &iaq, 250);
   6458  1.16.2.1        ad 
   6459  1.16.2.1        ad 	if (rv != 0)
   6460  1.16.2.1        ad 		return ETIMEDOUT;
   6461  1.16.2.1        ad 
   6462  1.16.2.1        ad 	switch (le16toh(iaq.iaq_retval)) {
   6463  1.16.2.1        ad 	case IXL_AQ_RC_OK:
   6464  1.16.2.1        ad 		break;
   6465  1.16.2.1        ad 	default:
   6466  1.16.2.1        ad 		return EIO;
   6467  1.16.2.1        ad 	}
   6468  1.16.2.1        ad 	return 0;
   6469  1.16.2.1        ad }
   6470  1.16.2.1        ad 
   6471  1.16.2.1        ad static int
   6472  1.16.2.1        ad ixl_srdone_poll(struct ixl_softc *sc)
   6473  1.16.2.1        ad {
   6474  1.16.2.1        ad 	int wait_count;
   6475  1.16.2.1        ad 	uint32_t reg;
   6476  1.16.2.1        ad 
   6477  1.16.2.1        ad 	for (wait_count = 0; wait_count < IXL_SRRD_SRCTL_ATTEMPTS;
   6478  1.16.2.1        ad 	    wait_count++) {
   6479  1.16.2.1        ad 		reg = ixl_rd(sc, I40E_GLNVM_SRCTL);
   6480  1.16.2.1        ad 		if (ISSET(reg, I40E_GLNVM_SRCTL_DONE_MASK))
   6481  1.16.2.1        ad 			break;
   6482  1.16.2.1        ad 
   6483  1.16.2.1        ad 		delaymsec(5);
   6484  1.16.2.1        ad 	}
   6485  1.16.2.1        ad 
   6486  1.16.2.1        ad 	if (wait_count == IXL_SRRD_SRCTL_ATTEMPTS)
   6487  1.16.2.1        ad 		return -1;
   6488  1.16.2.1        ad 
   6489  1.16.2.1        ad 	return 0;
   6490  1.16.2.1        ad }
   6491  1.16.2.1        ad 
   6492  1.16.2.1        ad static int
   6493  1.16.2.1        ad ixl_nvm_read_srctl(struct ixl_softc *sc, uint16_t offset, uint16_t *data)
   6494  1.16.2.1        ad {
   6495  1.16.2.1        ad 	uint32_t reg;
   6496  1.16.2.1        ad 
   6497  1.16.2.1        ad 	if (ixl_srdone_poll(sc) != 0)
   6498  1.16.2.1        ad 		return ETIMEDOUT;
   6499  1.16.2.1        ad 
   6500  1.16.2.1        ad 	reg = ((uint32_t)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
   6501  1.16.2.1        ad 	    __BIT(I40E_GLNVM_SRCTL_START_SHIFT);
   6502  1.16.2.1        ad 	ixl_wr(sc, I40E_GLNVM_SRCTL, reg);
   6503  1.16.2.1        ad 
   6504  1.16.2.1        ad 	if (ixl_srdone_poll(sc) != 0) {
   6505  1.16.2.1        ad 		aprint_debug("NVM read error: couldn't access "
   6506  1.16.2.1        ad 		    "Shadow RAM address: 0x%x\n", offset);
   6507  1.16.2.1        ad 		return ETIMEDOUT;
   6508  1.16.2.1        ad 	}
   6509  1.16.2.1        ad 
   6510  1.16.2.1        ad 	reg = ixl_rd(sc, I40E_GLNVM_SRDATA);
   6511  1.16.2.1        ad 	*data = (uint16_t)__SHIFTOUT(reg, I40E_GLNVM_SRDATA_RDDATA_MASK);
   6512  1.16.2.1        ad 
   6513  1.16.2.1        ad 	return 0;
   6514  1.16.2.1        ad }
   6515  1.16.2.1        ad 
   6516  1.16.2.1        ad static int
   6517  1.16.2.1        ad ixl_nvm_read_aq(struct ixl_softc *sc, uint16_t offset_word,
   6518  1.16.2.1        ad     void *data, size_t len)
   6519  1.16.2.1        ad {
   6520  1.16.2.1        ad 	struct ixl_dmamem *idm;
   6521  1.16.2.1        ad 	struct ixl_aq_desc iaq;
   6522  1.16.2.1        ad 	struct ixl_aq_nvm_param *param;
   6523  1.16.2.1        ad 	uint32_t offset_bytes;
   6524  1.16.2.1        ad 	int rv;
   6525  1.16.2.1        ad 
   6526  1.16.2.1        ad 	idm = &sc->sc_aqbuf;
   6527  1.16.2.1        ad 	if (len > IXL_DMA_LEN(idm))
   6528  1.16.2.1        ad 		return ENOMEM;
   6529  1.16.2.1        ad 
   6530  1.16.2.1        ad 	memset(IXL_DMA_KVA(idm), 0, IXL_DMA_LEN(idm));
   6531  1.16.2.1        ad 	memset(&iaq, 0, sizeof(iaq));
   6532  1.16.2.1        ad 	iaq.iaq_opcode = htole16(IXL_AQ_OP_NVM_READ);
   6533  1.16.2.1        ad 	iaq.iaq_flags = htole16(IXL_AQ_BUF |
   6534  1.16.2.1        ad 	    ((len > I40E_AQ_LARGE_BUF) ? IXL_AQ_LB : 0));
   6535  1.16.2.1        ad 	iaq.iaq_datalen = htole16(len);
   6536  1.16.2.1        ad 	ixl_aq_dva(&iaq, IXL_DMA_DVA(idm));
   6537  1.16.2.1        ad 
   6538  1.16.2.1        ad 	param = (struct ixl_aq_nvm_param *)iaq.iaq_param;
   6539  1.16.2.1        ad 	param->command_flags = IXL_AQ_NVM_LAST_CMD;
   6540  1.16.2.1        ad 	param->module_pointer = 0;
   6541  1.16.2.1        ad 	param->length = htole16(len);
   6542  1.16.2.1        ad 	offset_bytes = (uint32_t)offset_word * 2;
   6543  1.16.2.1        ad 	offset_bytes &= 0x00FFFFFF;
   6544  1.16.2.1        ad 	param->offset = htole32(offset_bytes);
   6545  1.16.2.1        ad 
   6546  1.16.2.1        ad 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm),
   6547  1.16.2.1        ad 	    BUS_DMASYNC_PREREAD);
   6548  1.16.2.1        ad 
   6549  1.16.2.1        ad 	rv = ixl_atq_poll(sc, &iaq, 250);
   6550  1.16.2.1        ad 
   6551  1.16.2.1        ad 	bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm),
   6552  1.16.2.1        ad 	    BUS_DMASYNC_POSTREAD);
   6553  1.16.2.1        ad 
   6554  1.16.2.1        ad 	if (rv != 0) {
   6555  1.16.2.1        ad 		return ETIMEDOUT;
   6556  1.16.2.1        ad 	}
   6557  1.16.2.1        ad 
   6558  1.16.2.1        ad 	switch (le16toh(iaq.iaq_retval)) {
   6559  1.16.2.1        ad 	case IXL_AQ_RC_OK:
   6560  1.16.2.1        ad 		break;
   6561  1.16.2.1        ad 	case IXL_AQ_RC_EPERM:
   6562  1.16.2.1        ad 		return EPERM;
   6563  1.16.2.1        ad 	case IXL_AQ_RC_EINVAL:
   6564  1.16.2.1        ad 		return EINVAL;
   6565  1.16.2.1        ad 	case IXL_AQ_RC_EBUSY:
   6566  1.16.2.1        ad 		return EBUSY;
   6567  1.16.2.1        ad 	case IXL_AQ_RC_EIO:
   6568  1.16.2.1        ad 	default:
   6569  1.16.2.1        ad 		return EIO;
   6570  1.16.2.1        ad 	}
   6571  1.16.2.1        ad 
   6572  1.16.2.1        ad 	memcpy(data, IXL_DMA_KVA(idm), len);
   6573  1.16.2.1        ad 
   6574  1.16.2.1        ad 	return 0;
   6575  1.16.2.1        ad }
   6576  1.16.2.1        ad 
   6577  1.16.2.1        ad static int
   6578  1.16.2.1        ad ixl_rd16_nvm(struct ixl_softc *sc, uint16_t offset, uint16_t *data)
   6579  1.16.2.1        ad {
   6580  1.16.2.1        ad 	int error;
   6581  1.16.2.1        ad 	uint16_t buf;
   6582  1.16.2.1        ad 
   6583  1.16.2.1        ad 	error = ixl_nvm_lock(sc, 'R');
   6584  1.16.2.1        ad 	if (error)
   6585  1.16.2.1        ad 		return error;
   6586  1.16.2.1        ad 
   6587  1.16.2.1        ad 	if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMREAD)) {
   6588  1.16.2.1        ad 		error = ixl_nvm_read_aq(sc, offset,
   6589  1.16.2.1        ad 		    &buf, sizeof(buf));
   6590  1.16.2.1        ad 		if (error == 0)
   6591  1.16.2.1        ad 			*data = le16toh(buf);
   6592  1.16.2.1        ad 	} else {
   6593  1.16.2.1        ad 		error = ixl_nvm_read_srctl(sc, offset, &buf);
   6594  1.16.2.1        ad 		if (error == 0)
   6595  1.16.2.1        ad 			*data = buf;
   6596  1.16.2.1        ad 	}
   6597  1.16.2.1        ad 
   6598  1.16.2.1        ad 	ixl_nvm_unlock(sc);
   6599  1.16.2.1        ad 
   6600  1.16.2.1        ad 	return error;
   6601  1.16.2.1        ad }
   6602  1.16.2.1        ad 
   6603       1.1  yamaguch MODULE(MODULE_CLASS_DRIVER, if_ixl, "pci");
   6604       1.1  yamaguch 
   6605       1.1  yamaguch #ifdef _MODULE
   6606       1.1  yamaguch #include "ioconf.c"
   6607       1.1  yamaguch #endif
   6608       1.1  yamaguch 
   6609  1.16.2.1        ad #ifdef _MODULE
   6610  1.16.2.1        ad static void
   6611  1.16.2.1        ad ixl_parse_modprop(prop_dictionary_t dict)
   6612  1.16.2.1        ad {
   6613  1.16.2.1        ad 	prop_object_t obj;
   6614  1.16.2.1        ad 	int64_t val;
   6615  1.16.2.1        ad 	uint64_t uval;
   6616  1.16.2.1        ad 
   6617  1.16.2.1        ad 	if (dict == NULL)
   6618  1.16.2.1        ad 		return;
   6619  1.16.2.1        ad 
   6620  1.16.2.1        ad 	obj = prop_dictionary_get(dict, "nomsix");
   6621  1.16.2.1        ad 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_BOOL) {
   6622  1.16.2.1        ad 		ixl_param_nomsix = prop_bool_true((prop_bool_t)obj);
   6623  1.16.2.1        ad 	}
   6624  1.16.2.1        ad 
   6625  1.16.2.1        ad 	obj = prop_dictionary_get(dict, "stats_interval");
   6626  1.16.2.1        ad 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   6627  1.16.2.1        ad 		val = prop_number_integer_value((prop_number_t)obj);
   6628  1.16.2.1        ad 
   6629  1.16.2.1        ad 		/* the range has no reason */
   6630  1.16.2.1        ad 		if (100 < val && val < 180000) {
   6631  1.16.2.1        ad 			ixl_param_stats_interval = val;
   6632  1.16.2.1        ad 		}
   6633  1.16.2.1        ad 	}
   6634  1.16.2.1        ad 
   6635  1.16.2.1        ad 	obj = prop_dictionary_get(dict, "nqps_limit");
   6636  1.16.2.1        ad 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   6637  1.16.2.1        ad 		val = prop_number_integer_value((prop_number_t)obj);
   6638  1.16.2.1        ad 
   6639  1.16.2.1        ad 		if (val <= INT32_MAX)
   6640  1.16.2.1        ad 			ixl_param_nqps_limit = val;
   6641  1.16.2.1        ad 	}
   6642  1.16.2.1        ad 
   6643  1.16.2.1        ad 	obj = prop_dictionary_get(dict, "rx_ndescs");
   6644  1.16.2.1        ad 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   6645  1.16.2.1        ad 		uval = prop_number_unsigned_integer_value((prop_number_t)obj);
   6646  1.16.2.1        ad 
   6647  1.16.2.1        ad 		if (uval > 8)
   6648  1.16.2.1        ad 			ixl_param_rx_ndescs = uval;
   6649  1.16.2.1        ad 	}
   6650  1.16.2.1        ad 
   6651  1.16.2.1        ad 	obj = prop_dictionary_get(dict, "tx_ndescs");
   6652  1.16.2.1        ad 	if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) {
   6653  1.16.2.1        ad 		uval = prop_number_unsigned_integer_value((prop_number_t)obj);
   6654  1.16.2.1        ad 
   6655  1.16.2.1        ad 		if (uval > IXL_TX_PKT_DESCS)
   6656  1.16.2.1        ad 			ixl_param_tx_ndescs = uval;
   6657  1.16.2.1        ad 	}
   6658  1.16.2.1        ad 
   6659  1.16.2.1        ad }
   6660  1.16.2.1        ad #endif
   6661  1.16.2.1        ad 
   6662       1.1  yamaguch static int
   6663       1.1  yamaguch if_ixl_modcmd(modcmd_t cmd, void *opaque)
   6664       1.1  yamaguch {
   6665       1.1  yamaguch 	int error = 0;
   6666       1.1  yamaguch 
   6667       1.1  yamaguch #ifdef _MODULE
   6668       1.1  yamaguch 	switch (cmd) {
   6669       1.1  yamaguch 	case MODULE_CMD_INIT:
   6670  1.16.2.1        ad 		ixl_parse_modprop((prop_dictionary_t)opaque);
   6671       1.1  yamaguch 		error = config_init_component(cfdriver_ioconf_if_ixl,
   6672       1.1  yamaguch 		    cfattach_ioconf_if_ixl, cfdata_ioconf_if_ixl);
   6673       1.1  yamaguch 		break;
   6674       1.1  yamaguch 	case MODULE_CMD_FINI:
   6675       1.1  yamaguch 		error = config_fini_component(cfdriver_ioconf_if_ixl,
   6676       1.1  yamaguch 		    cfattach_ioconf_if_ixl, cfdata_ioconf_if_ixl);
   6677       1.1  yamaguch 		break;
   6678       1.1  yamaguch 	default:
   6679       1.1  yamaguch 		error = ENOTTY;
   6680       1.1  yamaguch 		break;
   6681       1.1  yamaguch 	}
   6682       1.1  yamaguch #endif
   6683       1.1  yamaguch 
   6684       1.1  yamaguch 	return error;
   6685       1.1  yamaguch }
   6686