Home | History | Annotate | Line # | Download | only in pci
if_ena.c revision 1.13
      1   1.1  jdolecek /*-
      2   1.1  jdolecek  * BSD LICENSE
      3   1.1  jdolecek  *
      4   1.1  jdolecek  * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates.
      5   1.1  jdolecek  * All rights reserved.
      6   1.1  jdolecek  *
      7   1.1  jdolecek  * Redistribution and use in source and binary forms, with or without
      8   1.1  jdolecek  * modification, are permitted provided that the following conditions
      9   1.1  jdolecek  * are met:
     10   1.1  jdolecek  *
     11   1.1  jdolecek  * 1. Redistributions of source code must retain the above copyright
     12   1.1  jdolecek  *    notice, this list of conditions and the following disclaimer.
     13   1.1  jdolecek  *
     14   1.1  jdolecek  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1  jdolecek  *    notice, this list of conditions and the following disclaimer in the
     16   1.1  jdolecek  *    documentation and/or other materials provided with the distribution.
     17   1.1  jdolecek  *
     18   1.1  jdolecek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19   1.1  jdolecek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20   1.1  jdolecek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21   1.1  jdolecek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22   1.1  jdolecek  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23   1.1  jdolecek  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24   1.1  jdolecek  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25   1.1  jdolecek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26   1.1  jdolecek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27   1.1  jdolecek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28   1.1  jdolecek  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29   1.1  jdolecek  */
     30   1.1  jdolecek #include <sys/cdefs.h>
     31   1.2  jdolecek #if 0
     32   1.1  jdolecek __FBSDID("$FreeBSD: head/sys/dev/ena/ena.c 333456 2018-05-10 09:37:54Z mw $");
     33   1.2  jdolecek #endif
     34  1.13     ryoon __KERNEL_RCSID(0, "$NetBSD: if_ena.c,v 1.13 2019/01/23 11:15:11 ryoon Exp $");
     35   1.1  jdolecek 
     36   1.1  jdolecek #include <sys/param.h>
     37   1.1  jdolecek #include <sys/systm.h>
     38   1.1  jdolecek #include <sys/bus.h>
     39   1.1  jdolecek #include <sys/endian.h>
     40   1.1  jdolecek #include <sys/kernel.h>
     41   1.1  jdolecek #include <sys/kthread.h>
     42   1.1  jdolecek #include <sys/malloc.h>
     43   1.1  jdolecek #include <sys/mbuf.h>
     44   1.1  jdolecek #include <sys/module.h>
     45   1.1  jdolecek #include <sys/socket.h>
     46   1.1  jdolecek #include <sys/sockio.h>
     47   1.1  jdolecek #include <sys/sysctl.h>
     48   1.1  jdolecek #include <sys/time.h>
     49   1.2  jdolecek #include <sys/workqueue.h>
     50   1.4  jdolecek #include <sys/callout.h>
     51   1.4  jdolecek #include <sys/interrupt.h>
     52   1.4  jdolecek #include <sys/cpu.h>
     53   1.1  jdolecek 
     54   1.2  jdolecek #include <sys/bus.h>
     55   1.1  jdolecek 
     56   1.4  jdolecek #include <net/if_ether.h>
     57   1.4  jdolecek #include <net/if_vlanvar.h>
     58   1.4  jdolecek 
     59   1.2  jdolecek #include <dev/pci/if_enavar.h>
     60   1.1  jdolecek 
     61   1.1  jdolecek /*********************************************************
     62   1.1  jdolecek  *  Function prototypes
     63   1.1  jdolecek  *********************************************************/
     64   1.2  jdolecek static int	ena_probe(device_t, cfdata_t, void *);
     65   1.4  jdolecek static int	ena_intr_msix_mgmnt(void *);
     66   1.4  jdolecek static int	ena_allocate_pci_resources(struct pci_attach_args *,
     67   1.4  jdolecek 		    struct ena_adapter *);
     68   1.1  jdolecek static void	ena_free_pci_resources(struct ena_adapter *);
     69   1.2  jdolecek static int	ena_change_mtu(struct ifnet *, int);
     70   1.1  jdolecek static void	ena_init_io_rings_common(struct ena_adapter *,
     71   1.1  jdolecek     struct ena_ring *, uint16_t);
     72   1.1  jdolecek static void	ena_init_io_rings(struct ena_adapter *);
     73   1.1  jdolecek static void	ena_free_io_ring_resources(struct ena_adapter *, unsigned int);
     74   1.1  jdolecek static void	ena_free_all_io_rings_resources(struct ena_adapter *);
     75   1.4  jdolecek #if 0
     76   1.1  jdolecek static int	ena_setup_tx_dma_tag(struct ena_adapter *);
     77   1.1  jdolecek static int	ena_free_tx_dma_tag(struct ena_adapter *);
     78   1.1  jdolecek static int	ena_setup_rx_dma_tag(struct ena_adapter *);
     79   1.1  jdolecek static int	ena_free_rx_dma_tag(struct ena_adapter *);
     80   1.4  jdolecek #endif
     81   1.1  jdolecek static int	ena_setup_tx_resources(struct ena_adapter *, int);
     82   1.1  jdolecek static void	ena_free_tx_resources(struct ena_adapter *, int);
     83   1.1  jdolecek static int	ena_setup_all_tx_resources(struct ena_adapter *);
     84   1.1  jdolecek static void	ena_free_all_tx_resources(struct ena_adapter *);
     85   1.1  jdolecek static inline int validate_rx_req_id(struct ena_ring *, uint16_t);
     86   1.1  jdolecek static int	ena_setup_rx_resources(struct ena_adapter *, unsigned int);
     87   1.1  jdolecek static void	ena_free_rx_resources(struct ena_adapter *, unsigned int);
     88   1.1  jdolecek static int	ena_setup_all_rx_resources(struct ena_adapter *);
     89   1.1  jdolecek static void	ena_free_all_rx_resources(struct ena_adapter *);
     90   1.1  jdolecek static inline int ena_alloc_rx_mbuf(struct ena_adapter *, struct ena_ring *,
     91   1.1  jdolecek     struct ena_rx_buffer *);
     92   1.1  jdolecek static void	ena_free_rx_mbuf(struct ena_adapter *, struct ena_ring *,
     93   1.1  jdolecek     struct ena_rx_buffer *);
     94   1.1  jdolecek static int	ena_refill_rx_bufs(struct ena_ring *, uint32_t);
     95   1.1  jdolecek static void	ena_free_rx_bufs(struct ena_adapter *, unsigned int);
     96   1.1  jdolecek static void	ena_refill_all_rx_bufs(struct ena_adapter *);
     97   1.1  jdolecek static void	ena_free_all_rx_bufs(struct ena_adapter *);
     98   1.1  jdolecek static void	ena_free_tx_bufs(struct ena_adapter *, unsigned int);
     99   1.1  jdolecek static void	ena_free_all_tx_bufs(struct ena_adapter *);
    100   1.1  jdolecek static void	ena_destroy_all_tx_queues(struct ena_adapter *);
    101   1.1  jdolecek static void	ena_destroy_all_rx_queues(struct ena_adapter *);
    102   1.1  jdolecek static void	ena_destroy_all_io_queues(struct ena_adapter *);
    103   1.1  jdolecek static int	ena_create_io_queues(struct ena_adapter *);
    104   1.1  jdolecek static int	ena_tx_cleanup(struct ena_ring *);
    105   1.4  jdolecek static void	ena_deferred_rx_cleanup(struct work *, void *);
    106   1.1  jdolecek static int	ena_rx_cleanup(struct ena_ring *);
    107   1.1  jdolecek static inline int validate_tx_req_id(struct ena_ring *, uint16_t);
    108   1.4  jdolecek #if 0
    109   1.1  jdolecek static void	ena_rx_hash_mbuf(struct ena_ring *, struct ena_com_rx_ctx *,
    110   1.1  jdolecek     struct mbuf *);
    111   1.4  jdolecek #endif
    112   1.1  jdolecek static struct mbuf* ena_rx_mbuf(struct ena_ring *, struct ena_com_rx_buf_info *,
    113   1.1  jdolecek     struct ena_com_rx_ctx *, uint16_t *);
    114   1.1  jdolecek static inline void ena_rx_checksum(struct ena_ring *, struct ena_com_rx_ctx *,
    115   1.1  jdolecek     struct mbuf *);
    116   1.4  jdolecek static int	ena_handle_msix(void *);
    117   1.1  jdolecek static int	ena_enable_msix(struct ena_adapter *);
    118   1.1  jdolecek static int	ena_request_mgmnt_irq(struct ena_adapter *);
    119   1.1  jdolecek static int	ena_request_io_irq(struct ena_adapter *);
    120   1.1  jdolecek static void	ena_free_mgmnt_irq(struct ena_adapter *);
    121   1.1  jdolecek static void	ena_free_io_irq(struct ena_adapter *);
    122   1.1  jdolecek static void	ena_free_irqs(struct ena_adapter*);
    123   1.1  jdolecek static void	ena_disable_msix(struct ena_adapter *);
    124   1.1  jdolecek static void	ena_unmask_all_io_irqs(struct ena_adapter *);
    125   1.1  jdolecek static int	ena_rss_configure(struct ena_adapter *);
    126   1.1  jdolecek static int	ena_up_complete(struct ena_adapter *);
    127   1.1  jdolecek static int	ena_up(struct ena_adapter *);
    128   1.1  jdolecek static void	ena_down(struct ena_adapter *);
    129   1.2  jdolecek #if 0
    130   1.2  jdolecek static uint64_t	ena_get_counter(struct ifnet *, ift_counter);
    131   1.2  jdolecek #endif
    132   1.2  jdolecek static int	ena_media_change(struct ifnet *);
    133   1.2  jdolecek static void	ena_media_status(struct ifnet *, struct ifmediareq *);
    134   1.4  jdolecek static int	ena_init(struct ifnet *);
    135   1.2  jdolecek static int	ena_ioctl(struct ifnet *, u_long, void *);
    136   1.1  jdolecek static int	ena_get_dev_offloads(struct ena_com_dev_get_features_ctx *);
    137   1.2  jdolecek static void	ena_update_host_info(struct ena_admin_host_info *, struct ifnet *);
    138   1.1  jdolecek static void	ena_update_hwassist(struct ena_adapter *);
    139   1.1  jdolecek static int	ena_setup_ifnet(device_t, struct ena_adapter *,
    140   1.1  jdolecek     struct ena_com_dev_get_features_ctx *);
    141   1.1  jdolecek static void	ena_tx_csum(struct ena_com_tx_ctx *, struct mbuf *);
    142   1.1  jdolecek static int	ena_check_and_collapse_mbuf(struct ena_ring *tx_ring,
    143   1.1  jdolecek     struct mbuf **mbuf);
    144   1.1  jdolecek static int	ena_xmit_mbuf(struct ena_ring *, struct mbuf **);
    145   1.1  jdolecek static void	ena_start_xmit(struct ena_ring *);
    146   1.2  jdolecek static int	ena_mq_start(struct ifnet *, struct mbuf *);
    147   1.4  jdolecek static void	ena_deferred_mq_start(struct work *, void *);
    148   1.4  jdolecek #if 0
    149   1.2  jdolecek static void	ena_qflush(struct ifnet *);
    150   1.4  jdolecek #endif
    151   1.4  jdolecek static int	ena_calc_io_queue_num(struct pci_attach_args *,
    152   1.4  jdolecek     struct ena_adapter *, struct ena_com_dev_get_features_ctx *);
    153   1.1  jdolecek static int	ena_calc_queue_size(struct ena_adapter *, uint16_t *,
    154   1.1  jdolecek     uint16_t *, struct ena_com_dev_get_features_ctx *);
    155   1.4  jdolecek #if 0
    156   1.1  jdolecek static int	ena_rss_init_default(struct ena_adapter *);
    157   1.1  jdolecek static void	ena_rss_init_default_deferred(void *);
    158   1.4  jdolecek #endif
    159   1.1  jdolecek static void	ena_config_host_info(struct ena_com_dev *);
    160   1.4  jdolecek static void	ena_attach(device_t, device_t, void *);
    161   1.4  jdolecek static int	ena_detach(device_t, int);
    162   1.1  jdolecek static int	ena_device_init(struct ena_adapter *, device_t,
    163   1.1  jdolecek     struct ena_com_dev_get_features_ctx *, int *);
    164   1.1  jdolecek static int	ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *,
    165   1.1  jdolecek     int);
    166   1.1  jdolecek static void ena_update_on_link_change(void *, struct ena_admin_aenq_entry *);
    167   1.1  jdolecek static void	unimplemented_aenq_handler(void *,
    168   1.1  jdolecek     struct ena_admin_aenq_entry *);
    169   1.1  jdolecek static void	ena_timer_service(void *);
    170   1.1  jdolecek 
    171   1.2  jdolecek static const char ena_version[] =
    172   1.2  jdolecek     DEVICE_NAME DRV_MODULE_NAME " v" DRV_MODULE_VERSION;
    173   1.1  jdolecek 
    174   1.2  jdolecek #if 0
    175   1.1  jdolecek static SYSCTL_NODE(_hw, OID_AUTO, ena, CTLFLAG_RD, 0, "ENA driver parameters");
    176   1.2  jdolecek #endif
    177   1.1  jdolecek 
    178   1.1  jdolecek /*
    179   1.1  jdolecek  * Tuneable number of buffers in the buf-ring (drbr)
    180   1.1  jdolecek  */
    181   1.1  jdolecek static int ena_buf_ring_size = 4096;
    182   1.2  jdolecek #if 0
    183   1.1  jdolecek SYSCTL_INT(_hw_ena, OID_AUTO, buf_ring_size, CTLFLAG_RWTUN,
    184   1.1  jdolecek     &ena_buf_ring_size, 0, "Size of the bufring");
    185   1.2  jdolecek #endif
    186   1.1  jdolecek 
    187   1.1  jdolecek /*
    188   1.1  jdolecek  * Logging level for changing verbosity of the output
    189   1.1  jdolecek  */
    190   1.1  jdolecek int ena_log_level = ENA_ALERT | ENA_WARNING;
    191   1.2  jdolecek #if 0
    192   1.1  jdolecek SYSCTL_INT(_hw_ena, OID_AUTO, log_level, CTLFLAG_RWTUN,
    193   1.1  jdolecek     &ena_log_level, 0, "Logging level indicating verbosity of the logs");
    194   1.2  jdolecek #endif
    195   1.1  jdolecek 
    196   1.2  jdolecek static const ena_vendor_info_t ena_vendor_info_array[] = {
    197   1.1  jdolecek     { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_PF, 0},
    198   1.1  jdolecek     { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_LLQ_PF, 0},
    199   1.1  jdolecek     { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_VF, 0},
    200   1.1  jdolecek     { PCI_VENDOR_ID_AMAZON, PCI_DEV_ID_ENA_LLQ_VF, 0},
    201   1.1  jdolecek     /* Last entry */
    202   1.1  jdolecek     { 0, 0, 0 }
    203   1.1  jdolecek };
    204   1.1  jdolecek 
    205   1.1  jdolecek /*
    206   1.1  jdolecek  * Contains pointers to event handlers, e.g. link state chage.
    207   1.1  jdolecek  */
    208   1.1  jdolecek static struct ena_aenq_handlers aenq_handlers;
    209   1.1  jdolecek 
    210   1.1  jdolecek int
    211   1.1  jdolecek ena_dma_alloc(device_t dmadev, bus_size_t size,
    212   1.1  jdolecek     ena_mem_handle_t *dma , int mapflags)
    213   1.1  jdolecek {
    214   1.2  jdolecek 	struct ena_adapter *adapter = device_private(dmadev);
    215   1.1  jdolecek 	uint32_t maxsize;
    216   1.2  jdolecek 	bus_dma_segment_t seg;
    217   1.2  jdolecek 	int error, nsegs;
    218   1.1  jdolecek 
    219   1.1  jdolecek 	maxsize = ((size - 1) / PAGE_SIZE + 1) * PAGE_SIZE;
    220   1.1  jdolecek 
    221   1.2  jdolecek #if 0
    222   1.2  jdolecek 	/* XXX what is this needed for ? */
    223   1.1  jdolecek 	dma_space_addr = ENA_DMA_BIT_MASK(adapter->dma_width);
    224   1.1  jdolecek 	if (unlikely(dma_space_addr == 0))
    225   1.1  jdolecek 		dma_space_addr = BUS_SPACE_MAXADDR;
    226   1.2  jdolecek #endif
    227   1.2  jdolecek 
    228   1.2  jdolecek 	dma->tag = adapter->sc_dmat;
    229   1.1  jdolecek 
    230   1.4  jdolecek         if ((error = bus_dmamap_create(dma->tag, maxsize, 1, maxsize, 0,
    231   1.4  jdolecek             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &dma->map)) != 0) {
    232   1.2  jdolecek 		ena_trace(ENA_ALERT, "bus_dmamap_create(%ju) failed: %d\n",
    233   1.2  jdolecek 		    (uintmax_t)maxsize, error);
    234   1.2  jdolecek                 goto fail_create;
    235   1.2  jdolecek 	}
    236   1.2  jdolecek 
    237   1.2  jdolecek 	error = bus_dmamem_alloc(dma->tag, maxsize, 8, 0, &seg, 1, &nsegs,
    238   1.2  jdolecek 	    BUS_DMA_ALLOCNOW);
    239   1.2  jdolecek 	if (error) {
    240   1.1  jdolecek 		ena_trace(ENA_ALERT, "bus_dmamem_alloc(%ju) failed: %d\n",
    241   1.2  jdolecek 		    (uintmax_t)maxsize, error);
    242   1.2  jdolecek 		goto fail_alloc;
    243   1.2  jdolecek 	}
    244   1.2  jdolecek 
    245   1.2  jdolecek 	error = bus_dmamem_map(dma->tag, &seg, nsegs, maxsize,
    246   1.2  jdolecek 	    &dma->vaddr, BUS_DMA_COHERENT);
    247   1.2  jdolecek 	if (error) {
    248   1.2  jdolecek 		ena_trace(ENA_ALERT, "bus_dmamem_map(%ju) failed: %d\n",
    249   1.2  jdolecek 		    (uintmax_t)maxsize, error);
    250   1.2  jdolecek 		goto fail_map;
    251   1.1  jdolecek 	}
    252   1.2  jdolecek 	memset(dma->vaddr, 0, maxsize);
    253   1.1  jdolecek 
    254   1.1  jdolecek 	error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
    255   1.2  jdolecek 	    maxsize, NULL, mapflags);
    256   1.2  jdolecek 	if (error) {
    257   1.1  jdolecek 		ena_trace(ENA_ALERT, ": bus_dmamap_load failed: %d\n", error);
    258   1.2  jdolecek 		goto fail_load;
    259   1.1  jdolecek 	}
    260   1.2  jdolecek 	dma->paddr = dma->map->dm_segs[0].ds_addr;
    261   1.1  jdolecek 
    262   1.1  jdolecek 	return (0);
    263   1.1  jdolecek 
    264   1.2  jdolecek fail_load:
    265   1.2  jdolecek 	bus_dmamem_unmap(dma->tag, dma->vaddr, maxsize);
    266   1.2  jdolecek fail_map:
    267   1.2  jdolecek 	bus_dmamem_free(dma->tag, &seg, nsegs);
    268   1.2  jdolecek fail_alloc:
    269   1.2  jdolecek 	bus_dmamap_destroy(adapter->sc_dmat, dma->map);
    270   1.2  jdolecek fail_create:
    271   1.1  jdolecek 	return (error);
    272   1.1  jdolecek }
    273   1.1  jdolecek 
    274   1.1  jdolecek static int
    275   1.4  jdolecek ena_allocate_pci_resources(struct pci_attach_args *pa,
    276   1.4  jdolecek     struct ena_adapter *adapter)
    277   1.1  jdolecek {
    278   1.4  jdolecek 	bus_size_t size;
    279   1.1  jdolecek 
    280   1.4  jdolecek 	/*
    281   1.4  jdolecek 	 * Map control/status registers.
    282   1.4  jdolecek 	*/
    283   1.4  jdolecek 	pcireg_t memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, ENA_REG_BAR);
    284   1.4  jdolecek 	if (pci_mapreg_map(pa, ENA_REG_BAR, memtype, 0, &adapter->sc_btag,
    285   1.4  jdolecek 	    &adapter->sc_bhandle, NULL, &size)) {
    286   1.4  jdolecek 		aprint_error(": can't map mem space\n");
    287   1.4  jdolecek 		return ENXIO;
    288   1.1  jdolecek 	}
    289   1.1  jdolecek 
    290   1.1  jdolecek 	return (0);
    291   1.1  jdolecek }
    292   1.1  jdolecek 
    293   1.1  jdolecek static void
    294   1.1  jdolecek ena_free_pci_resources(struct ena_adapter *adapter)
    295   1.1  jdolecek {
    296   1.4  jdolecek 	/* Nothing to do */
    297   1.1  jdolecek }
    298   1.1  jdolecek 
    299   1.1  jdolecek static int
    300   1.2  jdolecek ena_probe(device_t parent, cfdata_t match, void *aux)
    301   1.1  jdolecek {
    302   1.2  jdolecek 	struct pci_attach_args *pa = aux;
    303   1.2  jdolecek 	const ena_vendor_info_t *ent;
    304   1.1  jdolecek 
    305   1.2  jdolecek 	for (int i = 0; i < __arraycount(ena_vendor_info_array); i++) {
    306   1.2  jdolecek 		ent = &ena_vendor_info_array[i];
    307   1.1  jdolecek 
    308   1.2  jdolecek 		if ((PCI_VENDOR(pa->pa_id) == ent->vendor_id) &&
    309   1.2  jdolecek 		    (PCI_PRODUCT(pa->pa_id) == ent->device_id)) {
    310   1.2  jdolecek 			return 1;
    311   1.1  jdolecek 		}
    312   1.1  jdolecek 	}
    313   1.1  jdolecek 
    314   1.2  jdolecek 	return 0;
    315   1.1  jdolecek }
    316   1.1  jdolecek 
    317   1.1  jdolecek static int
    318   1.2  jdolecek ena_change_mtu(struct ifnet *ifp, int new_mtu)
    319   1.1  jdolecek {
    320   1.1  jdolecek 	struct ena_adapter *adapter = if_getsoftc(ifp);
    321   1.1  jdolecek 	int rc;
    322   1.1  jdolecek 
    323   1.1  jdolecek 	if ((new_mtu > adapter->max_mtu) || (new_mtu < ENA_MIN_MTU)) {
    324   1.1  jdolecek 		device_printf(adapter->pdev, "Invalid MTU setting. "
    325   1.1  jdolecek 		    "new_mtu: %d max mtu: %d min mtu: %d\n",
    326   1.1  jdolecek 		    new_mtu, adapter->max_mtu, ENA_MIN_MTU);
    327   1.1  jdolecek 		return (EINVAL);
    328   1.1  jdolecek 	}
    329   1.1  jdolecek 
    330   1.1  jdolecek 	rc = ena_com_set_dev_mtu(adapter->ena_dev, new_mtu);
    331   1.1  jdolecek 	if (likely(rc == 0)) {
    332   1.1  jdolecek 		ena_trace(ENA_DBG, "set MTU to %d\n", new_mtu);
    333   1.1  jdolecek 		if_setmtu(ifp, new_mtu);
    334   1.1  jdolecek 	} else {
    335   1.1  jdolecek 		device_printf(adapter->pdev, "Failed to set MTU to %d\n",
    336   1.1  jdolecek 		    new_mtu);
    337   1.1  jdolecek 	}
    338   1.1  jdolecek 
    339   1.1  jdolecek 	return (rc);
    340   1.1  jdolecek }
    341   1.1  jdolecek 
    342   1.4  jdolecek #define EVCNT_INIT(st, f) \
    343   1.4  jdolecek 	do {								\
    344   1.4  jdolecek 		evcnt_attach_dynamic(&st->f, EVCNT_TYPE_MISC, NULL,	\
    345   1.4  jdolecek 		    st->name, #f);					\
    346   1.4  jdolecek 	} while (0)
    347   1.4  jdolecek 
    348   1.4  jdolecek static inline void
    349   1.4  jdolecek ena_alloc_counters_rx(struct ena_stats_rx *st, int queue)
    350   1.4  jdolecek {
    351   1.4  jdolecek 	snprintf(st->name, sizeof(st->name), "ena rxq%d", queue);
    352   1.4  jdolecek 
    353   1.4  jdolecek 	EVCNT_INIT(st, cnt);
    354   1.4  jdolecek 	EVCNT_INIT(st, bytes);
    355   1.4  jdolecek 	EVCNT_INIT(st, refil_partial);
    356   1.4  jdolecek 	EVCNT_INIT(st, bad_csum);
    357   1.4  jdolecek 	EVCNT_INIT(st, mjum_alloc_fail);
    358   1.4  jdolecek 	EVCNT_INIT(st, mbuf_alloc_fail);
    359   1.4  jdolecek 	EVCNT_INIT(st, dma_mapping_err);
    360   1.4  jdolecek 	EVCNT_INIT(st, bad_desc_num);
    361   1.4  jdolecek 	EVCNT_INIT(st, bad_req_id);
    362   1.4  jdolecek 	EVCNT_INIT(st, empty_rx_ring);
    363   1.4  jdolecek 
    364   1.4  jdolecek 	/* Make sure all code is updated when new fields added */
    365   1.4  jdolecek 	CTASSERT(offsetof(struct ena_stats_rx, empty_rx_ring)
    366   1.4  jdolecek 	    + sizeof(st->empty_rx_ring) == sizeof(*st));
    367   1.4  jdolecek }
    368   1.4  jdolecek 
    369   1.4  jdolecek static inline void
    370   1.4  jdolecek ena_alloc_counters_tx(struct ena_stats_tx *st, int queue)
    371   1.4  jdolecek {
    372   1.4  jdolecek 	snprintf(st->name, sizeof(st->name), "ena txq%d", queue);
    373   1.4  jdolecek 
    374   1.4  jdolecek 	EVCNT_INIT(st, cnt);
    375   1.4  jdolecek 	EVCNT_INIT(st, bytes);
    376   1.4  jdolecek 	EVCNT_INIT(st, prepare_ctx_err);
    377   1.4  jdolecek 	EVCNT_INIT(st, dma_mapping_err);
    378   1.4  jdolecek 	EVCNT_INIT(st, doorbells);
    379   1.4  jdolecek 	EVCNT_INIT(st, missing_tx_comp);
    380   1.4  jdolecek 	EVCNT_INIT(st, bad_req_id);
    381   1.4  jdolecek 	EVCNT_INIT(st, collapse);
    382   1.4  jdolecek 	EVCNT_INIT(st, collapse_err);
    383   1.4  jdolecek 
    384   1.4  jdolecek 	/* Make sure all code is updated when new fields added */
    385   1.4  jdolecek 	CTASSERT(offsetof(struct ena_stats_tx, collapse_err)
    386   1.4  jdolecek 	    + sizeof(st->collapse_err) == sizeof(*st));
    387   1.4  jdolecek }
    388   1.4  jdolecek 
    389   1.1  jdolecek static inline void
    390   1.4  jdolecek ena_alloc_counters_dev(struct ena_stats_dev *st, int queue)
    391   1.1  jdolecek {
    392   1.4  jdolecek 	snprintf(st->name, sizeof(st->name), "ena dev ioq%d", queue);
    393   1.1  jdolecek 
    394   1.4  jdolecek 	EVCNT_INIT(st, wd_expired);
    395   1.4  jdolecek 	EVCNT_INIT(st, interface_up);
    396   1.4  jdolecek 	EVCNT_INIT(st, interface_down);
    397   1.4  jdolecek 	EVCNT_INIT(st, admin_q_pause);
    398   1.4  jdolecek 
    399   1.4  jdolecek 	/* Make sure all code is updated when new fields added */
    400   1.4  jdolecek 	CTASSERT(offsetof(struct ena_stats_dev, admin_q_pause)
    401   1.4  jdolecek 	    + sizeof(st->admin_q_pause) == sizeof(*st));
    402   1.1  jdolecek }
    403   1.1  jdolecek 
    404   1.1  jdolecek static inline void
    405   1.4  jdolecek ena_alloc_counters_hwstats(struct ena_hw_stats *st, int queue)
    406   1.4  jdolecek {
    407   1.4  jdolecek 	snprintf(st->name, sizeof(st->name), "ena hw ioq%d", queue);
    408   1.4  jdolecek 
    409   1.4  jdolecek 	EVCNT_INIT(st, rx_packets);
    410   1.4  jdolecek 	EVCNT_INIT(st, tx_packets);
    411   1.4  jdolecek 	EVCNT_INIT(st, rx_bytes);
    412   1.4  jdolecek 	EVCNT_INIT(st, tx_bytes);
    413   1.4  jdolecek 	EVCNT_INIT(st, rx_drops);
    414   1.4  jdolecek 
    415   1.4  jdolecek 	/* Make sure all code is updated when new fields added */
    416   1.4  jdolecek 	CTASSERT(offsetof(struct ena_hw_stats, rx_drops)
    417   1.4  jdolecek 	    + sizeof(st->rx_drops) == sizeof(*st));
    418   1.4  jdolecek }
    419   1.4  jdolecek static inline void
    420   1.2  jdolecek ena_free_counters(struct evcnt *begin, int size)
    421   1.1  jdolecek {
    422   1.2  jdolecek 	struct evcnt *end = (struct evcnt *)((char *)begin + size);
    423   1.1  jdolecek 
    424   1.1  jdolecek 	for (; begin < end; ++begin)
    425   1.1  jdolecek 		counter_u64_free(*begin);
    426   1.1  jdolecek }
    427   1.1  jdolecek 
    428   1.1  jdolecek static inline void
    429   1.2  jdolecek ena_reset_counters(struct evcnt *begin, int size)
    430   1.1  jdolecek {
    431   1.2  jdolecek 	struct evcnt *end = (struct evcnt *)((char *)begin + size);
    432   1.1  jdolecek 
    433   1.1  jdolecek 	for (; begin < end; ++begin)
    434   1.1  jdolecek 		counter_u64_zero(*begin);
    435   1.1  jdolecek }
    436   1.1  jdolecek 
    437   1.1  jdolecek static void
    438   1.1  jdolecek ena_init_io_rings_common(struct ena_adapter *adapter, struct ena_ring *ring,
    439   1.1  jdolecek     uint16_t qid)
    440   1.1  jdolecek {
    441   1.1  jdolecek 
    442   1.1  jdolecek 	ring->qid = qid;
    443   1.1  jdolecek 	ring->adapter = adapter;
    444   1.1  jdolecek 	ring->ena_dev = adapter->ena_dev;
    445   1.1  jdolecek }
    446   1.1  jdolecek 
    447   1.1  jdolecek static void
    448   1.1  jdolecek ena_init_io_rings(struct ena_adapter *adapter)
    449   1.1  jdolecek {
    450   1.1  jdolecek 	struct ena_com_dev *ena_dev;
    451   1.1  jdolecek 	struct ena_ring *txr, *rxr;
    452   1.1  jdolecek 	struct ena_que *que;
    453   1.1  jdolecek 	int i;
    454   1.1  jdolecek 
    455   1.1  jdolecek 	ena_dev = adapter->ena_dev;
    456   1.1  jdolecek 
    457   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
    458   1.1  jdolecek 		txr = &adapter->tx_ring[i];
    459   1.1  jdolecek 		rxr = &adapter->rx_ring[i];
    460   1.1  jdolecek 
    461   1.1  jdolecek 		/* TX/RX common ring state */
    462   1.1  jdolecek 		ena_init_io_rings_common(adapter, txr, i);
    463   1.1  jdolecek 		ena_init_io_rings_common(adapter, rxr, i);
    464   1.1  jdolecek 
    465   1.1  jdolecek 		/* TX specific ring state */
    466   1.1  jdolecek 		txr->ring_size = adapter->tx_ring_size;
    467   1.1  jdolecek 		txr->tx_max_header_size = ena_dev->tx_max_header_size;
    468   1.1  jdolecek 		txr->tx_mem_queue_type = ena_dev->tx_mem_queue_type;
    469   1.1  jdolecek 		txr->smoothed_interval =
    470   1.1  jdolecek 		    ena_com_get_nonadaptive_moderation_interval_tx(ena_dev);
    471   1.1  jdolecek 
    472   1.1  jdolecek 		/* Allocate a buf ring */
    473   1.1  jdolecek 		txr->br = buf_ring_alloc(ena_buf_ring_size, M_DEVBUF,
    474   1.1  jdolecek 		    M_WAITOK, &txr->ring_mtx);
    475   1.1  jdolecek 
    476   1.1  jdolecek 		/* Alloc TX statistics. */
    477   1.4  jdolecek 		ena_alloc_counters_tx(&txr->tx_stats, i);
    478   1.1  jdolecek 
    479   1.1  jdolecek 		/* RX specific ring state */
    480   1.1  jdolecek 		rxr->ring_size = adapter->rx_ring_size;
    481   1.1  jdolecek 		rxr->smoothed_interval =
    482   1.1  jdolecek 		    ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
    483   1.1  jdolecek 
    484   1.1  jdolecek 		/* Alloc RX statistics. */
    485   1.4  jdolecek 		ena_alloc_counters_rx(&rxr->rx_stats, i);
    486   1.1  jdolecek 
    487   1.1  jdolecek 		/* Initialize locks */
    488   1.2  jdolecek 		snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
    489   1.2  jdolecek 		    device_xname(adapter->pdev), i);
    490   1.2  jdolecek 		snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)",
    491   1.2  jdolecek 		    device_xname(adapter->pdev), i);
    492   1.1  jdolecek 
    493   1.2  jdolecek 		mutex_init(&txr->ring_mtx, MUTEX_DEFAULT, IPL_NET);
    494   1.2  jdolecek 		mutex_init(&rxr->ring_mtx, MUTEX_DEFAULT, IPL_NET);
    495   1.1  jdolecek 
    496   1.1  jdolecek 		que = &adapter->que[i];
    497   1.1  jdolecek 		que->adapter = adapter;
    498   1.1  jdolecek 		que->id = i;
    499   1.1  jdolecek 		que->tx_ring = txr;
    500   1.1  jdolecek 		que->rx_ring = rxr;
    501   1.1  jdolecek 
    502   1.1  jdolecek 		txr->que = que;
    503   1.1  jdolecek 		rxr->que = que;
    504   1.1  jdolecek 
    505   1.1  jdolecek 		rxr->empty_rx_queue = 0;
    506   1.1  jdolecek 	}
    507   1.1  jdolecek }
    508   1.1  jdolecek 
    509   1.1  jdolecek static void
    510   1.1  jdolecek ena_free_io_ring_resources(struct ena_adapter *adapter, unsigned int qid)
    511   1.1  jdolecek {
    512   1.1  jdolecek 	struct ena_ring *txr = &adapter->tx_ring[qid];
    513   1.1  jdolecek 	struct ena_ring *rxr = &adapter->rx_ring[qid];
    514   1.1  jdolecek 
    515   1.2  jdolecek 	ena_free_counters((struct evcnt *)&txr->tx_stats,
    516   1.1  jdolecek 	    sizeof(txr->tx_stats));
    517   1.2  jdolecek 	ena_free_counters((struct evcnt *)&rxr->rx_stats,
    518   1.1  jdolecek 	    sizeof(rxr->rx_stats));
    519   1.1  jdolecek 
    520   1.1  jdolecek 	ENA_RING_MTX_LOCK(txr);
    521   1.1  jdolecek 	drbr_free(txr->br, M_DEVBUF);
    522   1.1  jdolecek 	ENA_RING_MTX_UNLOCK(txr);
    523   1.1  jdolecek 
    524   1.2  jdolecek 	mutex_destroy(&txr->ring_mtx);
    525   1.2  jdolecek 	mutex_destroy(&rxr->ring_mtx);
    526   1.1  jdolecek }
    527   1.1  jdolecek 
    528   1.1  jdolecek static void
    529   1.1  jdolecek ena_free_all_io_rings_resources(struct ena_adapter *adapter)
    530   1.1  jdolecek {
    531   1.1  jdolecek 	int i;
    532   1.1  jdolecek 
    533   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++)
    534   1.1  jdolecek 		ena_free_io_ring_resources(adapter, i);
    535   1.1  jdolecek 
    536   1.1  jdolecek }
    537   1.1  jdolecek 
    538   1.2  jdolecek #if 0
    539   1.1  jdolecek static int
    540   1.1  jdolecek ena_setup_tx_dma_tag(struct ena_adapter *adapter)
    541   1.1  jdolecek {
    542   1.1  jdolecek 	int ret;
    543   1.1  jdolecek 
    544   1.1  jdolecek 	/* Create DMA tag for Tx buffers */
    545   1.1  jdolecek 	ret = bus_dma_tag_create(bus_get_dma_tag(adapter->pdev),
    546   1.1  jdolecek 	    1, 0,				  /* alignment, bounds 	     */
    547   1.1  jdolecek 	    ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr of excl window  */
    548   1.1  jdolecek 	    BUS_SPACE_MAXADDR, 			  /* highaddr of excl window */
    549   1.1  jdolecek 	    NULL, NULL,				  /* filter, filterarg 	     */
    550   1.1  jdolecek 	    ENA_TSO_MAXSIZE,			  /* maxsize 		     */
    551   1.1  jdolecek 	    adapter->max_tx_sgl_size - 1,	  /* nsegments 		     */
    552   1.1  jdolecek 	    ENA_TSO_MAXSIZE,			  /* maxsegsize 	     */
    553   1.1  jdolecek 	    0,					  /* flags 		     */
    554   1.1  jdolecek 	    NULL,				  /* lockfunc 		     */
    555   1.1  jdolecek 	    NULL,				  /* lockfuncarg 	     */
    556   1.1  jdolecek 	    &adapter->tx_buf_tag);
    557   1.1  jdolecek 
    558   1.1  jdolecek 	return (ret);
    559   1.1  jdolecek }
    560   1.2  jdolecek #endif
    561   1.1  jdolecek 
    562   1.2  jdolecek #if 0
    563   1.1  jdolecek static int
    564   1.1  jdolecek ena_setup_rx_dma_tag(struct ena_adapter *adapter)
    565   1.1  jdolecek {
    566   1.1  jdolecek 	int ret;
    567   1.1  jdolecek 
    568   1.1  jdolecek 	/* Create DMA tag for Rx buffers*/
    569   1.1  jdolecek 	ret = bus_dma_tag_create(bus_get_dma_tag(adapter->pdev), /* parent   */
    570   1.1  jdolecek 	    1, 0,				  /* alignment, bounds 	     */
    571   1.1  jdolecek 	    ENA_DMA_BIT_MASK(adapter->dma_width), /* lowaddr of excl window  */
    572   1.1  jdolecek 	    BUS_SPACE_MAXADDR, 			  /* highaddr of excl window */
    573   1.1  jdolecek 	    NULL, NULL,				  /* filter, filterarg 	     */
    574   1.1  jdolecek 	    MJUM16BYTES,			  /* maxsize 		     */
    575   1.1  jdolecek 	    adapter->max_rx_sgl_size,		  /* nsegments 		     */
    576   1.1  jdolecek 	    MJUM16BYTES,			  /* maxsegsize 	     */
    577   1.1  jdolecek 	    0,					  /* flags 		     */
    578   1.1  jdolecek 	    NULL,				  /* lockfunc 		     */
    579   1.1  jdolecek 	    NULL,				  /* lockarg 		     */
    580   1.1  jdolecek 	    &adapter->rx_buf_tag);
    581   1.1  jdolecek 
    582   1.1  jdolecek 	return (ret);
    583   1.1  jdolecek }
    584   1.2  jdolecek #endif
    585   1.1  jdolecek 
    586   1.1  jdolecek /**
    587   1.1  jdolecek  * ena_setup_tx_resources - allocate Tx resources (Descriptors)
    588   1.1  jdolecek  * @adapter: network interface device structure
    589   1.1  jdolecek  * @qid: queue index
    590   1.1  jdolecek  *
    591   1.1  jdolecek  * Returns 0 on success, otherwise on failure.
    592   1.1  jdolecek  **/
    593   1.1  jdolecek static int
    594   1.1  jdolecek ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
    595   1.1  jdolecek {
    596   1.1  jdolecek 	struct ena_que *que = &adapter->que[qid];
    597   1.1  jdolecek 	struct ena_ring *tx_ring = que->tx_ring;
    598   1.1  jdolecek 	int size, i, err;
    599   1.1  jdolecek #ifdef	RSS
    600   1.1  jdolecek 	cpuset_t cpu_mask;
    601   1.1  jdolecek #endif
    602   1.1  jdolecek 
    603   1.1  jdolecek 	size = sizeof(struct ena_tx_buffer) * tx_ring->ring_size;
    604   1.1  jdolecek 
    605   1.1  jdolecek 	tx_ring->tx_buffer_info = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
    606   1.1  jdolecek 	if (unlikely(tx_ring->tx_buffer_info == NULL))
    607   1.1  jdolecek 		return (ENOMEM);
    608   1.1  jdolecek 
    609   1.1  jdolecek 	size = sizeof(uint16_t) * tx_ring->ring_size;
    610   1.1  jdolecek 	tx_ring->free_tx_ids = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
    611   1.1  jdolecek 	if (unlikely(tx_ring->free_tx_ids == NULL))
    612   1.1  jdolecek 		goto err_buf_info_free;
    613   1.1  jdolecek 
    614   1.1  jdolecek 	/* Req id stack for TX OOO completions */
    615   1.1  jdolecek 	for (i = 0; i < tx_ring->ring_size; i++)
    616   1.1  jdolecek 		tx_ring->free_tx_ids[i] = i;
    617   1.1  jdolecek 
    618   1.1  jdolecek 	/* Reset TX statistics. */
    619   1.2  jdolecek 	ena_reset_counters((struct evcnt *)&tx_ring->tx_stats,
    620   1.1  jdolecek 	    sizeof(tx_ring->tx_stats));
    621   1.1  jdolecek 
    622   1.1  jdolecek 	tx_ring->next_to_use = 0;
    623   1.1  jdolecek 	tx_ring->next_to_clean = 0;
    624   1.1  jdolecek 
    625   1.1  jdolecek 	/* Make sure that drbr is empty */
    626   1.1  jdolecek 	ENA_RING_MTX_LOCK(tx_ring);
    627   1.1  jdolecek 	drbr_flush(adapter->ifp, tx_ring->br);
    628   1.1  jdolecek 	ENA_RING_MTX_UNLOCK(tx_ring);
    629   1.1  jdolecek 
    630   1.1  jdolecek 	/* ... and create the buffer DMA maps */
    631   1.1  jdolecek 	for (i = 0; i < tx_ring->ring_size; i++) {
    632   1.4  jdolecek 		err = bus_dmamap_create(adapter->sc_dmat,
    633   1.4  jdolecek 		    ENA_TSO_MAXSIZE, adapter->max_tx_sgl_size - 1,
    634   1.4  jdolecek 		    ENA_TSO_MAXSIZE, 0, 0,
    635   1.1  jdolecek 		    &tx_ring->tx_buffer_info[i].map);
    636   1.1  jdolecek 		if (unlikely(err != 0)) {
    637   1.1  jdolecek 			ena_trace(ENA_ALERT,
    638   1.1  jdolecek 			     "Unable to create Tx DMA map for buffer %d\n", i);
    639   1.1  jdolecek 			goto err_buf_info_unmap;
    640   1.1  jdolecek 		}
    641   1.1  jdolecek 	}
    642   1.1  jdolecek 
    643   1.4  jdolecek 	/* Allocate workqueues */
    644  1.10  jmcneill 	int rc = workqueue_create(&tx_ring->enqueue_tq, "ena_tx_enq",
    645  1.10  jmcneill 	    ena_deferred_mq_start, tx_ring, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
    646  1.10  jmcneill 	if (unlikely(rc != 0)) {
    647   1.1  jdolecek 		ena_trace(ENA_ALERT,
    648   1.4  jdolecek 		    "Unable to create workqueue for enqueue task\n");
    649   1.1  jdolecek 		i = tx_ring->ring_size;
    650   1.1  jdolecek 		goto err_buf_info_unmap;
    651   1.1  jdolecek 	}
    652   1.1  jdolecek 
    653   1.4  jdolecek #if 0
    654   1.1  jdolecek 	/* RSS set cpu for thread */
    655   1.1  jdolecek #ifdef RSS
    656   1.1  jdolecek 	CPU_SETOF(que->cpu, &cpu_mask);
    657   1.2  jdolecek 	taskqueue_start_threads_cpuset(&tx_ring->enqueue_tq, 1, IPL_NET,
    658   1.1  jdolecek 	    &cpu_mask, "%s tx_ring enq (bucket %d)",
    659   1.2  jdolecek 	    device_xname(adapter->pdev), que->cpu);
    660   1.1  jdolecek #else /* RSS */
    661   1.2  jdolecek 	taskqueue_start_threads(&tx_ring->enqueue_tq, 1, IPL_NET,
    662   1.2  jdolecek 	    "%s txeq %d", device_xname(adapter->pdev), que->cpu);
    663   1.1  jdolecek #endif /* RSS */
    664   1.4  jdolecek #endif
    665   1.1  jdolecek 
    666   1.1  jdolecek 	return (0);
    667   1.1  jdolecek 
    668   1.1  jdolecek err_buf_info_unmap:
    669   1.1  jdolecek 	while (i--) {
    670   1.2  jdolecek 		bus_dmamap_destroy(adapter->sc_dmat,
    671   1.1  jdolecek 		    tx_ring->tx_buffer_info[i].map);
    672   1.1  jdolecek 	}
    673   1.1  jdolecek 	free(tx_ring->free_tx_ids, M_DEVBUF);
    674   1.1  jdolecek 	tx_ring->free_tx_ids = NULL;
    675   1.1  jdolecek err_buf_info_free:
    676   1.1  jdolecek 	free(tx_ring->tx_buffer_info, M_DEVBUF);
    677   1.1  jdolecek 	tx_ring->tx_buffer_info = NULL;
    678   1.1  jdolecek 
    679   1.1  jdolecek 	return (ENOMEM);
    680   1.1  jdolecek }
    681   1.1  jdolecek 
    682   1.1  jdolecek /**
    683   1.1  jdolecek  * ena_free_tx_resources - Free Tx Resources per Queue
    684   1.1  jdolecek  * @adapter: network interface device structure
    685   1.1  jdolecek  * @qid: queue index
    686   1.1  jdolecek  *
    687   1.1  jdolecek  * Free all transmit software resources
    688   1.1  jdolecek  **/
    689   1.1  jdolecek static void
    690   1.1  jdolecek ena_free_tx_resources(struct ena_adapter *adapter, int qid)
    691   1.1  jdolecek {
    692   1.1  jdolecek 	struct ena_ring *tx_ring = &adapter->tx_ring[qid];
    693   1.1  jdolecek 
    694   1.4  jdolecek 	workqueue_wait(tx_ring->enqueue_tq, &tx_ring->enqueue_task);
    695   1.4  jdolecek 	workqueue_destroy(tx_ring->enqueue_tq);
    696   1.4  jdolecek 	tx_ring->enqueue_tq = NULL;
    697   1.1  jdolecek 
    698   1.1  jdolecek 	ENA_RING_MTX_LOCK(tx_ring);
    699   1.1  jdolecek 	/* Flush buffer ring, */
    700   1.1  jdolecek 	drbr_flush(adapter->ifp, tx_ring->br);
    701   1.1  jdolecek 
    702   1.1  jdolecek 	/* Free buffer DMA maps, */
    703   1.1  jdolecek 	for (int i = 0; i < tx_ring->ring_size; i++) {
    704   1.1  jdolecek 		m_freem(tx_ring->tx_buffer_info[i].mbuf);
    705   1.1  jdolecek 		tx_ring->tx_buffer_info[i].mbuf = NULL;
    706   1.2  jdolecek 		bus_dmamap_unload(adapter->sc_dmat,
    707   1.1  jdolecek 		    tx_ring->tx_buffer_info[i].map);
    708   1.2  jdolecek 		bus_dmamap_destroy(adapter->sc_dmat,
    709   1.1  jdolecek 		    tx_ring->tx_buffer_info[i].map);
    710   1.1  jdolecek 	}
    711   1.1  jdolecek 	ENA_RING_MTX_UNLOCK(tx_ring);
    712   1.1  jdolecek 
    713   1.1  jdolecek 	/* And free allocated memory. */
    714   1.1  jdolecek 	free(tx_ring->tx_buffer_info, M_DEVBUF);
    715   1.1  jdolecek 	tx_ring->tx_buffer_info = NULL;
    716   1.1  jdolecek 
    717   1.1  jdolecek 	free(tx_ring->free_tx_ids, M_DEVBUF);
    718   1.1  jdolecek 	tx_ring->free_tx_ids = NULL;
    719   1.1  jdolecek }
    720   1.1  jdolecek 
    721   1.1  jdolecek /**
    722   1.1  jdolecek  * ena_setup_all_tx_resources - allocate all queues Tx resources
    723   1.1  jdolecek  * @adapter: network interface device structure
    724   1.1  jdolecek  *
    725   1.1  jdolecek  * Returns 0 on success, otherwise on failure.
    726   1.1  jdolecek  **/
    727   1.1  jdolecek static int
    728   1.1  jdolecek ena_setup_all_tx_resources(struct ena_adapter *adapter)
    729   1.1  jdolecek {
    730   1.1  jdolecek 	int i, rc;
    731   1.1  jdolecek 
    732   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
    733   1.1  jdolecek 		rc = ena_setup_tx_resources(adapter, i);
    734   1.1  jdolecek 		if (rc != 0) {
    735   1.1  jdolecek 			device_printf(adapter->pdev,
    736   1.1  jdolecek 			    "Allocation for Tx Queue %u failed\n", i);
    737   1.1  jdolecek 			goto err_setup_tx;
    738   1.1  jdolecek 		}
    739   1.1  jdolecek 	}
    740   1.1  jdolecek 
    741   1.1  jdolecek 	return (0);
    742   1.1  jdolecek 
    743   1.1  jdolecek err_setup_tx:
    744   1.1  jdolecek 	/* Rewind the index freeing the rings as we go */
    745   1.1  jdolecek 	while (i--)
    746   1.1  jdolecek 		ena_free_tx_resources(adapter, i);
    747   1.1  jdolecek 	return (rc);
    748   1.1  jdolecek }
    749   1.1  jdolecek 
    750   1.1  jdolecek /**
    751   1.1  jdolecek  * ena_free_all_tx_resources - Free Tx Resources for All Queues
    752   1.1  jdolecek  * @adapter: network interface device structure
    753   1.1  jdolecek  *
    754   1.1  jdolecek  * Free all transmit software resources
    755   1.1  jdolecek  **/
    756   1.1  jdolecek static void
    757   1.1  jdolecek ena_free_all_tx_resources(struct ena_adapter *adapter)
    758   1.1  jdolecek {
    759   1.1  jdolecek 	int i;
    760   1.1  jdolecek 
    761   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++)
    762   1.1  jdolecek 		ena_free_tx_resources(adapter, i);
    763   1.1  jdolecek }
    764   1.1  jdolecek 
    765   1.1  jdolecek static inline int
    766   1.1  jdolecek validate_rx_req_id(struct ena_ring *rx_ring, uint16_t req_id)
    767   1.1  jdolecek {
    768   1.1  jdolecek 	if (likely(req_id < rx_ring->ring_size))
    769   1.1  jdolecek 		return (0);
    770   1.1  jdolecek 
    771   1.1  jdolecek 	device_printf(rx_ring->adapter->pdev, "Invalid rx req_id: %hu\n",
    772   1.1  jdolecek 	    req_id);
    773   1.1  jdolecek 	counter_u64_add(rx_ring->rx_stats.bad_req_id, 1);
    774   1.1  jdolecek 
    775   1.1  jdolecek 	/* Trigger device reset */
    776   1.1  jdolecek 	rx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID;
    777   1.1  jdolecek 	rx_ring->adapter->trigger_reset = true;
    778   1.1  jdolecek 
    779   1.1  jdolecek 	return (EFAULT);
    780   1.1  jdolecek }
    781   1.1  jdolecek 
    782   1.1  jdolecek /**
    783   1.1  jdolecek  * ena_setup_rx_resources - allocate Rx resources (Descriptors)
    784   1.1  jdolecek  * @adapter: network interface device structure
    785   1.1  jdolecek  * @qid: queue index
    786   1.1  jdolecek  *
    787   1.1  jdolecek  * Returns 0 on success, otherwise on failure.
    788   1.1  jdolecek  **/
    789   1.1  jdolecek static int
    790   1.1  jdolecek ena_setup_rx_resources(struct ena_adapter *adapter, unsigned int qid)
    791   1.1  jdolecek {
    792   1.1  jdolecek 	struct ena_que *que = &adapter->que[qid];
    793   1.1  jdolecek 	struct ena_ring *rx_ring = que->rx_ring;
    794   1.1  jdolecek 	int size, err, i;
    795   1.1  jdolecek #ifdef	RSS
    796   1.1  jdolecek 	cpuset_t cpu_mask;
    797   1.1  jdolecek #endif
    798   1.1  jdolecek 
    799   1.1  jdolecek 	size = sizeof(struct ena_rx_buffer) * rx_ring->ring_size;
    800   1.1  jdolecek 
    801   1.1  jdolecek 	/*
    802   1.1  jdolecek 	 * Alloc extra element so in rx path
    803   1.1  jdolecek 	 * we can always prefetch rx_info + 1
    804   1.1  jdolecek 	 */
    805   1.1  jdolecek 	size += sizeof(struct ena_rx_buffer);
    806   1.1  jdolecek 
    807   1.1  jdolecek 	rx_ring->rx_buffer_info = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
    808   1.1  jdolecek 
    809   1.1  jdolecek 	size = sizeof(uint16_t) * rx_ring->ring_size;
    810   1.1  jdolecek 	rx_ring->free_rx_ids = malloc(size, M_DEVBUF, M_WAITOK);
    811   1.1  jdolecek 
    812   1.1  jdolecek 	for (i = 0; i < rx_ring->ring_size; i++)
    813   1.1  jdolecek 		rx_ring->free_rx_ids[i] = i;
    814   1.1  jdolecek 
    815   1.1  jdolecek 	/* Reset RX statistics. */
    816   1.2  jdolecek 	ena_reset_counters((struct evcnt *)&rx_ring->rx_stats,
    817   1.1  jdolecek 	    sizeof(rx_ring->rx_stats));
    818   1.1  jdolecek 
    819   1.1  jdolecek 	rx_ring->next_to_clean = 0;
    820   1.1  jdolecek 	rx_ring->next_to_use = 0;
    821   1.1  jdolecek 
    822   1.1  jdolecek 	/* ... and create the buffer DMA maps */
    823   1.1  jdolecek 	for (i = 0; i < rx_ring->ring_size; i++) {
    824   1.4  jdolecek 		err = bus_dmamap_create(adapter->sc_dmat,
    825   1.4  jdolecek 		    MJUM16BYTES, adapter->max_rx_sgl_size, MJUM16BYTES,
    826   1.4  jdolecek 		    0, 0,
    827   1.1  jdolecek 		    &(rx_ring->rx_buffer_info[i].map));
    828   1.1  jdolecek 		if (err != 0) {
    829   1.1  jdolecek 			ena_trace(ENA_ALERT,
    830   1.1  jdolecek 			    "Unable to create Rx DMA map for buffer %d\n", i);
    831   1.1  jdolecek 			goto err_buf_info_unmap;
    832   1.1  jdolecek 		}
    833   1.1  jdolecek 	}
    834   1.1  jdolecek 
    835   1.2  jdolecek #ifdef LRO
    836   1.1  jdolecek 	/* Create LRO for the ring */
    837   1.1  jdolecek 	if ((adapter->ifp->if_capenable & IFCAP_LRO) != 0) {
    838   1.1  jdolecek 		int err = tcp_lro_init(&rx_ring->lro);
    839   1.1  jdolecek 		if (err != 0) {
    840   1.1  jdolecek 			device_printf(adapter->pdev,
    841   1.1  jdolecek 			    "LRO[%d] Initialization failed!\n", qid);
    842   1.1  jdolecek 		} else {
    843   1.1  jdolecek 			ena_trace(ENA_INFO,
    844   1.1  jdolecek 			    "RX Soft LRO[%d] Initialized\n", qid);
    845   1.1  jdolecek 			rx_ring->lro.ifp = adapter->ifp;
    846   1.1  jdolecek 		}
    847   1.1  jdolecek 	}
    848   1.2  jdolecek #endif
    849   1.1  jdolecek 
    850   1.4  jdolecek 	/* Allocate workqueues */
    851  1.10  jmcneill 	int rc = workqueue_create(&rx_ring->cmpl_tq, "ena_rx_comp",
    852  1.10  jmcneill 	    ena_deferred_rx_cleanup, rx_ring, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
    853   1.4  jdolecek 	if (unlikely(rc != 0)) {
    854   1.4  jdolecek 		ena_trace(ENA_ALERT,
    855   1.4  jdolecek 		    "Unable to create workqueue for RX completion task\n");
    856   1.4  jdolecek 		goto err_buf_info_unmap;
    857   1.4  jdolecek 	}
    858   1.1  jdolecek 
    859   1.4  jdolecek #if 0
    860   1.1  jdolecek 	/* RSS set cpu for thread */
    861   1.1  jdolecek #ifdef RSS
    862   1.1  jdolecek 	CPU_SETOF(que->cpu, &cpu_mask);
    863   1.2  jdolecek 	taskqueue_start_threads_cpuset(&rx_ring->cmpl_tq, 1, IPL_NET, &cpu_mask,
    864   1.1  jdolecek 	    "%s rx_ring cmpl (bucket %d)",
    865   1.2  jdolecek 	    device_xname(adapter->pdev), que->cpu);
    866   1.1  jdolecek #else
    867   1.2  jdolecek 	taskqueue_start_threads(&rx_ring->cmpl_tq, 1, IPL_NET,
    868   1.2  jdolecek 	    "%s rx_ring cmpl %d", device_xname(adapter->pdev), que->cpu);
    869   1.1  jdolecek #endif
    870   1.4  jdolecek #endif
    871   1.1  jdolecek 
    872   1.1  jdolecek 	return (0);
    873   1.1  jdolecek 
    874   1.1  jdolecek err_buf_info_unmap:
    875   1.1  jdolecek 	while (i--) {
    876   1.2  jdolecek 		bus_dmamap_destroy(adapter->sc_dmat,
    877   1.1  jdolecek 		    rx_ring->rx_buffer_info[i].map);
    878   1.1  jdolecek 	}
    879   1.1  jdolecek 
    880   1.1  jdolecek 	free(rx_ring->free_rx_ids, M_DEVBUF);
    881   1.1  jdolecek 	rx_ring->free_rx_ids = NULL;
    882   1.1  jdolecek 	free(rx_ring->rx_buffer_info, M_DEVBUF);
    883   1.1  jdolecek 	rx_ring->rx_buffer_info = NULL;
    884   1.1  jdolecek 	return (ENOMEM);
    885   1.1  jdolecek }
    886   1.1  jdolecek 
    887   1.1  jdolecek /**
    888   1.1  jdolecek  * ena_free_rx_resources - Free Rx Resources
    889   1.1  jdolecek  * @adapter: network interface device structure
    890   1.1  jdolecek  * @qid: queue index
    891   1.1  jdolecek  *
    892   1.1  jdolecek  * Free all receive software resources
    893   1.1  jdolecek  **/
    894   1.1  jdolecek static void
    895   1.1  jdolecek ena_free_rx_resources(struct ena_adapter *adapter, unsigned int qid)
    896   1.1  jdolecek {
    897   1.1  jdolecek 	struct ena_ring *rx_ring = &adapter->rx_ring[qid];
    898   1.1  jdolecek 
    899   1.4  jdolecek 	workqueue_wait(rx_ring->cmpl_tq, &rx_ring->cmpl_task);
    900   1.4  jdolecek 	workqueue_destroy(rx_ring->cmpl_tq);
    901   1.4  jdolecek 	rx_ring->cmpl_tq = NULL;
    902   1.1  jdolecek 
    903   1.1  jdolecek 	/* Free buffer DMA maps, */
    904   1.1  jdolecek 	for (int i = 0; i < rx_ring->ring_size; i++) {
    905   1.1  jdolecek 		m_freem(rx_ring->rx_buffer_info[i].mbuf);
    906   1.1  jdolecek 		rx_ring->rx_buffer_info[i].mbuf = NULL;
    907   1.2  jdolecek 		bus_dmamap_unload(adapter->sc_dmat,
    908   1.1  jdolecek 		    rx_ring->rx_buffer_info[i].map);
    909   1.2  jdolecek 		bus_dmamap_destroy(adapter->sc_dmat,
    910   1.1  jdolecek 		    rx_ring->rx_buffer_info[i].map);
    911   1.1  jdolecek 	}
    912   1.1  jdolecek 
    913   1.2  jdolecek #ifdef LRO
    914   1.1  jdolecek 	/* free LRO resources, */
    915   1.1  jdolecek 	tcp_lro_free(&rx_ring->lro);
    916   1.2  jdolecek #endif
    917   1.1  jdolecek 
    918   1.1  jdolecek 	/* free allocated memory */
    919   1.1  jdolecek 	free(rx_ring->rx_buffer_info, M_DEVBUF);
    920   1.1  jdolecek 	rx_ring->rx_buffer_info = NULL;
    921   1.1  jdolecek 
    922   1.1  jdolecek 	free(rx_ring->free_rx_ids, M_DEVBUF);
    923   1.1  jdolecek 	rx_ring->free_rx_ids = NULL;
    924   1.1  jdolecek }
    925   1.1  jdolecek 
    926   1.1  jdolecek /**
    927   1.1  jdolecek  * ena_setup_all_rx_resources - allocate all queues Rx resources
    928   1.1  jdolecek  * @adapter: network interface device structure
    929   1.1  jdolecek  *
    930   1.1  jdolecek  * Returns 0 on success, otherwise on failure.
    931   1.1  jdolecek  **/
    932   1.1  jdolecek static int
    933   1.1  jdolecek ena_setup_all_rx_resources(struct ena_adapter *adapter)
    934   1.1  jdolecek {
    935   1.1  jdolecek 	int i, rc = 0;
    936   1.1  jdolecek 
    937   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
    938   1.1  jdolecek 		rc = ena_setup_rx_resources(adapter, i);
    939   1.1  jdolecek 		if (rc != 0) {
    940   1.1  jdolecek 			device_printf(adapter->pdev,
    941   1.1  jdolecek 			    "Allocation for Rx Queue %u failed\n", i);
    942   1.1  jdolecek 			goto err_setup_rx;
    943   1.1  jdolecek 		}
    944   1.1  jdolecek 	}
    945   1.1  jdolecek 	return (0);
    946   1.1  jdolecek 
    947   1.1  jdolecek err_setup_rx:
    948   1.1  jdolecek 	/* rewind the index freeing the rings as we go */
    949   1.1  jdolecek 	while (i--)
    950   1.1  jdolecek 		ena_free_rx_resources(adapter, i);
    951   1.1  jdolecek 	return (rc);
    952   1.1  jdolecek }
    953   1.1  jdolecek 
    954   1.1  jdolecek /**
    955   1.1  jdolecek  * ena_free_all_rx_resources - Free Rx resources for all queues
    956   1.1  jdolecek  * @adapter: network interface device structure
    957   1.1  jdolecek  *
    958   1.1  jdolecek  * Free all receive software resources
    959   1.1  jdolecek  **/
    960   1.1  jdolecek static void
    961   1.1  jdolecek ena_free_all_rx_resources(struct ena_adapter *adapter)
    962   1.1  jdolecek {
    963   1.1  jdolecek 	int i;
    964   1.1  jdolecek 
    965   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++)
    966   1.1  jdolecek 		ena_free_rx_resources(adapter, i);
    967   1.1  jdolecek }
    968   1.1  jdolecek 
    969   1.1  jdolecek static inline int
    970   1.1  jdolecek ena_alloc_rx_mbuf(struct ena_adapter *adapter,
    971   1.1  jdolecek     struct ena_ring *rx_ring, struct ena_rx_buffer *rx_info)
    972   1.1  jdolecek {
    973   1.1  jdolecek 	struct ena_com_buf *ena_buf;
    974   1.4  jdolecek 	int error;
    975   1.1  jdolecek 	int mlen;
    976   1.1  jdolecek 
    977   1.1  jdolecek 	/* if previous allocated frag is not used */
    978   1.1  jdolecek 	if (unlikely(rx_info->mbuf != NULL))
    979   1.1  jdolecek 		return (0);
    980   1.1  jdolecek 
    981   1.1  jdolecek 	/* Get mbuf using UMA allocator */
    982   1.1  jdolecek 	rx_info->mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM16BYTES);
    983   1.1  jdolecek 
    984   1.1  jdolecek 	if (unlikely(rx_info->mbuf == NULL)) {
    985   1.1  jdolecek 		counter_u64_add(rx_ring->rx_stats.mjum_alloc_fail, 1);
    986   1.1  jdolecek 		rx_info->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
    987   1.1  jdolecek 		if (unlikely(rx_info->mbuf == NULL)) {
    988   1.1  jdolecek 			counter_u64_add(rx_ring->rx_stats.mbuf_alloc_fail, 1);
    989   1.1  jdolecek 			return (ENOMEM);
    990   1.1  jdolecek 		}
    991   1.1  jdolecek 		mlen = MCLBYTES;
    992   1.1  jdolecek 	} else {
    993   1.1  jdolecek 		mlen = MJUM16BYTES;
    994   1.1  jdolecek 	}
    995   1.1  jdolecek 	/* Set mbuf length*/
    996   1.1  jdolecek 	rx_info->mbuf->m_pkthdr.len = rx_info->mbuf->m_len = mlen;
    997   1.1  jdolecek 
    998   1.1  jdolecek 	/* Map packets for DMA */
    999   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_RSC | ENA_RXPTH,
   1000   1.1  jdolecek 	    "Using tag %p for buffers' DMA mapping, mbuf %p len: %d",
   1001   1.2  jdolecek 	    adapter->sc_dmat,rx_info->mbuf, rx_info->mbuf->m_len);
   1002   1.4  jdolecek 	error = bus_dmamap_load_mbuf(adapter->sc_dmat, rx_info->map,
   1003   1.4  jdolecek 	    rx_info->mbuf, BUS_DMA_NOWAIT);
   1004   1.4  jdolecek 	if (unlikely((error != 0) || (rx_info->map->dm_nsegs != 1))) {
   1005   1.1  jdolecek 		ena_trace(ENA_WARNING, "failed to map mbuf, error: %d, "
   1006   1.4  jdolecek 		    "nsegs: %d\n", error, rx_info->map->dm_nsegs);
   1007   1.1  jdolecek 		counter_u64_add(rx_ring->rx_stats.dma_mapping_err, 1);
   1008   1.1  jdolecek 		goto exit;
   1009   1.1  jdolecek 
   1010   1.1  jdolecek 	}
   1011   1.1  jdolecek 
   1012   1.4  jdolecek 	bus_dmamap_sync(adapter->sc_dmat, rx_info->map, 0,
   1013   1.4  jdolecek 	    rx_info->map->dm_mapsize, BUS_DMASYNC_PREREAD);
   1014   1.1  jdolecek 
   1015   1.1  jdolecek 	ena_buf = &rx_info->ena_buf;
   1016   1.4  jdolecek 	ena_buf->paddr = rx_info->map->dm_segs[0].ds_addr;
   1017   1.1  jdolecek 	ena_buf->len = mlen;
   1018   1.1  jdolecek 
   1019   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_RSC | ENA_RXPTH,
   1020   1.1  jdolecek 	    "ALLOC RX BUF: mbuf %p, rx_info %p, len %d, paddr %#jx\n",
   1021   1.1  jdolecek 	    rx_info->mbuf, rx_info,ena_buf->len, (uintmax_t)ena_buf->paddr);
   1022   1.1  jdolecek 
   1023   1.1  jdolecek 	return (0);
   1024   1.1  jdolecek 
   1025   1.1  jdolecek exit:
   1026   1.1  jdolecek 	m_freem(rx_info->mbuf);
   1027   1.1  jdolecek 	rx_info->mbuf = NULL;
   1028   1.1  jdolecek 	return (EFAULT);
   1029   1.1  jdolecek }
   1030   1.1  jdolecek 
   1031   1.1  jdolecek static void
   1032   1.1  jdolecek ena_free_rx_mbuf(struct ena_adapter *adapter, struct ena_ring *rx_ring,
   1033   1.1  jdolecek     struct ena_rx_buffer *rx_info)
   1034   1.1  jdolecek {
   1035   1.1  jdolecek 
   1036   1.1  jdolecek 	if (rx_info->mbuf == NULL) {
   1037   1.1  jdolecek 		ena_trace(ENA_WARNING, "Trying to free unallocated buffer\n");
   1038   1.1  jdolecek 		return;
   1039   1.1  jdolecek 	}
   1040   1.1  jdolecek 
   1041   1.2  jdolecek 	bus_dmamap_unload(adapter->sc_dmat, rx_info->map);
   1042   1.1  jdolecek 	m_freem(rx_info->mbuf);
   1043   1.1  jdolecek 	rx_info->mbuf = NULL;
   1044   1.1  jdolecek }
   1045   1.1  jdolecek 
   1046   1.1  jdolecek /**
   1047   1.1  jdolecek  * ena_refill_rx_bufs - Refills ring with descriptors
   1048   1.1  jdolecek  * @rx_ring: the ring which we want to feed with free descriptors
   1049   1.1  jdolecek  * @num: number of descriptors to refill
   1050   1.1  jdolecek  * Refills the ring with newly allocated DMA-mapped mbufs for receiving
   1051   1.1  jdolecek  **/
   1052   1.1  jdolecek static int
   1053   1.1  jdolecek ena_refill_rx_bufs(struct ena_ring *rx_ring, uint32_t num)
   1054   1.1  jdolecek {
   1055   1.1  jdolecek 	struct ena_adapter *adapter = rx_ring->adapter;
   1056   1.1  jdolecek 	uint16_t next_to_use, req_id;
   1057   1.1  jdolecek 	uint32_t i;
   1058   1.1  jdolecek 	int rc;
   1059   1.1  jdolecek 
   1060   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_RXPTH | ENA_RSC, "refill qid: %d",
   1061   1.1  jdolecek 	    rx_ring->qid);
   1062   1.1  jdolecek 
   1063   1.1  jdolecek 	next_to_use = rx_ring->next_to_use;
   1064   1.1  jdolecek 
   1065   1.1  jdolecek 	for (i = 0; i < num; i++) {
   1066   1.1  jdolecek 		struct ena_rx_buffer *rx_info;
   1067   1.1  jdolecek 
   1068   1.1  jdolecek 		ena_trace(ENA_DBG | ENA_RXPTH | ENA_RSC,
   1069   1.1  jdolecek 		    "RX buffer - next to use: %d", next_to_use);
   1070   1.1  jdolecek 
   1071   1.1  jdolecek 		req_id = rx_ring->free_rx_ids[next_to_use];
   1072   1.1  jdolecek 		rc = validate_rx_req_id(rx_ring, req_id);
   1073   1.1  jdolecek 		if (unlikely(rc != 0))
   1074   1.1  jdolecek 			break;
   1075   1.1  jdolecek 
   1076   1.1  jdolecek 		rx_info = &rx_ring->rx_buffer_info[req_id];
   1077   1.1  jdolecek 
   1078   1.1  jdolecek 		rc = ena_alloc_rx_mbuf(adapter, rx_ring, rx_info);
   1079   1.1  jdolecek 		if (unlikely(rc != 0)) {
   1080   1.1  jdolecek 			ena_trace(ENA_WARNING,
   1081   1.1  jdolecek 			    "failed to alloc buffer for rx queue %d\n",
   1082   1.1  jdolecek 			    rx_ring->qid);
   1083   1.1  jdolecek 			break;
   1084   1.1  jdolecek 		}
   1085   1.1  jdolecek 		rc = ena_com_add_single_rx_desc(rx_ring->ena_com_io_sq,
   1086   1.1  jdolecek 		    &rx_info->ena_buf, req_id);
   1087   1.1  jdolecek 		if (unlikely(rc != 0)) {
   1088   1.1  jdolecek 			ena_trace(ENA_WARNING,
   1089   1.1  jdolecek 			    "failed to add buffer for rx queue %d\n",
   1090   1.1  jdolecek 			    rx_ring->qid);
   1091   1.1  jdolecek 			break;
   1092   1.1  jdolecek 		}
   1093   1.1  jdolecek 		next_to_use = ENA_RX_RING_IDX_NEXT(next_to_use,
   1094   1.1  jdolecek 		    rx_ring->ring_size);
   1095   1.1  jdolecek 	}
   1096   1.1  jdolecek 
   1097   1.1  jdolecek 	if (unlikely(i < num)) {
   1098   1.1  jdolecek 		counter_u64_add(rx_ring->rx_stats.refil_partial, 1);
   1099   1.1  jdolecek 		ena_trace(ENA_WARNING,
   1100   1.1  jdolecek 		     "refilled rx qid %d with only %d mbufs (from %d)\n",
   1101   1.1  jdolecek 		     rx_ring->qid, i, num);
   1102   1.1  jdolecek 	}
   1103   1.1  jdolecek 
   1104   1.1  jdolecek 	if (likely(i != 0)) {
   1105   1.1  jdolecek 		wmb();
   1106   1.1  jdolecek 		ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
   1107   1.1  jdolecek 	}
   1108   1.1  jdolecek 	rx_ring->next_to_use = next_to_use;
   1109   1.1  jdolecek 	return (i);
   1110   1.1  jdolecek }
   1111   1.1  jdolecek 
   1112   1.1  jdolecek static void
   1113   1.1  jdolecek ena_free_rx_bufs(struct ena_adapter *adapter, unsigned int qid)
   1114   1.1  jdolecek {
   1115   1.1  jdolecek 	struct ena_ring *rx_ring = &adapter->rx_ring[qid];
   1116   1.1  jdolecek 	unsigned int i;
   1117   1.1  jdolecek 
   1118   1.1  jdolecek 	for (i = 0; i < rx_ring->ring_size; i++) {
   1119   1.1  jdolecek 		struct ena_rx_buffer *rx_info = &rx_ring->rx_buffer_info[i];
   1120   1.1  jdolecek 
   1121   1.1  jdolecek 		if (rx_info->mbuf != NULL)
   1122   1.1  jdolecek 			ena_free_rx_mbuf(adapter, rx_ring, rx_info);
   1123   1.1  jdolecek 	}
   1124   1.1  jdolecek }
   1125   1.1  jdolecek 
   1126   1.1  jdolecek /**
   1127   1.1  jdolecek  * ena_refill_all_rx_bufs - allocate all queues Rx buffers
   1128   1.1  jdolecek  * @adapter: network interface device structure
   1129   1.1  jdolecek  *
   1130   1.1  jdolecek  */
   1131   1.1  jdolecek static void
   1132   1.1  jdolecek ena_refill_all_rx_bufs(struct ena_adapter *adapter)
   1133   1.1  jdolecek {
   1134   1.1  jdolecek 	struct ena_ring *rx_ring;
   1135   1.1  jdolecek 	int i, rc, bufs_num;
   1136   1.1  jdolecek 
   1137   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1138   1.1  jdolecek 		rx_ring = &adapter->rx_ring[i];
   1139   1.1  jdolecek 		bufs_num = rx_ring->ring_size - 1;
   1140   1.1  jdolecek 		rc = ena_refill_rx_bufs(rx_ring, bufs_num);
   1141   1.1  jdolecek 
   1142   1.1  jdolecek 		if (unlikely(rc != bufs_num))
   1143   1.1  jdolecek 			ena_trace(ENA_WARNING, "refilling Queue %d failed. "
   1144   1.1  jdolecek 			    "Allocated %d buffers from: %d\n", i, rc, bufs_num);
   1145   1.1  jdolecek 	}
   1146   1.1  jdolecek }
   1147   1.1  jdolecek 
   1148   1.1  jdolecek static void
   1149   1.1  jdolecek ena_free_all_rx_bufs(struct ena_adapter *adapter)
   1150   1.1  jdolecek {
   1151   1.1  jdolecek 	int i;
   1152   1.1  jdolecek 
   1153   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++)
   1154   1.1  jdolecek 		ena_free_rx_bufs(adapter, i);
   1155   1.1  jdolecek }
   1156   1.1  jdolecek 
   1157   1.1  jdolecek /**
   1158   1.1  jdolecek  * ena_free_tx_bufs - Free Tx Buffers per Queue
   1159   1.1  jdolecek  * @adapter: network interface device structure
   1160   1.1  jdolecek  * @qid: queue index
   1161   1.1  jdolecek  **/
   1162   1.1  jdolecek static void
   1163   1.1  jdolecek ena_free_tx_bufs(struct ena_adapter *adapter, unsigned int qid)
   1164   1.1  jdolecek {
   1165   1.1  jdolecek 	bool print_once = true;
   1166   1.1  jdolecek 	struct ena_ring *tx_ring = &adapter->tx_ring[qid];
   1167   1.1  jdolecek 
   1168   1.1  jdolecek 	ENA_RING_MTX_LOCK(tx_ring);
   1169   1.1  jdolecek 	for (int i = 0; i < tx_ring->ring_size; i++) {
   1170   1.1  jdolecek 		struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i];
   1171   1.1  jdolecek 
   1172   1.1  jdolecek 		if (tx_info->mbuf == NULL)
   1173   1.1  jdolecek 			continue;
   1174   1.1  jdolecek 
   1175   1.1  jdolecek 		if (print_once) {
   1176   1.1  jdolecek 			device_printf(adapter->pdev,
   1177   1.1  jdolecek 			    "free uncompleted tx mbuf qid %d idx 0x%x",
   1178   1.1  jdolecek 			    qid, i);
   1179   1.1  jdolecek 			print_once = false;
   1180   1.1  jdolecek 		} else {
   1181   1.1  jdolecek 			ena_trace(ENA_DBG,
   1182   1.1  jdolecek 			    "free uncompleted tx mbuf qid %d idx 0x%x",
   1183   1.1  jdolecek 			     qid, i);
   1184   1.1  jdolecek 		}
   1185   1.1  jdolecek 
   1186   1.2  jdolecek 		bus_dmamap_unload(adapter->sc_dmat, tx_info->map);
   1187   1.1  jdolecek 		m_free(tx_info->mbuf);
   1188   1.1  jdolecek 		tx_info->mbuf = NULL;
   1189   1.1  jdolecek 	}
   1190   1.1  jdolecek 	ENA_RING_MTX_UNLOCK(tx_ring);
   1191   1.1  jdolecek }
   1192   1.1  jdolecek 
   1193   1.1  jdolecek static void
   1194   1.1  jdolecek ena_free_all_tx_bufs(struct ena_adapter *adapter)
   1195   1.1  jdolecek {
   1196   1.1  jdolecek 
   1197   1.1  jdolecek 	for (int i = 0; i < adapter->num_queues; i++)
   1198   1.1  jdolecek 		ena_free_tx_bufs(adapter, i);
   1199   1.1  jdolecek }
   1200   1.1  jdolecek 
   1201   1.1  jdolecek static void
   1202   1.1  jdolecek ena_destroy_all_tx_queues(struct ena_adapter *adapter)
   1203   1.1  jdolecek {
   1204   1.1  jdolecek 	uint16_t ena_qid;
   1205   1.1  jdolecek 	int i;
   1206   1.1  jdolecek 
   1207   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1208   1.1  jdolecek 		ena_qid = ENA_IO_TXQ_IDX(i);
   1209   1.1  jdolecek 		ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
   1210   1.1  jdolecek 	}
   1211   1.1  jdolecek }
   1212   1.1  jdolecek 
   1213   1.1  jdolecek static void
   1214   1.1  jdolecek ena_destroy_all_rx_queues(struct ena_adapter *adapter)
   1215   1.1  jdolecek {
   1216   1.1  jdolecek 	uint16_t ena_qid;
   1217   1.1  jdolecek 	int i;
   1218   1.1  jdolecek 
   1219   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1220   1.1  jdolecek 		ena_qid = ENA_IO_RXQ_IDX(i);
   1221   1.1  jdolecek 		ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
   1222   1.1  jdolecek 	}
   1223   1.1  jdolecek }
   1224   1.1  jdolecek 
   1225   1.1  jdolecek static void
   1226   1.1  jdolecek ena_destroy_all_io_queues(struct ena_adapter *adapter)
   1227   1.1  jdolecek {
   1228   1.1  jdolecek 	ena_destroy_all_tx_queues(adapter);
   1229   1.1  jdolecek 	ena_destroy_all_rx_queues(adapter);
   1230   1.1  jdolecek }
   1231   1.1  jdolecek 
   1232   1.1  jdolecek static inline int
   1233   1.1  jdolecek validate_tx_req_id(struct ena_ring *tx_ring, uint16_t req_id)
   1234   1.1  jdolecek {
   1235   1.1  jdolecek 	struct ena_adapter *adapter = tx_ring->adapter;
   1236   1.1  jdolecek 	struct ena_tx_buffer *tx_info = NULL;
   1237   1.1  jdolecek 
   1238   1.1  jdolecek 	if (likely(req_id < tx_ring->ring_size)) {
   1239   1.1  jdolecek 		tx_info = &tx_ring->tx_buffer_info[req_id];
   1240   1.1  jdolecek 		if (tx_info->mbuf != NULL)
   1241   1.1  jdolecek 			return (0);
   1242   1.1  jdolecek 	}
   1243   1.1  jdolecek 
   1244   1.1  jdolecek 	if (tx_info->mbuf == NULL)
   1245   1.1  jdolecek 		device_printf(adapter->pdev,
   1246   1.1  jdolecek 		    "tx_info doesn't have valid mbuf\n");
   1247   1.1  jdolecek 	else
   1248   1.1  jdolecek 		device_printf(adapter->pdev, "Invalid req_id: %hu\n", req_id);
   1249   1.1  jdolecek 
   1250   1.1  jdolecek 	counter_u64_add(tx_ring->tx_stats.bad_req_id, 1);
   1251   1.1  jdolecek 
   1252   1.1  jdolecek 	return (EFAULT);
   1253   1.1  jdolecek }
   1254   1.1  jdolecek 
   1255   1.1  jdolecek static int
   1256   1.1  jdolecek ena_create_io_queues(struct ena_adapter *adapter)
   1257   1.1  jdolecek {
   1258   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   1259   1.1  jdolecek 	struct ena_com_create_io_ctx ctx;
   1260   1.1  jdolecek 	struct ena_ring *ring;
   1261   1.1  jdolecek 	uint16_t ena_qid;
   1262   1.1  jdolecek 	uint32_t msix_vector;
   1263   1.1  jdolecek 	int rc, i;
   1264   1.1  jdolecek 
   1265   1.1  jdolecek 	/* Create TX queues */
   1266   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1267   1.1  jdolecek 		msix_vector = ENA_IO_IRQ_IDX(i);
   1268   1.1  jdolecek 		ena_qid = ENA_IO_TXQ_IDX(i);
   1269   1.1  jdolecek 		ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
   1270   1.1  jdolecek 		ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
   1271   1.1  jdolecek 		ctx.queue_size = adapter->tx_ring_size;
   1272   1.1  jdolecek 		ctx.msix_vector = msix_vector;
   1273   1.1  jdolecek 		ctx.qid = ena_qid;
   1274   1.1  jdolecek 		rc = ena_com_create_io_queue(ena_dev, &ctx);
   1275   1.1  jdolecek 		if (rc != 0) {
   1276   1.1  jdolecek 			device_printf(adapter->pdev,
   1277   1.1  jdolecek 			    "Failed to create io TX queue #%d rc: %d\n", i, rc);
   1278   1.1  jdolecek 			goto err_tx;
   1279   1.1  jdolecek 		}
   1280   1.1  jdolecek 		ring = &adapter->tx_ring[i];
   1281   1.1  jdolecek 		rc = ena_com_get_io_handlers(ena_dev, ena_qid,
   1282   1.1  jdolecek 		    &ring->ena_com_io_sq,
   1283   1.1  jdolecek 		    &ring->ena_com_io_cq);
   1284   1.1  jdolecek 		if (rc != 0) {
   1285   1.1  jdolecek 			device_printf(adapter->pdev,
   1286   1.1  jdolecek 			    "Failed to get TX queue handlers. TX queue num"
   1287   1.1  jdolecek 			    " %d rc: %d\n", i, rc);
   1288   1.1  jdolecek 			ena_com_destroy_io_queue(ena_dev, ena_qid);
   1289   1.1  jdolecek 			goto err_tx;
   1290   1.1  jdolecek 		}
   1291   1.1  jdolecek 	}
   1292   1.1  jdolecek 
   1293   1.1  jdolecek 	/* Create RX queues */
   1294   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1295   1.1  jdolecek 		msix_vector = ENA_IO_IRQ_IDX(i);
   1296   1.1  jdolecek 		ena_qid = ENA_IO_RXQ_IDX(i);
   1297   1.1  jdolecek 		ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
   1298   1.1  jdolecek 		ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX;
   1299   1.1  jdolecek 		ctx.queue_size = adapter->rx_ring_size;
   1300   1.1  jdolecek 		ctx.msix_vector = msix_vector;
   1301   1.1  jdolecek 		ctx.qid = ena_qid;
   1302   1.1  jdolecek 		rc = ena_com_create_io_queue(ena_dev, &ctx);
   1303   1.1  jdolecek 		if (unlikely(rc != 0)) {
   1304   1.1  jdolecek 			device_printf(adapter->pdev,
   1305   1.1  jdolecek 			    "Failed to create io RX queue[%d] rc: %d\n", i, rc);
   1306   1.1  jdolecek 			goto err_rx;
   1307   1.1  jdolecek 		}
   1308   1.1  jdolecek 
   1309   1.1  jdolecek 		ring = &adapter->rx_ring[i];
   1310   1.1  jdolecek 		rc = ena_com_get_io_handlers(ena_dev, ena_qid,
   1311   1.1  jdolecek 		    &ring->ena_com_io_sq,
   1312   1.1  jdolecek 		    &ring->ena_com_io_cq);
   1313   1.1  jdolecek 		if (unlikely(rc != 0)) {
   1314   1.1  jdolecek 			device_printf(adapter->pdev,
   1315   1.1  jdolecek 			    "Failed to get RX queue handlers. RX queue num"
   1316   1.1  jdolecek 			    " %d rc: %d\n", i, rc);
   1317   1.1  jdolecek 			ena_com_destroy_io_queue(ena_dev, ena_qid);
   1318   1.1  jdolecek 			goto err_rx;
   1319   1.1  jdolecek 		}
   1320   1.1  jdolecek 	}
   1321   1.1  jdolecek 
   1322   1.1  jdolecek 	return (0);
   1323   1.1  jdolecek 
   1324   1.1  jdolecek err_rx:
   1325   1.1  jdolecek 	while (i--)
   1326   1.1  jdolecek 		ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i));
   1327   1.1  jdolecek 	i = adapter->num_queues;
   1328   1.1  jdolecek err_tx:
   1329   1.1  jdolecek 	while (i--)
   1330   1.1  jdolecek 		ena_com_destroy_io_queue(ena_dev, ENA_IO_TXQ_IDX(i));
   1331   1.1  jdolecek 
   1332   1.1  jdolecek 	return (ENXIO);
   1333   1.1  jdolecek }
   1334   1.1  jdolecek 
   1335   1.1  jdolecek /**
   1336   1.1  jdolecek  * ena_tx_cleanup - clear sent packets and corresponding descriptors
   1337   1.1  jdolecek  * @tx_ring: ring for which we want to clean packets
   1338   1.1  jdolecek  *
   1339   1.1  jdolecek  * Once packets are sent, we ask the device in a loop for no longer used
   1340   1.1  jdolecek  * descriptors. We find the related mbuf chain in a map (index in an array)
   1341   1.1  jdolecek  * and free it, then update ring state.
   1342   1.1  jdolecek  * This is performed in "endless" loop, updating ring pointers every
   1343   1.1  jdolecek  * TX_COMMIT. The first check of free descriptor is performed before the actual
   1344   1.1  jdolecek  * loop, then repeated at the loop end.
   1345   1.1  jdolecek  **/
   1346   1.1  jdolecek static int
   1347   1.1  jdolecek ena_tx_cleanup(struct ena_ring *tx_ring)
   1348   1.1  jdolecek {
   1349   1.1  jdolecek 	struct ena_adapter *adapter;
   1350   1.1  jdolecek 	struct ena_com_io_cq* io_cq;
   1351   1.1  jdolecek 	uint16_t next_to_clean;
   1352   1.1  jdolecek 	uint16_t req_id;
   1353   1.1  jdolecek 	uint16_t ena_qid;
   1354   1.1  jdolecek 	unsigned int total_done = 0;
   1355   1.1  jdolecek 	int rc;
   1356   1.1  jdolecek 	int commit = TX_COMMIT;
   1357   1.1  jdolecek 	int budget = TX_BUDGET;
   1358   1.1  jdolecek 	int work_done;
   1359   1.1  jdolecek 
   1360   1.1  jdolecek 	adapter = tx_ring->que->adapter;
   1361   1.1  jdolecek 	ena_qid = ENA_IO_TXQ_IDX(tx_ring->que->id);
   1362   1.1  jdolecek 	io_cq = &adapter->ena_dev->io_cq_queues[ena_qid];
   1363   1.1  jdolecek 	next_to_clean = tx_ring->next_to_clean;
   1364   1.1  jdolecek 
   1365   1.1  jdolecek 	do {
   1366   1.1  jdolecek 		struct ena_tx_buffer *tx_info;
   1367   1.1  jdolecek 		struct mbuf *mbuf;
   1368   1.1  jdolecek 
   1369   1.1  jdolecek 		rc = ena_com_tx_comp_req_id_get(io_cq, &req_id);
   1370   1.1  jdolecek 		if (unlikely(rc != 0))
   1371   1.1  jdolecek 			break;
   1372   1.1  jdolecek 
   1373   1.1  jdolecek 		rc = validate_tx_req_id(tx_ring, req_id);
   1374   1.1  jdolecek 		if (unlikely(rc != 0))
   1375   1.1  jdolecek 			break;
   1376   1.1  jdolecek 
   1377   1.1  jdolecek 		tx_info = &tx_ring->tx_buffer_info[req_id];
   1378   1.1  jdolecek 
   1379   1.1  jdolecek 		mbuf = tx_info->mbuf;
   1380   1.1  jdolecek 
   1381   1.1  jdolecek 		tx_info->mbuf = NULL;
   1382   1.1  jdolecek 		bintime_clear(&tx_info->timestamp);
   1383   1.1  jdolecek 
   1384   1.1  jdolecek 		if (likely(tx_info->num_of_bufs != 0)) {
   1385   1.1  jdolecek 			/* Map is no longer required */
   1386   1.2  jdolecek 			bus_dmamap_unload(adapter->sc_dmat, tx_info->map);
   1387   1.1  jdolecek 		}
   1388   1.1  jdolecek 
   1389   1.1  jdolecek 		ena_trace(ENA_DBG | ENA_TXPTH, "tx: q %d mbuf %p completed",
   1390   1.1  jdolecek 		    tx_ring->qid, mbuf);
   1391   1.1  jdolecek 
   1392   1.1  jdolecek 		m_freem(mbuf);
   1393   1.1  jdolecek 
   1394   1.1  jdolecek 		total_done += tx_info->tx_descs;
   1395   1.1  jdolecek 
   1396   1.1  jdolecek 		tx_ring->free_tx_ids[next_to_clean] = req_id;
   1397   1.1  jdolecek 		next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
   1398   1.1  jdolecek 		    tx_ring->ring_size);
   1399   1.1  jdolecek 
   1400   1.1  jdolecek 		if (unlikely(--commit == 0)) {
   1401   1.1  jdolecek 			commit = TX_COMMIT;
   1402   1.1  jdolecek 			/* update ring state every TX_COMMIT descriptor */
   1403   1.1  jdolecek 			tx_ring->next_to_clean = next_to_clean;
   1404   1.1  jdolecek 			ena_com_comp_ack(
   1405   1.1  jdolecek 			    &adapter->ena_dev->io_sq_queues[ena_qid],
   1406   1.1  jdolecek 			    total_done);
   1407   1.1  jdolecek 			ena_com_update_dev_comp_head(io_cq);
   1408   1.1  jdolecek 			total_done = 0;
   1409   1.1  jdolecek 		}
   1410   1.1  jdolecek 	} while (likely(--budget));
   1411   1.1  jdolecek 
   1412   1.1  jdolecek 	work_done = TX_BUDGET - budget;
   1413   1.1  jdolecek 
   1414   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_TXPTH, "tx: q %d done. total pkts: %d",
   1415   1.1  jdolecek 	tx_ring->qid, work_done);
   1416   1.1  jdolecek 
   1417   1.1  jdolecek 	/* If there is still something to commit update ring state */
   1418   1.1  jdolecek 	if (likely(commit != TX_COMMIT)) {
   1419   1.1  jdolecek 		tx_ring->next_to_clean = next_to_clean;
   1420   1.1  jdolecek 		ena_com_comp_ack(&adapter->ena_dev->io_sq_queues[ena_qid],
   1421   1.1  jdolecek 		    total_done);
   1422   1.1  jdolecek 		ena_com_update_dev_comp_head(io_cq);
   1423   1.1  jdolecek 	}
   1424   1.1  jdolecek 
   1425  1.10  jmcneill 	if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
   1426  1.10  jmcneill 		workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task, NULL);
   1427   1.1  jdolecek 
   1428   1.1  jdolecek 	return (work_done);
   1429   1.1  jdolecek }
   1430   1.1  jdolecek 
   1431   1.4  jdolecek #if 0
   1432   1.1  jdolecek static void
   1433   1.1  jdolecek ena_rx_hash_mbuf(struct ena_ring *rx_ring, struct ena_com_rx_ctx *ena_rx_ctx,
   1434   1.1  jdolecek     struct mbuf *mbuf)
   1435   1.1  jdolecek {
   1436   1.1  jdolecek 	struct ena_adapter *adapter = rx_ring->adapter;
   1437   1.1  jdolecek 
   1438   1.1  jdolecek 	if (likely(adapter->rss_support)) {
   1439   1.1  jdolecek 		mbuf->m_pkthdr.flowid = ena_rx_ctx->hash;
   1440   1.1  jdolecek 
   1441   1.1  jdolecek 		if (ena_rx_ctx->frag &&
   1442   1.1  jdolecek 		    (ena_rx_ctx->l3_proto != ENA_ETH_IO_L3_PROTO_UNKNOWN)) {
   1443   1.1  jdolecek 			M_HASHTYPE_SET(mbuf, M_HASHTYPE_OPAQUE_HASH);
   1444   1.1  jdolecek 			return;
   1445   1.1  jdolecek 		}
   1446   1.1  jdolecek 
   1447   1.1  jdolecek 		switch (ena_rx_ctx->l3_proto) {
   1448   1.1  jdolecek 		case ENA_ETH_IO_L3_PROTO_IPV4:
   1449   1.1  jdolecek 			switch (ena_rx_ctx->l4_proto) {
   1450   1.1  jdolecek 			case ENA_ETH_IO_L4_PROTO_TCP:
   1451   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_TCP_IPV4);
   1452   1.1  jdolecek 				break;
   1453   1.1  jdolecek 			case ENA_ETH_IO_L4_PROTO_UDP:
   1454   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_UDP_IPV4);
   1455   1.1  jdolecek 				break;
   1456   1.1  jdolecek 			default:
   1457   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_IPV4);
   1458   1.1  jdolecek 			}
   1459   1.1  jdolecek 			break;
   1460   1.1  jdolecek 		case ENA_ETH_IO_L3_PROTO_IPV6:
   1461   1.1  jdolecek 			switch (ena_rx_ctx->l4_proto) {
   1462   1.1  jdolecek 			case ENA_ETH_IO_L4_PROTO_TCP:
   1463   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_TCP_IPV6);
   1464   1.1  jdolecek 				break;
   1465   1.1  jdolecek 			case ENA_ETH_IO_L4_PROTO_UDP:
   1466   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_UDP_IPV6);
   1467   1.1  jdolecek 				break;
   1468   1.1  jdolecek 			default:
   1469   1.1  jdolecek 				M_HASHTYPE_SET(mbuf, M_HASHTYPE_RSS_IPV6);
   1470   1.1  jdolecek 			}
   1471   1.1  jdolecek 			break;
   1472   1.1  jdolecek 		case ENA_ETH_IO_L3_PROTO_UNKNOWN:
   1473   1.1  jdolecek 			M_HASHTYPE_SET(mbuf, M_HASHTYPE_NONE);
   1474   1.1  jdolecek 			break;
   1475   1.1  jdolecek 		default:
   1476   1.1  jdolecek 			M_HASHTYPE_SET(mbuf, M_HASHTYPE_OPAQUE_HASH);
   1477   1.1  jdolecek 		}
   1478   1.1  jdolecek 	} else {
   1479   1.1  jdolecek 		mbuf->m_pkthdr.flowid = rx_ring->qid;
   1480   1.1  jdolecek 		M_HASHTYPE_SET(mbuf, M_HASHTYPE_NONE);
   1481   1.1  jdolecek 	}
   1482   1.1  jdolecek }
   1483   1.4  jdolecek #endif
   1484   1.1  jdolecek 
   1485   1.1  jdolecek /**
   1486   1.1  jdolecek  * ena_rx_mbuf - assemble mbuf from descriptors
   1487   1.1  jdolecek  * @rx_ring: ring for which we want to clean packets
   1488   1.1  jdolecek  * @ena_bufs: buffer info
   1489   1.1  jdolecek  * @ena_rx_ctx: metadata for this packet(s)
   1490   1.1  jdolecek  * @next_to_clean: ring pointer, will be updated only upon success
   1491   1.1  jdolecek  *
   1492   1.1  jdolecek  **/
   1493   1.1  jdolecek static struct mbuf*
   1494   1.1  jdolecek ena_rx_mbuf(struct ena_ring *rx_ring, struct ena_com_rx_buf_info *ena_bufs,
   1495   1.1  jdolecek     struct ena_com_rx_ctx *ena_rx_ctx, uint16_t *next_to_clean)
   1496   1.1  jdolecek {
   1497   1.1  jdolecek 	struct mbuf *mbuf;
   1498   1.1  jdolecek 	struct ena_rx_buffer *rx_info;
   1499   1.1  jdolecek 	struct ena_adapter *adapter;
   1500   1.1  jdolecek 	unsigned int descs = ena_rx_ctx->descs;
   1501   1.1  jdolecek 	uint16_t ntc, len, req_id, buf = 0;
   1502   1.1  jdolecek 
   1503   1.1  jdolecek 	ntc = *next_to_clean;
   1504   1.1  jdolecek 	adapter = rx_ring->adapter;
   1505   1.1  jdolecek 	rx_info = &rx_ring->rx_buffer_info[ntc];
   1506   1.1  jdolecek 
   1507   1.1  jdolecek 	if (unlikely(rx_info->mbuf == NULL)) {
   1508   1.1  jdolecek 		device_printf(adapter->pdev, "NULL mbuf in rx_info");
   1509   1.1  jdolecek 		return (NULL);
   1510   1.1  jdolecek 	}
   1511   1.1  jdolecek 
   1512   1.1  jdolecek 	len = ena_bufs[buf].len;
   1513   1.1  jdolecek 	req_id = ena_bufs[buf].req_id;
   1514   1.1  jdolecek 	rx_info = &rx_ring->rx_buffer_info[req_id];
   1515   1.1  jdolecek 
   1516   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_RXPTH, "rx_info %p, mbuf %p, paddr %jx",
   1517   1.1  jdolecek 	    rx_info, rx_info->mbuf, (uintmax_t)rx_info->ena_buf.paddr);
   1518   1.1  jdolecek 
   1519   1.1  jdolecek 	mbuf = rx_info->mbuf;
   1520   1.3      maxv 	KASSERT(mbuf->m_flags & M_PKTHDR);
   1521   1.1  jdolecek 	mbuf->m_pkthdr.len = len;
   1522   1.1  jdolecek 	mbuf->m_len = len;
   1523   1.4  jdolecek 	m_set_rcvif(mbuf, rx_ring->que->adapter->ifp);
   1524   1.1  jdolecek 
   1525   1.1  jdolecek 	/* Fill mbuf with hash key and it's interpretation for optimization */
   1526   1.4  jdolecek #if 0
   1527   1.1  jdolecek 	ena_rx_hash_mbuf(rx_ring, ena_rx_ctx, mbuf);
   1528   1.4  jdolecek #endif
   1529   1.1  jdolecek 
   1530   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_RXPTH, "rx mbuf 0x%p, flags=0x%x, len: %d",
   1531   1.1  jdolecek 	    mbuf, mbuf->m_flags, mbuf->m_pkthdr.len);
   1532   1.1  jdolecek 
   1533   1.1  jdolecek 	/* DMA address is not needed anymore, unmap it */
   1534   1.2  jdolecek 	bus_dmamap_unload(rx_ring->adapter->sc_dmat, rx_info->map);
   1535   1.1  jdolecek 
   1536   1.1  jdolecek 	rx_info->mbuf = NULL;
   1537   1.1  jdolecek 	rx_ring->free_rx_ids[ntc] = req_id;
   1538   1.1  jdolecek 	ntc = ENA_RX_RING_IDX_NEXT(ntc, rx_ring->ring_size);
   1539   1.1  jdolecek 
   1540   1.1  jdolecek 	/*
   1541   1.1  jdolecek 	 * While we have more than 1 descriptors for one rcvd packet, append
   1542   1.1  jdolecek 	 * other mbufs to the main one
   1543   1.1  jdolecek 	 */
   1544   1.1  jdolecek 	while (--descs) {
   1545   1.1  jdolecek 		++buf;
   1546   1.1  jdolecek 		len = ena_bufs[buf].len;
   1547   1.1  jdolecek 		req_id = ena_bufs[buf].req_id;
   1548   1.1  jdolecek 		rx_info = &rx_ring->rx_buffer_info[req_id];
   1549   1.1  jdolecek 
   1550   1.1  jdolecek 		if (unlikely(rx_info->mbuf == NULL)) {
   1551   1.1  jdolecek 			device_printf(adapter->pdev, "NULL mbuf in rx_info");
   1552   1.1  jdolecek 			/*
   1553   1.1  jdolecek 			 * If one of the required mbufs was not allocated yet,
   1554   1.1  jdolecek 			 * we can break there.
   1555   1.1  jdolecek 			 * All earlier used descriptors will be reallocated
   1556   1.1  jdolecek 			 * later and not used mbufs can be reused.
   1557   1.1  jdolecek 			 * The next_to_clean pointer will not be updated in case
   1558   1.1  jdolecek 			 * of an error, so caller should advance it manually
   1559   1.1  jdolecek 			 * in error handling routine to keep it up to date
   1560   1.1  jdolecek 			 * with hw ring.
   1561   1.1  jdolecek 			 */
   1562   1.1  jdolecek 			m_freem(mbuf);
   1563   1.1  jdolecek 			return (NULL);
   1564   1.1  jdolecek 		}
   1565   1.1  jdolecek 
   1566   1.1  jdolecek 		if (unlikely(m_append(mbuf, len, rx_info->mbuf->m_data) == 0)) {
   1567   1.1  jdolecek 			counter_u64_add(rx_ring->rx_stats.mbuf_alloc_fail, 1);
   1568   1.1  jdolecek 			ena_trace(ENA_WARNING, "Failed to append Rx mbuf %p",
   1569   1.1  jdolecek 			    mbuf);
   1570   1.1  jdolecek 		}
   1571   1.1  jdolecek 
   1572   1.1  jdolecek 		ena_trace(ENA_DBG | ENA_RXPTH,
   1573   1.1  jdolecek 		    "rx mbuf updated. len %d", mbuf->m_pkthdr.len);
   1574   1.1  jdolecek 
   1575   1.1  jdolecek 		/* Free already appended mbuf, it won't be useful anymore */
   1576   1.2  jdolecek 		bus_dmamap_unload(rx_ring->adapter->sc_dmat, rx_info->map);
   1577   1.1  jdolecek 		m_freem(rx_info->mbuf);
   1578   1.1  jdolecek 		rx_info->mbuf = NULL;
   1579   1.1  jdolecek 
   1580   1.1  jdolecek 		rx_ring->free_rx_ids[ntc] = req_id;
   1581   1.1  jdolecek 		ntc = ENA_RX_RING_IDX_NEXT(ntc, rx_ring->ring_size);
   1582   1.1  jdolecek 	}
   1583   1.1  jdolecek 
   1584   1.1  jdolecek 	*next_to_clean = ntc;
   1585   1.1  jdolecek 
   1586   1.1  jdolecek 	return (mbuf);
   1587   1.1  jdolecek }
   1588   1.1  jdolecek 
   1589   1.1  jdolecek /**
   1590   1.1  jdolecek  * ena_rx_checksum - indicate in mbuf if hw indicated a good cksum
   1591   1.1  jdolecek  **/
   1592   1.1  jdolecek static inline void
   1593   1.1  jdolecek ena_rx_checksum(struct ena_ring *rx_ring, struct ena_com_rx_ctx *ena_rx_ctx,
   1594   1.1  jdolecek     struct mbuf *mbuf)
   1595   1.1  jdolecek {
   1596   1.1  jdolecek 
   1597   1.6       bad 	/* IPv4 */
   1598  1.12       roy 	if (ena_rx_ctx->l3_proto == ENA_ETH_IO_L3_PROTO_IPV4) {
   1599   1.6       bad 		mbuf->m_pkthdr.csum_flags |= M_CSUM_IPv4;
   1600   1.6       bad 		if (ena_rx_ctx->l3_csum_err) {
   1601   1.6       bad 			/* ipv4 checksum error */
   1602   1.6       bad 			mbuf->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
   1603   1.6       bad 			counter_u64_add(rx_ring->rx_stats.bad_csum, 1);
   1604   1.6       bad 			ena_trace(ENA_DBG, "RX IPv4 header checksum error");
   1605   1.6       bad 			return;
   1606   1.6       bad 		}
   1607   1.6       bad 
   1608   1.6       bad 		/*  TCP/UDP */
   1609   1.6       bad 		if ((ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ||
   1610   1.6       bad 		    (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP)) {
   1611   1.6       bad 			mbuf->m_pkthdr.csum_flags |= (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ? M_CSUM_TCPv4 : M_CSUM_UDPv4;
   1612   1.6       bad 			if (ena_rx_ctx->l4_csum_err) {
   1613   1.6       bad 				/* TCP/UDP checksum error */
   1614   1.6       bad 				mbuf->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
   1615   1.6       bad 				counter_u64_add(rx_ring->rx_stats.bad_csum, 1);
   1616   1.6       bad 				ena_trace(ENA_DBG, "RX L4 checksum error");
   1617   1.6       bad 			}
   1618   1.6       bad 		}
   1619   1.1  jdolecek 	}
   1620   1.6       bad 	/* IPv6 */
   1621  1.12       roy 	else if (ena_rx_ctx->l3_proto == ENA_ETH_IO_L3_PROTO_IPV6) {
   1622   1.6       bad 		/*  TCP/UDP */
   1623   1.6       bad 		if ((ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ||
   1624   1.6       bad 		    (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP)) {
   1625   1.6       bad 			mbuf->m_pkthdr.csum_flags |= (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP) ? M_CSUM_TCPv6 : M_CSUM_UDPv6;
   1626   1.6       bad 			if (ena_rx_ctx->l4_csum_err) {
   1627   1.6       bad 				/* TCP/UDP checksum error */
   1628   1.6       bad 				mbuf->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
   1629   1.6       bad 				counter_u64_add(rx_ring->rx_stats.bad_csum, 1);
   1630   1.6       bad 				ena_trace(ENA_DBG, "RX L4 checksum error");
   1631   1.6       bad 			}
   1632   1.1  jdolecek 		}
   1633   1.1  jdolecek 	}
   1634   1.1  jdolecek }
   1635   1.1  jdolecek 
   1636   1.1  jdolecek static void
   1637   1.4  jdolecek ena_deferred_rx_cleanup(struct work *wk, void *arg)
   1638   1.1  jdolecek {
   1639   1.1  jdolecek 	struct ena_ring *rx_ring = arg;
   1640   1.1  jdolecek 	int budget = CLEAN_BUDGET;
   1641   1.1  jdolecek 
   1642  1.10  jmcneill 	atomic_swap_uint(&rx_ring->task_pending, 0);
   1643  1.10  jmcneill 
   1644   1.1  jdolecek 	ENA_RING_MTX_LOCK(rx_ring);
   1645   1.1  jdolecek 	/*
   1646   1.1  jdolecek 	 * If deferred task was executed, perform cleanup of all awaiting
   1647   1.1  jdolecek 	 * descs (or until given budget is depleted to avoid infinite loop).
   1648   1.1  jdolecek 	 */
   1649   1.1  jdolecek 	while (likely(budget--)) {
   1650   1.1  jdolecek 		if (ena_rx_cleanup(rx_ring) == 0)
   1651   1.1  jdolecek 			break;
   1652   1.1  jdolecek 	}
   1653   1.1  jdolecek 	ENA_RING_MTX_UNLOCK(rx_ring);
   1654   1.1  jdolecek }
   1655   1.1  jdolecek 
   1656   1.1  jdolecek /**
   1657   1.1  jdolecek  * ena_rx_cleanup - handle rx irq
   1658   1.1  jdolecek  * @arg: ring for which irq is being handled
   1659   1.1  jdolecek  **/
   1660   1.1  jdolecek static int
   1661   1.1  jdolecek ena_rx_cleanup(struct ena_ring *rx_ring)
   1662   1.1  jdolecek {
   1663   1.1  jdolecek 	struct ena_adapter *adapter;
   1664   1.1  jdolecek 	struct mbuf *mbuf;
   1665   1.1  jdolecek 	struct ena_com_rx_ctx ena_rx_ctx;
   1666   1.1  jdolecek 	struct ena_com_io_cq* io_cq;
   1667   1.1  jdolecek 	struct ena_com_io_sq* io_sq;
   1668   1.2  jdolecek 	struct ifnet *ifp;
   1669   1.1  jdolecek 	uint16_t ena_qid;
   1670   1.1  jdolecek 	uint16_t next_to_clean;
   1671   1.1  jdolecek 	uint32_t refill_required;
   1672   1.1  jdolecek 	uint32_t refill_threshold;
   1673   1.1  jdolecek 	uint32_t do_if_input = 0;
   1674   1.1  jdolecek 	unsigned int qid;
   1675   1.1  jdolecek 	int rc, i;
   1676   1.1  jdolecek 	int budget = RX_BUDGET;
   1677   1.1  jdolecek 
   1678   1.1  jdolecek 	adapter = rx_ring->que->adapter;
   1679   1.1  jdolecek 	ifp = adapter->ifp;
   1680   1.1  jdolecek 	qid = rx_ring->que->id;
   1681   1.1  jdolecek 	ena_qid = ENA_IO_RXQ_IDX(qid);
   1682   1.1  jdolecek 	io_cq = &adapter->ena_dev->io_cq_queues[ena_qid];
   1683   1.1  jdolecek 	io_sq = &adapter->ena_dev->io_sq_queues[ena_qid];
   1684   1.1  jdolecek 	next_to_clean = rx_ring->next_to_clean;
   1685   1.1  jdolecek 
   1686   1.1  jdolecek 	ena_trace(ENA_DBG, "rx: qid %d", qid);
   1687   1.1  jdolecek 
   1688   1.1  jdolecek 	do {
   1689   1.1  jdolecek 		ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
   1690   1.1  jdolecek 		ena_rx_ctx.max_bufs = adapter->max_rx_sgl_size;
   1691   1.1  jdolecek 		ena_rx_ctx.descs = 0;
   1692   1.1  jdolecek 		rc = ena_com_rx_pkt(io_cq, io_sq, &ena_rx_ctx);
   1693   1.1  jdolecek 
   1694   1.1  jdolecek 		if (unlikely(rc != 0))
   1695   1.1  jdolecek 			goto error;
   1696   1.1  jdolecek 
   1697   1.1  jdolecek 		if (unlikely(ena_rx_ctx.descs == 0))
   1698   1.1  jdolecek 			break;
   1699   1.1  jdolecek 
   1700   1.1  jdolecek 		ena_trace(ENA_DBG | ENA_RXPTH, "rx: q %d got packet from ena. "
   1701   1.1  jdolecek 		    "descs #: %d l3 proto %d l4 proto %d hash: %x",
   1702   1.1  jdolecek 		    rx_ring->qid, ena_rx_ctx.descs, ena_rx_ctx.l3_proto,
   1703   1.1  jdolecek 		    ena_rx_ctx.l4_proto, ena_rx_ctx.hash);
   1704   1.1  jdolecek 
   1705   1.1  jdolecek 		/* Receive mbuf from the ring */
   1706   1.1  jdolecek 		mbuf = ena_rx_mbuf(rx_ring, rx_ring->ena_bufs,
   1707   1.1  jdolecek 		    &ena_rx_ctx, &next_to_clean);
   1708   1.1  jdolecek 
   1709   1.1  jdolecek 		/* Exit if we failed to retrieve a buffer */
   1710   1.1  jdolecek 		if (unlikely(mbuf == NULL)) {
   1711   1.1  jdolecek 			for (i = 0; i < ena_rx_ctx.descs; ++i) {
   1712   1.1  jdolecek 				rx_ring->free_rx_ids[next_to_clean] =
   1713   1.1  jdolecek 				    rx_ring->ena_bufs[i].req_id;
   1714   1.1  jdolecek 				next_to_clean =
   1715   1.1  jdolecek 				    ENA_RX_RING_IDX_NEXT(next_to_clean,
   1716   1.1  jdolecek 				    rx_ring->ring_size);
   1717   1.1  jdolecek 
   1718   1.1  jdolecek 			}
   1719   1.1  jdolecek 			break;
   1720   1.1  jdolecek 		}
   1721   1.1  jdolecek 
   1722   1.4  jdolecek 		if (((ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) != 0) ||
   1723   1.4  jdolecek 		    ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) != 0) ||
   1724   1.4  jdolecek 		    ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) != 0) ||
   1725   1.4  jdolecek 		    ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) != 0) ||
   1726   1.4  jdolecek 		    ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) != 0)) {
   1727   1.1  jdolecek 			ena_rx_checksum(rx_ring, &ena_rx_ctx, mbuf);
   1728   1.1  jdolecek 		}
   1729   1.1  jdolecek 
   1730   1.1  jdolecek 		counter_enter();
   1731   1.1  jdolecek 		counter_u64_add_protected(rx_ring->rx_stats.bytes,
   1732   1.1  jdolecek 		    mbuf->m_pkthdr.len);
   1733   1.1  jdolecek 		counter_u64_add_protected(adapter->hw_stats.rx_bytes,
   1734   1.1  jdolecek 		    mbuf->m_pkthdr.len);
   1735   1.1  jdolecek 		counter_exit();
   1736   1.1  jdolecek 		/*
   1737   1.1  jdolecek 		 * LRO is only for IP/TCP packets and TCP checksum of the packet
   1738   1.1  jdolecek 		 * should be computed by hardware.
   1739   1.1  jdolecek 		 */
   1740   1.1  jdolecek 		do_if_input = 1;
   1741  1.11  jmcneill #ifdef LRO
   1742   1.1  jdolecek 		if (((ifp->if_capenable & IFCAP_LRO) != 0)  &&
   1743   1.1  jdolecek 		    ((mbuf->m_pkthdr.csum_flags & CSUM_IP_VALID) != 0) &&
   1744   1.1  jdolecek 		    (ena_rx_ctx.l4_proto == ENA_ETH_IO_L4_PROTO_TCP)) {
   1745   1.1  jdolecek 			/*
   1746   1.1  jdolecek 			 * Send to the stack if:
   1747   1.1  jdolecek 			 *  - LRO not enabled, or
   1748   1.1  jdolecek 			 *  - no LRO resources, or
   1749   1.1  jdolecek 			 *  - lro enqueue fails
   1750   1.1  jdolecek 			 */
   1751   1.1  jdolecek 			if ((rx_ring->lro.lro_cnt != 0) &&
   1752   1.1  jdolecek 			    (tcp_lro_rx(&rx_ring->lro, mbuf, 0) == 0))
   1753   1.1  jdolecek 					do_if_input = 0;
   1754   1.1  jdolecek 		}
   1755  1.11  jmcneill #endif
   1756   1.1  jdolecek 		if (do_if_input != 0) {
   1757   1.1  jdolecek 			ena_trace(ENA_DBG | ENA_RXPTH,
   1758   1.1  jdolecek 			    "calling if_input() with mbuf %p", mbuf);
   1759  1.11  jmcneill 			if_percpuq_enqueue(ifp->if_percpuq, mbuf);
   1760   1.1  jdolecek 		}
   1761   1.1  jdolecek 
   1762   1.1  jdolecek 		counter_enter();
   1763   1.1  jdolecek 		counter_u64_add_protected(rx_ring->rx_stats.cnt, 1);
   1764   1.1  jdolecek 		counter_u64_add_protected(adapter->hw_stats.rx_packets, 1);
   1765   1.1  jdolecek 		counter_exit();
   1766   1.1  jdolecek 	} while (--budget);
   1767   1.1  jdolecek 
   1768   1.1  jdolecek 	rx_ring->next_to_clean = next_to_clean;
   1769   1.1  jdolecek 
   1770   1.1  jdolecek 	refill_required = ena_com_free_desc(io_sq);
   1771   1.1  jdolecek 	refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER;
   1772   1.1  jdolecek 
   1773   1.1  jdolecek 	if (refill_required > refill_threshold) {
   1774   1.1  jdolecek 		ena_com_update_dev_comp_head(rx_ring->ena_com_io_cq);
   1775   1.1  jdolecek 		ena_refill_rx_bufs(rx_ring, refill_required);
   1776   1.1  jdolecek 	}
   1777   1.1  jdolecek 
   1778   1.2  jdolecek #ifdef LRO
   1779   1.1  jdolecek 	tcp_lro_flush_all(&rx_ring->lro);
   1780   1.2  jdolecek #endif
   1781   1.1  jdolecek 
   1782   1.1  jdolecek 	return (RX_BUDGET - budget);
   1783   1.1  jdolecek 
   1784   1.1  jdolecek error:
   1785   1.1  jdolecek 	counter_u64_add(rx_ring->rx_stats.bad_desc_num, 1);
   1786   1.1  jdolecek 	return (RX_BUDGET - budget);
   1787   1.1  jdolecek }
   1788   1.1  jdolecek 
   1789   1.1  jdolecek /*********************************************************************
   1790   1.1  jdolecek  *
   1791   1.1  jdolecek  *  MSIX & Interrupt Service routine
   1792   1.1  jdolecek  *
   1793   1.1  jdolecek  **********************************************************************/
   1794   1.1  jdolecek 
   1795   1.1  jdolecek /**
   1796   1.1  jdolecek  * ena_handle_msix - MSIX Interrupt Handler for admin/async queue
   1797   1.1  jdolecek  * @arg: interrupt number
   1798   1.1  jdolecek  **/
   1799   1.4  jdolecek static int
   1800   1.1  jdolecek ena_intr_msix_mgmnt(void *arg)
   1801   1.1  jdolecek {
   1802   1.1  jdolecek 	struct ena_adapter *adapter = (struct ena_adapter *)arg;
   1803   1.1  jdolecek 
   1804   1.1  jdolecek 	ena_com_admin_q_comp_intr_handler(adapter->ena_dev);
   1805   1.1  jdolecek 	if (likely(adapter->running))
   1806   1.1  jdolecek 		ena_com_aenq_intr_handler(adapter->ena_dev, arg);
   1807   1.4  jdolecek 
   1808   1.4  jdolecek 	return 1;
   1809   1.1  jdolecek }
   1810   1.1  jdolecek 
   1811   1.1  jdolecek /**
   1812   1.1  jdolecek  * ena_handle_msix - MSIX Interrupt Handler for Tx/Rx
   1813   1.1  jdolecek  * @arg: interrupt number
   1814   1.1  jdolecek  **/
   1815   1.4  jdolecek static int
   1816   1.1  jdolecek ena_handle_msix(void *arg)
   1817   1.1  jdolecek {
   1818   1.1  jdolecek 	struct ena_que	*que = arg;
   1819   1.1  jdolecek 	struct ena_adapter *adapter = que->adapter;
   1820   1.2  jdolecek 	struct ifnet *ifp = adapter->ifp;
   1821   1.1  jdolecek 	struct ena_ring *tx_ring;
   1822   1.1  jdolecek 	struct ena_ring *rx_ring;
   1823   1.1  jdolecek 	struct ena_com_io_cq* io_cq;
   1824   1.1  jdolecek 	struct ena_eth_io_intr_reg intr_reg;
   1825   1.1  jdolecek 	int qid, ena_qid;
   1826   1.1  jdolecek 	int txc, rxc, i;
   1827   1.1  jdolecek 
   1828   1.4  jdolecek 	if (unlikely((if_getdrvflags(ifp) & IFF_RUNNING) == 0))
   1829   1.4  jdolecek 		return 0;
   1830   1.1  jdolecek 
   1831   1.1  jdolecek 	ena_trace(ENA_DBG, "MSI-X TX/RX routine");
   1832   1.1  jdolecek 
   1833   1.1  jdolecek 	tx_ring = que->tx_ring;
   1834   1.1  jdolecek 	rx_ring = que->rx_ring;
   1835   1.1  jdolecek 	qid = que->id;
   1836   1.1  jdolecek 	ena_qid = ENA_IO_TXQ_IDX(qid);
   1837   1.1  jdolecek 	io_cq = &adapter->ena_dev->io_cq_queues[ena_qid];
   1838   1.1  jdolecek 
   1839   1.1  jdolecek 	for (i = 0; i < CLEAN_BUDGET; ++i) {
   1840   1.1  jdolecek 		/*
   1841   1.1  jdolecek 		 * If lock cannot be acquired, then deferred cleanup task was
   1842   1.1  jdolecek 		 * being executed and rx ring is being cleaned up in
   1843   1.1  jdolecek 		 * another thread.
   1844   1.1  jdolecek 		 */
   1845   1.1  jdolecek 		if (likely(ENA_RING_MTX_TRYLOCK(rx_ring) != 0)) {
   1846   1.1  jdolecek 			rxc = ena_rx_cleanup(rx_ring);
   1847   1.1  jdolecek 			ENA_RING_MTX_UNLOCK(rx_ring);
   1848   1.1  jdolecek 		} else {
   1849   1.1  jdolecek 			rxc = 0;
   1850   1.1  jdolecek 		}
   1851   1.1  jdolecek 
   1852   1.1  jdolecek 		/* Protection from calling ena_tx_cleanup from ena_start_xmit */
   1853   1.1  jdolecek 		ENA_RING_MTX_LOCK(tx_ring);
   1854   1.1  jdolecek 		txc = ena_tx_cleanup(tx_ring);
   1855   1.1  jdolecek 		ENA_RING_MTX_UNLOCK(tx_ring);
   1856   1.1  jdolecek 
   1857   1.4  jdolecek 		if (unlikely((if_getdrvflags(ifp) & IFF_RUNNING) == 0))
   1858   1.4  jdolecek 			return 0;
   1859   1.1  jdolecek 
   1860   1.1  jdolecek 		if ((txc != TX_BUDGET) && (rxc != RX_BUDGET))
   1861   1.1  jdolecek 		       break;
   1862   1.1  jdolecek 	}
   1863   1.1  jdolecek 
   1864   1.1  jdolecek 	/* Signal that work is done and unmask interrupt */
   1865   1.1  jdolecek 	ena_com_update_intr_reg(&intr_reg,
   1866   1.1  jdolecek 	    RX_IRQ_INTERVAL,
   1867   1.1  jdolecek 	    TX_IRQ_INTERVAL,
   1868   1.1  jdolecek 	    true);
   1869   1.1  jdolecek 	ena_com_unmask_intr(io_cq, &intr_reg);
   1870   1.4  jdolecek 
   1871   1.4  jdolecek 	return 1;
   1872   1.1  jdolecek }
   1873   1.1  jdolecek 
   1874   1.1  jdolecek static int
   1875   1.1  jdolecek ena_enable_msix(struct ena_adapter *adapter)
   1876   1.1  jdolecek {
   1877   1.4  jdolecek 	int msix_req;
   1878   1.4  jdolecek 	int counts[PCI_INTR_TYPE_SIZE];
   1879   1.4  jdolecek 	int max_type;
   1880   1.1  jdolecek 
   1881   1.1  jdolecek 	/* Reserved the max msix vectors we might need */
   1882   1.4  jdolecek 	msix_req = ENA_MAX_MSIX_VEC(adapter->num_queues);
   1883   1.1  jdolecek 
   1884   1.4  jdolecek 	counts[PCI_INTR_TYPE_INTX] = 0;
   1885   1.4  jdolecek 	counts[PCI_INTR_TYPE_MSI] = 0;
   1886   1.4  jdolecek 	counts[PCI_INTR_TYPE_MSIX] = msix_req;
   1887   1.4  jdolecek 	max_type = PCI_INTR_TYPE_MSIX;
   1888   1.4  jdolecek 
   1889   1.4  jdolecek 	if (pci_intr_alloc(&adapter->sc_pa, &adapter->sc_intrs, counts,
   1890   1.4  jdolecek 	    max_type) != 0) {
   1891   1.4  jdolecek 		aprint_error_dev(adapter->pdev,
   1892   1.4  jdolecek 		    "failed to allocate interrupt\n");
   1893   1.7  jdolecek 		return ENOSPC;
   1894   1.7  jdolecek 	}
   1895   1.1  jdolecek 
   1896   1.4  jdolecek 	adapter->sc_nintrs = counts[PCI_INTR_TYPE_MSIX];
   1897   1.1  jdolecek 
   1898   1.4  jdolecek 	if (counts[PCI_INTR_TYPE_MSIX] != msix_req) {
   1899   1.4  jdolecek 		device_printf(adapter->pdev,
   1900   1.4  jdolecek 		    "Enable only %d MSI-x (out of %d), reduce "
   1901   1.4  jdolecek 		    "the number of queues\n", adapter->sc_nintrs, msix_req);
   1902   1.4  jdolecek 		adapter->num_queues = adapter->sc_nintrs - ENA_ADMIN_MSIX_VEC;
   1903   1.1  jdolecek 	}
   1904   1.1  jdolecek 
   1905   1.4  jdolecek 	return 0;
   1906   1.1  jdolecek }
   1907   1.1  jdolecek 
   1908   1.4  jdolecek #if 0
   1909   1.1  jdolecek static void
   1910   1.1  jdolecek ena_setup_io_intr(struct ena_adapter *adapter)
   1911   1.1  jdolecek {
   1912   1.1  jdolecek 	static int last_bind_cpu = -1;
   1913   1.1  jdolecek 	int irq_idx;
   1914   1.1  jdolecek 
   1915   1.1  jdolecek 	for (int i = 0; i < adapter->num_queues; i++) {
   1916   1.1  jdolecek 		irq_idx = ENA_IO_IRQ_IDX(i);
   1917   1.1  jdolecek 
   1918   1.1  jdolecek 		snprintf(adapter->irq_tbl[irq_idx].name, ENA_IRQNAME_SIZE,
   1919   1.2  jdolecek 		    "%s-TxRx-%d", device_xname(adapter->pdev), i);
   1920   1.1  jdolecek 		adapter->irq_tbl[irq_idx].handler = ena_handle_msix;
   1921   1.1  jdolecek 		adapter->irq_tbl[irq_idx].data = &adapter->que[i];
   1922   1.1  jdolecek 		adapter->irq_tbl[irq_idx].vector =
   1923   1.1  jdolecek 		    adapter->msix_entries[irq_idx].vector;
   1924   1.1  jdolecek 		ena_trace(ENA_INFO | ENA_IOQ, "ena_setup_io_intr vector: %d\n",
   1925   1.1  jdolecek 		    adapter->msix_entries[irq_idx].vector);
   1926   1.1  jdolecek #ifdef	RSS
   1927   1.1  jdolecek 		adapter->que[i].cpu = adapter->irq_tbl[irq_idx].cpu =
   1928   1.1  jdolecek 		    rss_getcpu(i % rss_getnumbuckets());
   1929   1.1  jdolecek #else
   1930   1.1  jdolecek 		/*
   1931   1.1  jdolecek 		 * We still want to bind rings to the corresponding cpu
   1932   1.1  jdolecek 		 * using something similar to the RSS round-robin technique.
   1933   1.1  jdolecek 		 */
   1934   1.1  jdolecek 		if (unlikely(last_bind_cpu < 0))
   1935   1.1  jdolecek 			last_bind_cpu = CPU_FIRST();
   1936   1.1  jdolecek 		adapter->que[i].cpu = adapter->irq_tbl[irq_idx].cpu =
   1937   1.1  jdolecek 		    last_bind_cpu;
   1938   1.1  jdolecek 		last_bind_cpu = CPU_NEXT(last_bind_cpu);
   1939   1.1  jdolecek #endif
   1940   1.1  jdolecek 	}
   1941   1.1  jdolecek }
   1942   1.4  jdolecek #endif
   1943   1.1  jdolecek 
   1944   1.1  jdolecek static int
   1945   1.1  jdolecek ena_request_mgmnt_irq(struct ena_adapter *adapter)
   1946   1.1  jdolecek {
   1947   1.4  jdolecek 	const char *intrstr;
   1948   1.4  jdolecek 	char intrbuf[PCI_INTRSTR_LEN];
   1949   1.4  jdolecek 	char intr_xname[INTRDEVNAMEBUF];
   1950   1.4  jdolecek 	pci_chipset_tag_t pc = adapter->sc_pa.pa_pc;
   1951   1.4  jdolecek 	const int irq_slot = ENA_MGMNT_IRQ_IDX;
   1952   1.4  jdolecek 
   1953   1.4  jdolecek 	KASSERT(adapter->sc_intrs != NULL);
   1954   1.4  jdolecek 	KASSERT(adapter->sc_ihs[irq_slot] == NULL);
   1955   1.4  jdolecek 
   1956   1.4  jdolecek 	snprintf(intr_xname, sizeof(intr_xname), "%s mgmnt",
   1957   1.4  jdolecek 	    device_xname(adapter->pdev));
   1958   1.4  jdolecek 	intrstr = pci_intr_string(pc, adapter->sc_intrs[irq_slot],
   1959   1.4  jdolecek 	    intrbuf, sizeof(intrbuf));
   1960   1.1  jdolecek 
   1961   1.4  jdolecek 	adapter->sc_ihs[irq_slot] = pci_intr_establish_xname(
   1962   1.4  jdolecek 	    pc, adapter->sc_intrs[irq_slot],
   1963   1.4  jdolecek 	    IPL_NET, ena_intr_msix_mgmnt, adapter, intr_xname);
   1964   1.1  jdolecek 
   1965   1.4  jdolecek 	if (adapter->sc_ihs[irq_slot] == NULL) {
   1966   1.1  jdolecek 		device_printf(adapter->pdev, "failed to register "
   1967   1.4  jdolecek 		    "interrupt handler for MGMNT irq %s\n",
   1968   1.4  jdolecek 		    intrstr);
   1969   1.4  jdolecek 		return ENOMEM;
   1970   1.1  jdolecek 	}
   1971   1.1  jdolecek 
   1972   1.4  jdolecek 	aprint_normal_dev(adapter->pdev,
   1973   1.4  jdolecek 	    "for MGMNT interrupting at %s\n", intrstr);
   1974   1.1  jdolecek 
   1975   1.4  jdolecek 	return 0;
   1976   1.1  jdolecek }
   1977   1.1  jdolecek 
   1978   1.1  jdolecek static int
   1979   1.1  jdolecek ena_request_io_irq(struct ena_adapter *adapter)
   1980   1.1  jdolecek {
   1981   1.4  jdolecek 	const char *intrstr;
   1982   1.4  jdolecek 	char intrbuf[PCI_INTRSTR_LEN];
   1983   1.4  jdolecek 	char intr_xname[INTRDEVNAMEBUF];
   1984   1.4  jdolecek 	pci_chipset_tag_t pc = adapter->sc_pa.pa_pc;
   1985   1.4  jdolecek 	const int irq_off = ENA_IO_IRQ_FIRST_IDX;
   1986   1.4  jdolecek 	void *vih;
   1987   1.4  jdolecek 	kcpuset_t *affinity;
   1988   1.4  jdolecek 	int i;
   1989   1.4  jdolecek 
   1990   1.4  jdolecek 	KASSERT(adapter->sc_intrs != NULL);
   1991   1.4  jdolecek 
   1992   1.4  jdolecek 	kcpuset_create(&affinity, false);
   1993   1.1  jdolecek 
   1994   1.4  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   1995   1.4  jdolecek 		int irq_slot = i + irq_off;
   1996   1.4  jdolecek 		int affinity_to = (irq_slot) % ncpu;
   1997   1.4  jdolecek 
   1998   1.4  jdolecek 		KASSERT((void *)adapter->sc_intrs[irq_slot] != NULL);
   1999   1.4  jdolecek 		KASSERT(adapter->sc_ihs[irq_slot] == NULL);
   2000   1.1  jdolecek 
   2001   1.4  jdolecek 		snprintf(intr_xname, sizeof(intr_xname), "%s ioq%d",
   2002   1.4  jdolecek 		    device_xname(adapter->pdev), i);
   2003   1.4  jdolecek 		intrstr = pci_intr_string(pc, adapter->sc_intrs[irq_slot],
   2004   1.4  jdolecek 		    intrbuf, sizeof(intrbuf));
   2005   1.1  jdolecek 
   2006   1.4  jdolecek 		vih = pci_intr_establish_xname(adapter->sc_pa.pa_pc,
   2007   1.4  jdolecek 		    adapter->sc_intrs[irq_slot], IPL_NET,
   2008   1.4  jdolecek 		    ena_handle_msix, &adapter->que[i], intr_xname);
   2009   1.1  jdolecek 
   2010   1.4  jdolecek 		if (adapter->sc_ihs[ENA_MGMNT_IRQ_IDX] == NULL) {
   2011   1.4  jdolecek 			device_printf(adapter->pdev, "failed to register "
   2012   1.4  jdolecek 			    "interrupt handler for IO queue %d irq %s\n",
   2013   1.4  jdolecek 			    i, intrstr);
   2014   1.1  jdolecek 			goto err;
   2015   1.1  jdolecek 		}
   2016   1.1  jdolecek 
   2017   1.4  jdolecek 		kcpuset_zero(affinity);
   2018   1.4  jdolecek 		/* Round-robin affinity */
   2019   1.4  jdolecek 		kcpuset_set(affinity, affinity_to);
   2020   1.4  jdolecek 		int error = interrupt_distribute(vih, affinity, NULL);
   2021   1.4  jdolecek 		if (error == 0) {
   2022   1.4  jdolecek 			aprint_normal_dev(adapter->pdev,
   2023   1.4  jdolecek 			    "for IO queue %d interrupting at %s"
   2024   1.4  jdolecek 			    " affinity to %u\n", i, intrstr, affinity_to);
   2025   1.4  jdolecek 		} else {
   2026   1.4  jdolecek 			aprint_normal_dev(adapter->pdev,
   2027   1.4  jdolecek 			    "for IO queue %d interrupting at %s\n", i, intrstr);
   2028   1.1  jdolecek 		}
   2029   1.4  jdolecek 
   2030   1.4  jdolecek 		adapter->sc_ihs[irq_slot] = vih;
   2031   1.1  jdolecek 
   2032   1.1  jdolecek #ifdef	RSS
   2033   1.1  jdolecek 		ena_trace(ENA_INFO, "queue %d - RSS bucket %d\n",
   2034   1.1  jdolecek 		    i - ENA_IO_IRQ_FIRST_IDX, irq->cpu);
   2035   1.1  jdolecek #else
   2036   1.1  jdolecek 		ena_trace(ENA_INFO, "queue %d - cpu %d\n",
   2037   1.4  jdolecek 		    i - ENA_IO_IRQ_FIRST_IDX, affinity_to);
   2038   1.1  jdolecek #endif
   2039   1.1  jdolecek 	}
   2040   1.1  jdolecek 
   2041   1.4  jdolecek 	kcpuset_destroy(affinity);
   2042   1.4  jdolecek 	return 0;
   2043   1.1  jdolecek 
   2044   1.1  jdolecek err:
   2045   1.4  jdolecek 	kcpuset_destroy(affinity);
   2046   1.1  jdolecek 
   2047   1.4  jdolecek 	for (i--; i >= 0; i--) {
   2048  1.13     ryoon #if defined(DEBUG) || defined(DIAGNOSTIC)
   2049   1.4  jdolecek 		int irq_slot = i + irq_off;
   2050  1.13     ryoon #endif
   2051   1.4  jdolecek 		KASSERT(adapter->sc_ihs[irq_slot] != NULL);
   2052   1.4  jdolecek 		pci_intr_disestablish(adapter->sc_pa.pa_pc, adapter->sc_ihs[i]);
   2053   1.4  jdolecek 		adapter->sc_ihs[i] = NULL;
   2054   1.1  jdolecek 	}
   2055   1.1  jdolecek 
   2056   1.4  jdolecek 	return ENOSPC;
   2057   1.1  jdolecek }
   2058   1.1  jdolecek 
   2059   1.1  jdolecek static void
   2060   1.1  jdolecek ena_free_mgmnt_irq(struct ena_adapter *adapter)
   2061   1.1  jdolecek {
   2062   1.4  jdolecek 	const int irq_slot = ENA_MGMNT_IRQ_IDX;
   2063   1.1  jdolecek 
   2064   1.4  jdolecek 	if (adapter->sc_ihs[irq_slot]) {
   2065   1.4  jdolecek 		pci_intr_disestablish(adapter->sc_pa.pa_pc,
   2066   1.4  jdolecek 		    adapter->sc_ihs[irq_slot]);
   2067   1.4  jdolecek 		adapter->sc_ihs[irq_slot] = NULL;
   2068   1.1  jdolecek 	}
   2069   1.1  jdolecek }
   2070   1.1  jdolecek 
   2071   1.1  jdolecek static void
   2072   1.1  jdolecek ena_free_io_irq(struct ena_adapter *adapter)
   2073   1.1  jdolecek {
   2074   1.4  jdolecek 	const int irq_off = ENA_IO_IRQ_FIRST_IDX;
   2075   1.1  jdolecek 
   2076   1.4  jdolecek 	for (int i = 0; i < adapter->num_queues; i++) {
   2077   1.4  jdolecek 		int irq_slot = i + irq_off;
   2078   1.1  jdolecek 
   2079   1.4  jdolecek 		if (adapter->sc_ihs[irq_slot]) {
   2080   1.4  jdolecek 			pci_intr_disestablish(adapter->sc_pa.pa_pc,
   2081   1.4  jdolecek 			    adapter->sc_ihs[i]);
   2082   1.4  jdolecek 			adapter->sc_ihs[i] = NULL;
   2083   1.1  jdolecek 		}
   2084   1.1  jdolecek 	}
   2085   1.1  jdolecek }
   2086   1.1  jdolecek 
   2087   1.1  jdolecek static void
   2088   1.1  jdolecek ena_free_irqs(struct ena_adapter* adapter)
   2089   1.1  jdolecek {
   2090   1.1  jdolecek 
   2091   1.1  jdolecek 	ena_free_io_irq(adapter);
   2092   1.1  jdolecek 	ena_free_mgmnt_irq(adapter);
   2093   1.1  jdolecek 	ena_disable_msix(adapter);
   2094   1.1  jdolecek }
   2095   1.1  jdolecek 
   2096   1.1  jdolecek static void
   2097   1.1  jdolecek ena_disable_msix(struct ena_adapter *adapter)
   2098   1.1  jdolecek {
   2099   1.4  jdolecek 	pci_intr_release(adapter->sc_pa.pa_pc, adapter->sc_intrs,
   2100   1.4  jdolecek 	    adapter->sc_nintrs);
   2101   1.1  jdolecek }
   2102   1.1  jdolecek 
   2103   1.1  jdolecek static void
   2104   1.1  jdolecek ena_unmask_all_io_irqs(struct ena_adapter *adapter)
   2105   1.1  jdolecek {
   2106   1.1  jdolecek 	struct ena_com_io_cq* io_cq;
   2107   1.1  jdolecek 	struct ena_eth_io_intr_reg intr_reg;
   2108   1.1  jdolecek 	uint16_t ena_qid;
   2109   1.1  jdolecek 	int i;
   2110   1.1  jdolecek 
   2111   1.1  jdolecek 	/* Unmask interrupts for all queues */
   2112   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   2113   1.1  jdolecek 		ena_qid = ENA_IO_TXQ_IDX(i);
   2114   1.1  jdolecek 		io_cq = &adapter->ena_dev->io_cq_queues[ena_qid];
   2115   1.1  jdolecek 		ena_com_update_intr_reg(&intr_reg, 0, 0, true);
   2116   1.1  jdolecek 		ena_com_unmask_intr(io_cq, &intr_reg);
   2117   1.1  jdolecek 	}
   2118   1.1  jdolecek }
   2119   1.1  jdolecek 
   2120   1.1  jdolecek /* Configure the Rx forwarding */
   2121   1.1  jdolecek static int
   2122   1.1  jdolecek ena_rss_configure(struct ena_adapter *adapter)
   2123   1.1  jdolecek {
   2124   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   2125   1.1  jdolecek 	int rc;
   2126   1.1  jdolecek 
   2127   1.1  jdolecek 	/* Set indirect table */
   2128   1.1  jdolecek 	rc = ena_com_indirect_table_set(ena_dev);
   2129   1.1  jdolecek 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP)))
   2130   1.1  jdolecek 		return (rc);
   2131   1.1  jdolecek 
   2132   1.1  jdolecek 	/* Configure hash function (if supported) */
   2133   1.1  jdolecek 	rc = ena_com_set_hash_function(ena_dev);
   2134   1.1  jdolecek 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP)))
   2135   1.1  jdolecek 		return (rc);
   2136   1.1  jdolecek 
   2137   1.1  jdolecek 	/* Configure hash inputs (if supported) */
   2138   1.1  jdolecek 	rc = ena_com_set_hash_ctrl(ena_dev);
   2139   1.1  jdolecek 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP)))
   2140   1.1  jdolecek 		return (rc);
   2141   1.1  jdolecek 
   2142   1.1  jdolecek 	return (0);
   2143   1.1  jdolecek }
   2144   1.1  jdolecek 
   2145   1.1  jdolecek static int
   2146   1.1  jdolecek ena_up_complete(struct ena_adapter *adapter)
   2147   1.1  jdolecek {
   2148   1.1  jdolecek 	int rc;
   2149   1.1  jdolecek 
   2150   1.1  jdolecek 	if (likely(adapter->rss_support)) {
   2151   1.1  jdolecek 		rc = ena_rss_configure(adapter);
   2152   1.1  jdolecek 		if (rc != 0)
   2153   1.1  jdolecek 			return (rc);
   2154   1.1  jdolecek 	}
   2155   1.1  jdolecek 
   2156   1.1  jdolecek 	rc = ena_change_mtu(adapter->ifp, adapter->ifp->if_mtu);
   2157   1.1  jdolecek 	if (unlikely(rc != 0))
   2158   1.1  jdolecek 		return (rc);
   2159   1.1  jdolecek 
   2160   1.1  jdolecek 	ena_refill_all_rx_bufs(adapter);
   2161   1.2  jdolecek 	ena_reset_counters((struct evcnt *)&adapter->hw_stats,
   2162   1.1  jdolecek 	    sizeof(adapter->hw_stats));
   2163   1.1  jdolecek 
   2164   1.1  jdolecek 	return (0);
   2165   1.1  jdolecek }
   2166   1.1  jdolecek 
   2167   1.1  jdolecek static int
   2168   1.1  jdolecek ena_up(struct ena_adapter *adapter)
   2169   1.1  jdolecek {
   2170   1.1  jdolecek 	int rc = 0;
   2171   1.1  jdolecek 
   2172   1.4  jdolecek #if 0
   2173   1.1  jdolecek 	if (unlikely(device_is_attached(adapter->pdev) == 0)) {
   2174   1.1  jdolecek 		device_printf(adapter->pdev, "device is not attached!\n");
   2175   1.1  jdolecek 		return (ENXIO);
   2176   1.1  jdolecek 	}
   2177   1.4  jdolecek #endif
   2178   1.1  jdolecek 
   2179   1.1  jdolecek 	if (unlikely(!adapter->running)) {
   2180   1.1  jdolecek 		device_printf(adapter->pdev, "device is not running!\n");
   2181   1.1  jdolecek 		return (ENXIO);
   2182   1.1  jdolecek 	}
   2183   1.1  jdolecek 
   2184   1.1  jdolecek 	if (!adapter->up) {
   2185   1.1  jdolecek 		device_printf(adapter->pdev, "device is going UP\n");
   2186   1.1  jdolecek 
   2187   1.1  jdolecek 		/* setup interrupts for IO queues */
   2188   1.1  jdolecek 		rc = ena_request_io_irq(adapter);
   2189   1.1  jdolecek 		if (unlikely(rc != 0)) {
   2190   1.1  jdolecek 			ena_trace(ENA_ALERT, "err_req_irq");
   2191   1.1  jdolecek 			goto err_req_irq;
   2192   1.1  jdolecek 		}
   2193   1.1  jdolecek 
   2194   1.1  jdolecek 		/* allocate transmit descriptors */
   2195   1.1  jdolecek 		rc = ena_setup_all_tx_resources(adapter);
   2196   1.1  jdolecek 		if (unlikely(rc != 0)) {
   2197   1.1  jdolecek 			ena_trace(ENA_ALERT, "err_setup_tx");
   2198   1.1  jdolecek 			goto err_setup_tx;
   2199   1.1  jdolecek 		}
   2200   1.1  jdolecek 
   2201   1.1  jdolecek 		/* allocate receive descriptors */
   2202   1.1  jdolecek 		rc = ena_setup_all_rx_resources(adapter);
   2203   1.1  jdolecek 		if (unlikely(rc != 0)) {
   2204   1.1  jdolecek 			ena_trace(ENA_ALERT, "err_setup_rx");
   2205   1.1  jdolecek 			goto err_setup_rx;
   2206   1.1  jdolecek 		}
   2207   1.1  jdolecek 
   2208   1.1  jdolecek 		/* create IO queues for Rx & Tx */
   2209   1.1  jdolecek 		rc = ena_create_io_queues(adapter);
   2210   1.1  jdolecek 		if (unlikely(rc != 0)) {
   2211   1.1  jdolecek 			ena_trace(ENA_ALERT,
   2212   1.1  jdolecek 			    "create IO queues failed");
   2213   1.1  jdolecek 			goto err_io_que;
   2214   1.1  jdolecek 		}
   2215   1.1  jdolecek 
   2216   1.1  jdolecek 		if (unlikely(adapter->link_status))
   2217   1.1  jdolecek 			if_link_state_change(adapter->ifp, LINK_STATE_UP);
   2218   1.1  jdolecek 
   2219   1.1  jdolecek 		rc = ena_up_complete(adapter);
   2220   1.1  jdolecek 		if (unlikely(rc != 0))
   2221   1.1  jdolecek 			goto err_up_complete;
   2222   1.1  jdolecek 
   2223   1.1  jdolecek 		counter_u64_add(adapter->dev_stats.interface_up, 1);
   2224   1.1  jdolecek 
   2225   1.1  jdolecek 		ena_update_hwassist(adapter);
   2226   1.1  jdolecek 
   2227   1.4  jdolecek 		if_setdrvflagbits(adapter->ifp, IFF_RUNNING,
   2228   1.4  jdolecek 		    IFF_OACTIVE);
   2229   1.1  jdolecek 
   2230   1.4  jdolecek 		callout_reset(&adapter->timer_service, hz,
   2231   1.4  jdolecek 		    ena_timer_service, (void *)adapter);
   2232   1.1  jdolecek 
   2233   1.1  jdolecek 		adapter->up = true;
   2234   1.1  jdolecek 
   2235   1.1  jdolecek 		ena_unmask_all_io_irqs(adapter);
   2236   1.1  jdolecek 	}
   2237   1.1  jdolecek 
   2238   1.1  jdolecek 	return (0);
   2239   1.1  jdolecek 
   2240   1.1  jdolecek err_up_complete:
   2241   1.1  jdolecek 	ena_destroy_all_io_queues(adapter);
   2242   1.1  jdolecek err_io_que:
   2243   1.1  jdolecek 	ena_free_all_rx_resources(adapter);
   2244   1.1  jdolecek err_setup_rx:
   2245   1.1  jdolecek 	ena_free_all_tx_resources(adapter);
   2246   1.1  jdolecek err_setup_tx:
   2247   1.1  jdolecek 	ena_free_io_irq(adapter);
   2248   1.1  jdolecek err_req_irq:
   2249   1.1  jdolecek 	return (rc);
   2250   1.1  jdolecek }
   2251   1.1  jdolecek 
   2252   1.2  jdolecek #if 0
   2253   1.1  jdolecek static uint64_t
   2254   1.2  jdolecek ena_get_counter(struct ifnet *ifp, ift_counter cnt)
   2255   1.1  jdolecek {
   2256   1.1  jdolecek 	struct ena_adapter *adapter;
   2257   1.1  jdolecek 	struct ena_hw_stats *stats;
   2258   1.1  jdolecek 
   2259   1.1  jdolecek 	adapter = if_getsoftc(ifp);
   2260   1.1  jdolecek 	stats = &adapter->hw_stats;
   2261   1.1  jdolecek 
   2262   1.1  jdolecek 	switch (cnt) {
   2263   1.1  jdolecek 	case IFCOUNTER_IPACKETS:
   2264   1.1  jdolecek 		return (counter_u64_fetch(stats->rx_packets));
   2265   1.1  jdolecek 	case IFCOUNTER_OPACKETS:
   2266   1.1  jdolecek 		return (counter_u64_fetch(stats->tx_packets));
   2267   1.1  jdolecek 	case IFCOUNTER_IBYTES:
   2268   1.1  jdolecek 		return (counter_u64_fetch(stats->rx_bytes));
   2269   1.1  jdolecek 	case IFCOUNTER_OBYTES:
   2270   1.1  jdolecek 		return (counter_u64_fetch(stats->tx_bytes));
   2271   1.1  jdolecek 	case IFCOUNTER_IQDROPS:
   2272   1.1  jdolecek 		return (counter_u64_fetch(stats->rx_drops));
   2273   1.1  jdolecek 	default:
   2274   1.1  jdolecek 		return (if_get_counter_default(ifp, cnt));
   2275   1.1  jdolecek 	}
   2276   1.1  jdolecek }
   2277   1.2  jdolecek #endif
   2278   1.1  jdolecek 
   2279   1.1  jdolecek static int
   2280   1.2  jdolecek ena_media_change(struct ifnet *ifp)
   2281   1.1  jdolecek {
   2282   1.1  jdolecek 	/* Media Change is not supported by firmware */
   2283   1.1  jdolecek 	return (0);
   2284   1.1  jdolecek }
   2285   1.1  jdolecek 
   2286   1.1  jdolecek static void
   2287   1.2  jdolecek ena_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
   2288   1.1  jdolecek {
   2289   1.1  jdolecek 	struct ena_adapter *adapter = if_getsoftc(ifp);
   2290   1.1  jdolecek 	ena_trace(ENA_DBG, "enter");
   2291   1.1  jdolecek 
   2292   1.2  jdolecek 	mutex_enter(&adapter->global_mtx);
   2293   1.1  jdolecek 
   2294   1.1  jdolecek 	ifmr->ifm_status = IFM_AVALID;
   2295   1.1  jdolecek 	ifmr->ifm_active = IFM_ETHER;
   2296   1.1  jdolecek 
   2297   1.1  jdolecek 	if (!adapter->link_status) {
   2298   1.2  jdolecek 		mutex_exit(&adapter->global_mtx);
   2299   1.1  jdolecek 		ena_trace(ENA_INFO, "link_status = false");
   2300   1.1  jdolecek 		return;
   2301   1.1  jdolecek 	}
   2302   1.1  jdolecek 
   2303   1.1  jdolecek 	ifmr->ifm_status |= IFM_ACTIVE;
   2304   1.1  jdolecek 	ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
   2305   1.1  jdolecek 
   2306   1.2  jdolecek 	mutex_exit(&adapter->global_mtx);
   2307   1.1  jdolecek }
   2308   1.1  jdolecek 
   2309   1.4  jdolecek static int
   2310   1.4  jdolecek ena_init(struct ifnet *ifp)
   2311   1.1  jdolecek {
   2312   1.4  jdolecek 	struct ena_adapter *adapter = if_getsoftc(ifp);
   2313   1.1  jdolecek 
   2314   1.1  jdolecek 	if (!adapter->up) {
   2315   1.2  jdolecek 		rw_enter(&adapter->ioctl_sx, RW_WRITER);
   2316   1.1  jdolecek 		ena_up(adapter);
   2317   1.2  jdolecek 		rw_exit(&adapter->ioctl_sx);
   2318   1.1  jdolecek 	}
   2319   1.4  jdolecek 
   2320   1.4  jdolecek 	return 0;
   2321   1.1  jdolecek }
   2322   1.1  jdolecek 
   2323   1.1  jdolecek static int
   2324   1.2  jdolecek ena_ioctl(struct ifnet *ifp, u_long command, void *data)
   2325   1.1  jdolecek {
   2326   1.1  jdolecek 	struct ena_adapter *adapter;
   2327   1.1  jdolecek 	struct ifreq *ifr;
   2328   1.1  jdolecek 	int rc;
   2329   1.1  jdolecek 
   2330   1.1  jdolecek 	adapter = ifp->if_softc;
   2331   1.1  jdolecek 	ifr = (struct ifreq *)data;
   2332   1.1  jdolecek 
   2333   1.1  jdolecek 	/*
   2334   1.1  jdolecek 	 * Acquiring lock to prevent from running up and down routines parallel.
   2335   1.1  jdolecek 	 */
   2336   1.1  jdolecek 	rc = 0;
   2337   1.1  jdolecek 	switch (command) {
   2338   1.1  jdolecek 	case SIOCSIFMTU:
   2339   1.1  jdolecek 		if (ifp->if_mtu == ifr->ifr_mtu)
   2340   1.1  jdolecek 			break;
   2341   1.2  jdolecek 		rw_enter(&adapter->ioctl_sx, RW_WRITER);
   2342   1.1  jdolecek 		ena_down(adapter);
   2343   1.1  jdolecek 
   2344   1.1  jdolecek 		ena_change_mtu(ifp, ifr->ifr_mtu);
   2345   1.1  jdolecek 
   2346   1.1  jdolecek 		rc = ena_up(adapter);
   2347   1.2  jdolecek 		rw_exit(&adapter->ioctl_sx);
   2348   1.1  jdolecek 		break;
   2349   1.1  jdolecek 
   2350   1.1  jdolecek 	case SIOCSIFFLAGS:
   2351   1.1  jdolecek 		if ((ifp->if_flags & IFF_UP) != 0) {
   2352   1.4  jdolecek 			if ((if_getdrvflags(ifp) & IFF_RUNNING) != 0) {
   2353   1.1  jdolecek 				if ((ifp->if_flags & (IFF_PROMISC |
   2354   1.1  jdolecek 				    IFF_ALLMULTI)) != 0) {
   2355   1.1  jdolecek 					device_printf(adapter->pdev,
   2356   1.1  jdolecek 					    "ioctl promisc/allmulti\n");
   2357   1.1  jdolecek 				}
   2358   1.1  jdolecek 			} else {
   2359   1.2  jdolecek 				rw_enter(&adapter->ioctl_sx, RW_WRITER);
   2360   1.1  jdolecek 				rc = ena_up(adapter);
   2361   1.2  jdolecek 				rw_exit(&adapter->ioctl_sx);
   2362   1.1  jdolecek 			}
   2363   1.1  jdolecek 		} else {
   2364   1.4  jdolecek 			if ((if_getdrvflags(ifp) & IFF_RUNNING) != 0) {
   2365   1.2  jdolecek 				rw_enter(&adapter->ioctl_sx, RW_WRITER);
   2366   1.1  jdolecek 				ena_down(adapter);
   2367   1.2  jdolecek 				rw_exit(&adapter->ioctl_sx);
   2368   1.1  jdolecek 			}
   2369   1.1  jdolecek 		}
   2370   1.1  jdolecek 		break;
   2371   1.1  jdolecek 
   2372   1.1  jdolecek 	case SIOCADDMULTI:
   2373   1.1  jdolecek 	case SIOCDELMULTI:
   2374   1.1  jdolecek 		break;
   2375   1.1  jdolecek 
   2376   1.1  jdolecek 	case SIOCSIFMEDIA:
   2377   1.1  jdolecek 	case SIOCGIFMEDIA:
   2378   1.1  jdolecek 		rc = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
   2379   1.1  jdolecek 		break;
   2380   1.1  jdolecek 
   2381   1.1  jdolecek 	case SIOCSIFCAP:
   2382   1.1  jdolecek 		{
   2383   1.4  jdolecek 			struct ifcapreq *ifcr = data;
   2384   1.1  jdolecek 			int reinit = 0;
   2385   1.1  jdolecek 
   2386   1.4  jdolecek 			if (ifcr->ifcr_capenable != ifp->if_capenable) {
   2387   1.4  jdolecek 				ifp->if_capenable = ifcr->ifcr_capenable;
   2388   1.1  jdolecek 				reinit = 1;
   2389   1.1  jdolecek 			}
   2390   1.1  jdolecek 
   2391   1.1  jdolecek 			if ((reinit != 0) &&
   2392   1.4  jdolecek 			    ((if_getdrvflags(ifp) & IFF_RUNNING) != 0)) {
   2393   1.2  jdolecek 				rw_enter(&adapter->ioctl_sx, RW_WRITER);
   2394   1.1  jdolecek 				ena_down(adapter);
   2395   1.1  jdolecek 				rc = ena_up(adapter);
   2396   1.2  jdolecek 				rw_exit(&adapter->ioctl_sx);
   2397   1.1  jdolecek 			}
   2398   1.1  jdolecek 		}
   2399   1.1  jdolecek 
   2400   1.1  jdolecek 		break;
   2401   1.1  jdolecek 	default:
   2402   1.1  jdolecek 		rc = ether_ioctl(ifp, command, data);
   2403   1.1  jdolecek 		break;
   2404   1.1  jdolecek 	}
   2405   1.1  jdolecek 
   2406   1.1  jdolecek 	return (rc);
   2407   1.1  jdolecek }
   2408   1.1  jdolecek 
   2409   1.1  jdolecek static int
   2410   1.1  jdolecek ena_get_dev_offloads(struct ena_com_dev_get_features_ctx *feat)
   2411   1.1  jdolecek {
   2412   1.1  jdolecek 	int caps = 0;
   2413   1.1  jdolecek 
   2414   1.1  jdolecek 	if ((feat->offload.tx &
   2415   1.1  jdolecek 	    (ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK |
   2416   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK |
   2417   1.1  jdolecek 		ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK)) != 0)
   2418   1.4  jdolecek 		caps |= IFCAP_CSUM_IPv4_Tx;
   2419   1.1  jdolecek 
   2420   1.1  jdolecek 	if ((feat->offload.tx &
   2421   1.1  jdolecek 	    (ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK |
   2422   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK)) != 0)
   2423   1.4  jdolecek 		caps |= IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx;
   2424   1.1  jdolecek 
   2425   1.1  jdolecek 	if ((feat->offload.tx &
   2426   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK) != 0)
   2427   1.4  jdolecek 		caps |= IFCAP_TSOv4;
   2428   1.1  jdolecek 
   2429   1.1  jdolecek 	if ((feat->offload.tx &
   2430   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK) != 0)
   2431   1.4  jdolecek 		caps |= IFCAP_TSOv6;
   2432   1.1  jdolecek 
   2433   1.1  jdolecek 	if ((feat->offload.rx_supported &
   2434   1.1  jdolecek 	    (ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK |
   2435   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK)) != 0)
   2436   1.4  jdolecek 		caps |= IFCAP_CSUM_IPv4_Rx;
   2437   1.1  jdolecek 
   2438   1.1  jdolecek 	if ((feat->offload.rx_supported &
   2439   1.1  jdolecek 	    ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK) != 0)
   2440   1.4  jdolecek 		caps |= IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
   2441   1.1  jdolecek 
   2442   1.4  jdolecek 	caps |= IFCAP_LRO;
   2443   1.1  jdolecek 
   2444   1.1  jdolecek 	return (caps);
   2445   1.1  jdolecek }
   2446   1.1  jdolecek 
   2447   1.1  jdolecek static void
   2448   1.2  jdolecek ena_update_host_info(struct ena_admin_host_info *host_info, struct ifnet *ifp)
   2449   1.1  jdolecek {
   2450   1.1  jdolecek 
   2451   1.1  jdolecek 	host_info->supported_network_features[0] =
   2452   1.1  jdolecek 	    (uint32_t)if_getcapabilities(ifp);
   2453   1.1  jdolecek }
   2454   1.1  jdolecek 
   2455   1.1  jdolecek static void
   2456   1.1  jdolecek ena_update_hwassist(struct ena_adapter *adapter)
   2457   1.1  jdolecek {
   2458   1.2  jdolecek 	struct ifnet *ifp = adapter->ifp;
   2459   1.1  jdolecek 	uint32_t feat = adapter->tx_offload_cap;
   2460   1.1  jdolecek 	int cap = if_getcapenable(ifp);
   2461   1.1  jdolecek 	int flags = 0;
   2462   1.1  jdolecek 
   2463   1.1  jdolecek 	if_clearhwassist(ifp);
   2464   1.1  jdolecek 
   2465   1.4  jdolecek 	if ((cap & (IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_UDPv4_Tx))
   2466   1.4  jdolecek 	    != 0) {
   2467   1.1  jdolecek 		if ((feat &
   2468   1.1  jdolecek 		    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK) != 0)
   2469   1.4  jdolecek 			flags |= M_CSUM_IPv4;
   2470   1.1  jdolecek 		if ((feat &
   2471   1.1  jdolecek 		    (ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK |
   2472   1.1  jdolecek 		    ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK)) != 0)
   2473   1.4  jdolecek 			flags |= M_CSUM_TCPv4 | M_CSUM_UDPv4;
   2474   1.1  jdolecek 	}
   2475   1.1  jdolecek 
   2476   1.4  jdolecek 	if ((cap & IFCAP_CSUM_TCPv6_Tx) != 0)
   2477   1.4  jdolecek 		flags |= M_CSUM_TCPv6;
   2478   1.4  jdolecek 
   2479   1.4  jdolecek 	if ((cap & IFCAP_CSUM_UDPv6_Tx) != 0)
   2480   1.4  jdolecek 		flags |= M_CSUM_UDPv6;
   2481   1.1  jdolecek 
   2482   1.4  jdolecek 	if ((cap & IFCAP_TSOv4) != 0)
   2483   1.4  jdolecek 		flags |= M_CSUM_TSOv4;
   2484   1.1  jdolecek 
   2485   1.4  jdolecek 	if ((cap & IFCAP_TSOv6) != 0)
   2486   1.4  jdolecek 		flags |= M_CSUM_TSOv6;
   2487   1.1  jdolecek 
   2488   1.1  jdolecek 	if_sethwassistbits(ifp, flags, 0);
   2489   1.1  jdolecek }
   2490   1.1  jdolecek 
   2491   1.1  jdolecek static int
   2492   1.1  jdolecek ena_setup_ifnet(device_t pdev, struct ena_adapter *adapter,
   2493   1.1  jdolecek     struct ena_com_dev_get_features_ctx *feat)
   2494   1.1  jdolecek {
   2495   1.2  jdolecek 	struct ifnet *ifp;
   2496   1.1  jdolecek 	int caps = 0;
   2497   1.1  jdolecek 
   2498   1.4  jdolecek 	ifp = adapter->ifp = &adapter->sc_ec.ec_if;
   2499   1.1  jdolecek 	if (unlikely(ifp == NULL)) {
   2500   1.1  jdolecek 		ena_trace(ENA_ALERT, "can not allocate ifnet structure\n");
   2501   1.1  jdolecek 		return (ENXIO);
   2502   1.1  jdolecek 	}
   2503  1.11  jmcneill 	if_initname(ifp, "ena", device_unit(pdev));
   2504   1.1  jdolecek 	if_setdev(ifp, pdev);
   2505   1.1  jdolecek 	if_setsoftc(ifp, adapter);
   2506   1.1  jdolecek 
   2507   1.1  jdolecek 	if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
   2508   1.1  jdolecek 	if_setinitfn(ifp, ena_init);
   2509   1.1  jdolecek 	if_settransmitfn(ifp, ena_mq_start);
   2510   1.4  jdolecek #if 0
   2511   1.1  jdolecek 	if_setqflushfn(ifp, ena_qflush);
   2512   1.4  jdolecek #endif
   2513   1.1  jdolecek 	if_setioctlfn(ifp, ena_ioctl);
   2514   1.4  jdolecek #if 0
   2515   1.1  jdolecek 	if_setgetcounterfn(ifp, ena_get_counter);
   2516   1.4  jdolecek #endif
   2517   1.1  jdolecek 
   2518   1.1  jdolecek 	if_setsendqlen(ifp, adapter->tx_ring_size);
   2519   1.1  jdolecek 	if_setsendqready(ifp);
   2520   1.1  jdolecek 	if_setmtu(ifp, ETHERMTU);
   2521   1.1  jdolecek 	if_setbaudrate(ifp, 0);
   2522   1.1  jdolecek 	/* Zeroize capabilities... */
   2523   1.1  jdolecek 	if_setcapabilities(ifp, 0);
   2524   1.1  jdolecek 	if_setcapenable(ifp, 0);
   2525   1.1  jdolecek 	/* check hardware support */
   2526   1.1  jdolecek 	caps = ena_get_dev_offloads(feat);
   2527   1.1  jdolecek 	/* ... and set them */
   2528   1.1  jdolecek 	if_setcapabilitiesbit(ifp, caps, 0);
   2529   1.4  jdolecek 	adapter->sc_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU;
   2530   1.1  jdolecek 
   2531   1.4  jdolecek #if 0
   2532   1.1  jdolecek 	/* TSO parameters */
   2533   1.4  jdolecek 	/* XXX no limits on NetBSD, guarded by virtue of dmamap load failing */
   2534   1.1  jdolecek 	ifp->if_hw_tsomax = ENA_TSO_MAXSIZE -
   2535   1.1  jdolecek 	    (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
   2536   1.1  jdolecek 	ifp->if_hw_tsomaxsegcount = adapter->max_tx_sgl_size - 1;
   2537   1.1  jdolecek 	ifp->if_hw_tsomaxsegsize = ENA_TSO_MAXSIZE;
   2538   1.4  jdolecek #endif
   2539   1.1  jdolecek 
   2540   1.1  jdolecek 	if_setifheaderlen(ifp, sizeof(struct ether_vlan_header));
   2541   1.1  jdolecek 	if_setcapenable(ifp, if_getcapabilities(ifp));
   2542   1.1  jdolecek 
   2543   1.1  jdolecek 	/*
   2544   1.1  jdolecek 	 * Specify the media types supported by this adapter and register
   2545   1.1  jdolecek 	 * callbacks to update media and link information
   2546   1.1  jdolecek 	 */
   2547   1.1  jdolecek 	ifmedia_init(&adapter->media, IFM_IMASK,
   2548   1.1  jdolecek 	    ena_media_change, ena_media_status);
   2549   1.1  jdolecek 	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
   2550   1.1  jdolecek 	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
   2551   1.1  jdolecek 
   2552   1.9  jmcneill 	if_attach(ifp);
   2553   1.9  jmcneill 	if_deferred_start_init(ifp, NULL);
   2554   1.9  jmcneill 
   2555   1.1  jdolecek 	ether_ifattach(ifp, adapter->mac_addr);
   2556   1.1  jdolecek 
   2557   1.1  jdolecek 	return (0);
   2558   1.1  jdolecek }
   2559   1.1  jdolecek 
   2560   1.1  jdolecek static void
   2561   1.1  jdolecek ena_down(struct ena_adapter *adapter)
   2562   1.1  jdolecek {
   2563   1.1  jdolecek 	int rc;
   2564   1.1  jdolecek 
   2565   1.1  jdolecek 	if (adapter->up) {
   2566   1.1  jdolecek 		device_printf(adapter->pdev, "device is going DOWN\n");
   2567   1.1  jdolecek 
   2568   1.4  jdolecek 		callout_halt(&adapter->timer_service, &adapter->global_mtx);
   2569   1.1  jdolecek 
   2570   1.1  jdolecek 		adapter->up = false;
   2571   1.4  jdolecek 		if_setdrvflagbits(adapter->ifp, IFF_OACTIVE,
   2572   1.4  jdolecek 		    IFF_RUNNING);
   2573   1.1  jdolecek 
   2574   1.1  jdolecek 		ena_free_io_irq(adapter);
   2575   1.1  jdolecek 
   2576   1.1  jdolecek 		if (adapter->trigger_reset) {
   2577   1.1  jdolecek 			rc = ena_com_dev_reset(adapter->ena_dev,
   2578   1.1  jdolecek 			    adapter->reset_reason);
   2579   1.1  jdolecek 			if (unlikely(rc != 0))
   2580   1.1  jdolecek 				device_printf(adapter->pdev,
   2581   1.1  jdolecek 				    "Device reset failed\n");
   2582   1.1  jdolecek 		}
   2583   1.1  jdolecek 
   2584   1.1  jdolecek 		ena_destroy_all_io_queues(adapter);
   2585   1.1  jdolecek 
   2586   1.1  jdolecek 		ena_free_all_tx_bufs(adapter);
   2587   1.1  jdolecek 		ena_free_all_rx_bufs(adapter);
   2588   1.1  jdolecek 		ena_free_all_tx_resources(adapter);
   2589   1.1  jdolecek 		ena_free_all_rx_resources(adapter);
   2590   1.1  jdolecek 
   2591   1.1  jdolecek 		counter_u64_add(adapter->dev_stats.interface_down, 1);
   2592   1.1  jdolecek 	}
   2593   1.1  jdolecek }
   2594   1.1  jdolecek 
   2595   1.1  jdolecek static void
   2596   1.1  jdolecek ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct mbuf *mbuf)
   2597   1.1  jdolecek {
   2598   1.1  jdolecek 	struct ena_com_tx_meta *ena_meta;
   2599   1.1  jdolecek 	struct ether_vlan_header *eh;
   2600   1.1  jdolecek 	u32 mss;
   2601   1.1  jdolecek 	bool offload;
   2602   1.1  jdolecek 	uint16_t etype;
   2603   1.1  jdolecek 	int ehdrlen;
   2604   1.1  jdolecek 	struct ip *ip;
   2605   1.1  jdolecek 	int iphlen;
   2606   1.1  jdolecek 	struct tcphdr *th;
   2607   1.1  jdolecek 
   2608   1.1  jdolecek 	offload = false;
   2609   1.1  jdolecek 	ena_meta = &ena_tx_ctx->ena_meta;
   2610   1.4  jdolecek 
   2611   1.4  jdolecek #if 0
   2612   1.4  jdolecek 	u32 mss = mbuf->m_pkthdr.tso_segsz;
   2613   1.1  jdolecek 
   2614   1.1  jdolecek 	if (mss != 0)
   2615   1.1  jdolecek 		offload = true;
   2616   1.4  jdolecek #else
   2617   1.4  jdolecek 	mss = mbuf->m_pkthdr.len;	/* XXX don't have tso_segsz */
   2618   1.4  jdolecek #endif
   2619   1.1  jdolecek 
   2620   1.4  jdolecek 	if ((mbuf->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6)) != 0)
   2621   1.1  jdolecek 		offload = true;
   2622   1.1  jdolecek 
   2623   1.1  jdolecek 	if ((mbuf->m_pkthdr.csum_flags & CSUM_OFFLOAD) != 0)
   2624   1.1  jdolecek 		offload = true;
   2625   1.1  jdolecek 
   2626   1.1  jdolecek 	if (!offload) {
   2627   1.1  jdolecek 		ena_tx_ctx->meta_valid = 0;
   2628   1.1  jdolecek 		return;
   2629   1.1  jdolecek 	}
   2630   1.1  jdolecek 
   2631   1.1  jdolecek 	/* Determine where frame payload starts. */
   2632   1.1  jdolecek 	eh = mtod(mbuf, struct ether_vlan_header *);
   2633   1.1  jdolecek 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
   2634   1.1  jdolecek 		etype = ntohs(eh->evl_proto);
   2635   1.1  jdolecek 		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
   2636   1.1  jdolecek 	} else {
   2637   1.4  jdolecek 		etype = htons(eh->evl_encap_proto);
   2638   1.1  jdolecek 		ehdrlen = ETHER_HDR_LEN;
   2639   1.1  jdolecek 	}
   2640   1.1  jdolecek 
   2641   1.1  jdolecek 	ip = (struct ip *)(mbuf->m_data + ehdrlen);
   2642   1.1  jdolecek 	iphlen = ip->ip_hl << 2;
   2643   1.2  jdolecek 	th = (struct tcphdr *)((vaddr_t)ip + iphlen);
   2644   1.1  jdolecek 
   2645   1.4  jdolecek 	if ((mbuf->m_pkthdr.csum_flags & M_CSUM_IPv4) != 0) {
   2646   1.1  jdolecek 		ena_tx_ctx->l3_csum_enable = 1;
   2647   1.1  jdolecek 	}
   2648   1.4  jdolecek 	if ((mbuf->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6)) != 0) {
   2649   1.1  jdolecek 		ena_tx_ctx->tso_enable = 1;
   2650   1.1  jdolecek 		ena_meta->l4_hdr_len = (th->th_off);
   2651   1.1  jdolecek 	}
   2652   1.1  jdolecek 
   2653   1.1  jdolecek 	switch (etype) {
   2654   1.1  jdolecek 	case ETHERTYPE_IP:
   2655   1.1  jdolecek 		ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV4;
   2656   1.1  jdolecek 		if ((ip->ip_off & htons(IP_DF)) != 0)
   2657   1.1  jdolecek 			ena_tx_ctx->df = 1;
   2658   1.1  jdolecek 		break;
   2659   1.1  jdolecek 	case ETHERTYPE_IPV6:
   2660   1.1  jdolecek 		ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV6;
   2661   1.1  jdolecek 
   2662   1.1  jdolecek 	default:
   2663   1.1  jdolecek 		break;
   2664   1.1  jdolecek 	}
   2665   1.1  jdolecek 
   2666   1.1  jdolecek 	if (ip->ip_p == IPPROTO_TCP) {
   2667   1.1  jdolecek 		ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_TCP;
   2668   1.1  jdolecek 		if ((mbuf->m_pkthdr.csum_flags &
   2669   1.4  jdolecek 		    (M_CSUM_TCPv4 | M_CSUM_TCPv6)) != 0)
   2670   1.1  jdolecek 			ena_tx_ctx->l4_csum_enable = 1;
   2671   1.1  jdolecek 		else
   2672   1.1  jdolecek 			ena_tx_ctx->l4_csum_enable = 0;
   2673   1.1  jdolecek 	} else if (ip->ip_p == IPPROTO_UDP) {
   2674   1.1  jdolecek 		ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_UDP;
   2675   1.1  jdolecek 		if ((mbuf->m_pkthdr.csum_flags &
   2676   1.4  jdolecek 		    (M_CSUM_UDPv4 | M_CSUM_UDPv6)) != 0)
   2677   1.1  jdolecek 			ena_tx_ctx->l4_csum_enable = 1;
   2678   1.1  jdolecek 		else
   2679   1.1  jdolecek 			ena_tx_ctx->l4_csum_enable = 0;
   2680   1.1  jdolecek 	} else {
   2681   1.1  jdolecek 		ena_tx_ctx->l4_proto = ENA_ETH_IO_L4_PROTO_UNKNOWN;
   2682   1.1  jdolecek 		ena_tx_ctx->l4_csum_enable = 0;
   2683   1.1  jdolecek 	}
   2684   1.1  jdolecek 
   2685   1.1  jdolecek 	ena_meta->mss = mss;
   2686   1.1  jdolecek 	ena_meta->l3_hdr_len = iphlen;
   2687   1.1  jdolecek 	ena_meta->l3_hdr_offset = ehdrlen;
   2688   1.1  jdolecek 	ena_tx_ctx->meta_valid = 1;
   2689   1.1  jdolecek }
   2690   1.1  jdolecek 
   2691   1.1  jdolecek static int
   2692   1.1  jdolecek ena_check_and_collapse_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf)
   2693   1.1  jdolecek {
   2694   1.1  jdolecek 	struct ena_adapter *adapter;
   2695   1.1  jdolecek 	struct mbuf *collapsed_mbuf;
   2696   1.1  jdolecek 	int num_frags;
   2697   1.1  jdolecek 
   2698   1.1  jdolecek 	adapter = tx_ring->adapter;
   2699   1.1  jdolecek 	num_frags = ena_mbuf_count(*mbuf);
   2700   1.1  jdolecek 
   2701   1.1  jdolecek 	/* One segment must be reserved for configuration descriptor. */
   2702   1.1  jdolecek 	if (num_frags < adapter->max_tx_sgl_size)
   2703   1.1  jdolecek 		return (0);
   2704   1.1  jdolecek 	counter_u64_add(tx_ring->tx_stats.collapse, 1);
   2705   1.1  jdolecek 
   2706   1.1  jdolecek 	collapsed_mbuf = m_collapse(*mbuf, M_NOWAIT,
   2707   1.1  jdolecek 	    adapter->max_tx_sgl_size - 1);
   2708   1.1  jdolecek 	if (unlikely(collapsed_mbuf == NULL)) {
   2709   1.1  jdolecek 		counter_u64_add(tx_ring->tx_stats.collapse_err, 1);
   2710   1.1  jdolecek 		return (ENOMEM);
   2711   1.1  jdolecek 	}
   2712   1.1  jdolecek 
   2713   1.1  jdolecek 	/* If mbuf was collapsed succesfully, original mbuf is released. */
   2714   1.1  jdolecek 	*mbuf = collapsed_mbuf;
   2715   1.1  jdolecek 
   2716   1.1  jdolecek 	return (0);
   2717   1.1  jdolecek }
   2718   1.1  jdolecek 
   2719   1.1  jdolecek static int
   2720   1.1  jdolecek ena_xmit_mbuf(struct ena_ring *tx_ring, struct mbuf **mbuf)
   2721   1.1  jdolecek {
   2722   1.1  jdolecek 	struct ena_adapter *adapter;
   2723   1.1  jdolecek 	struct ena_tx_buffer *tx_info;
   2724   1.1  jdolecek 	struct ena_com_tx_ctx ena_tx_ctx;
   2725   1.1  jdolecek 	struct ena_com_dev *ena_dev;
   2726   1.1  jdolecek 	struct ena_com_buf *ena_buf;
   2727   1.1  jdolecek 	struct ena_com_io_sq* io_sq;
   2728   1.1  jdolecek 	void *push_hdr;
   2729   1.1  jdolecek 	uint16_t next_to_use;
   2730   1.1  jdolecek 	uint16_t req_id;
   2731   1.1  jdolecek 	uint16_t ena_qid;
   2732   1.4  jdolecek 	uint32_t header_len;
   2733   1.1  jdolecek 	int i, rc;
   2734   1.1  jdolecek 	int nb_hw_desc;
   2735   1.1  jdolecek 
   2736   1.1  jdolecek 	ena_qid = ENA_IO_TXQ_IDX(tx_ring->que->id);
   2737   1.1  jdolecek 	adapter = tx_ring->que->adapter;
   2738   1.1  jdolecek 	ena_dev = adapter->ena_dev;
   2739   1.1  jdolecek 	io_sq = &ena_dev->io_sq_queues[ena_qid];
   2740   1.1  jdolecek 
   2741   1.1  jdolecek 	rc = ena_check_and_collapse_mbuf(tx_ring, mbuf);
   2742   1.1  jdolecek 	if (unlikely(rc != 0)) {
   2743   1.1  jdolecek 		ena_trace(ENA_WARNING,
   2744   1.1  jdolecek 		    "Failed to collapse mbuf! err: %d", rc);
   2745   1.1  jdolecek 		return (rc);
   2746   1.1  jdolecek 	}
   2747   1.1  jdolecek 
   2748   1.1  jdolecek 	next_to_use = tx_ring->next_to_use;
   2749   1.1  jdolecek 	req_id = tx_ring->free_tx_ids[next_to_use];
   2750   1.1  jdolecek 	tx_info = &tx_ring->tx_buffer_info[req_id];
   2751   1.1  jdolecek 
   2752   1.1  jdolecek 	tx_info->mbuf = *mbuf;
   2753   1.1  jdolecek 	tx_info->num_of_bufs = 0;
   2754   1.1  jdolecek 
   2755   1.1  jdolecek 	ena_buf = tx_info->bufs;
   2756   1.1  jdolecek 
   2757   1.1  jdolecek 	ena_trace(ENA_DBG | ENA_TXPTH, "Tx: %d bytes", (*mbuf)->m_pkthdr.len);
   2758   1.1  jdolecek 
   2759   1.1  jdolecek 	/*
   2760   1.1  jdolecek 	 * header_len is just a hint for the device. Because FreeBSD is not
   2761   1.1  jdolecek 	 * giving us information about packet header length and it is not
   2762   1.1  jdolecek 	 * guaranteed that all packet headers will be in the 1st mbuf, setting
   2763   1.1  jdolecek 	 * header_len to 0 is making the device ignore this value and resolve
   2764   1.1  jdolecek 	 * header on it's own.
   2765   1.1  jdolecek 	 */
   2766   1.1  jdolecek 	header_len = 0;
   2767   1.1  jdolecek 	push_hdr = NULL;
   2768   1.1  jdolecek 
   2769   1.4  jdolecek 	rc = bus_dmamap_load_mbuf(adapter->sc_dmat, tx_info->map,
   2770   1.4  jdolecek 	    *mbuf, BUS_DMA_NOWAIT);
   2771   1.1  jdolecek 
   2772   1.4  jdolecek 	if (unlikely((rc != 0) || (tx_info->map->dm_nsegs == 0))) {
   2773   1.1  jdolecek 		ena_trace(ENA_WARNING,
   2774   1.4  jdolecek 		    "dmamap load failed! err: %d nsegs: %d", rc,
   2775   1.4  jdolecek 		    tx_info->map->dm_nsegs);
   2776   1.1  jdolecek 		counter_u64_add(tx_ring->tx_stats.dma_mapping_err, 1);
   2777   1.1  jdolecek 		tx_info->mbuf = NULL;
   2778   1.1  jdolecek 		if (rc == ENOMEM)
   2779   1.1  jdolecek 			return (ENA_COM_NO_MEM);
   2780   1.1  jdolecek 		else
   2781   1.1  jdolecek 			return (ENA_COM_INVAL);
   2782   1.1  jdolecek 	}
   2783   1.1  jdolecek 
   2784   1.4  jdolecek 	for (i = 0; i < tx_info->map->dm_nsegs; i++) {
   2785   1.4  jdolecek 		ena_buf->len = tx_info->map->dm_segs[i].ds_len;
   2786   1.4  jdolecek 		ena_buf->paddr = tx_info->map->dm_segs[i].ds_addr;
   2787   1.1  jdolecek 		ena_buf++;
   2788   1.1  jdolecek 	}
   2789   1.4  jdolecek 	tx_info->num_of_bufs = tx_info->map->dm_nsegs;
   2790   1.1  jdolecek 
   2791   1.1  jdolecek 	memset(&ena_tx_ctx, 0x0, sizeof(struct ena_com_tx_ctx));
   2792   1.1  jdolecek 	ena_tx_ctx.ena_bufs = tx_info->bufs;
   2793   1.1  jdolecek 	ena_tx_ctx.push_header = push_hdr;
   2794   1.1  jdolecek 	ena_tx_ctx.num_bufs = tx_info->num_of_bufs;
   2795   1.1  jdolecek 	ena_tx_ctx.req_id = req_id;
   2796   1.1  jdolecek 	ena_tx_ctx.header_len = header_len;
   2797   1.1  jdolecek 
   2798   1.1  jdolecek 	/* Set flags and meta data */
   2799   1.1  jdolecek 	ena_tx_csum(&ena_tx_ctx, *mbuf);
   2800   1.1  jdolecek 	/* Prepare the packet's descriptors and send them to device */
   2801   1.1  jdolecek 	rc = ena_com_prepare_tx(io_sq, &ena_tx_ctx, &nb_hw_desc);
   2802   1.1  jdolecek 	if (unlikely(rc != 0)) {
   2803   1.1  jdolecek 		device_printf(adapter->pdev, "failed to prepare tx bufs\n");
   2804   1.1  jdolecek 		counter_u64_add(tx_ring->tx_stats.prepare_ctx_err, 1);
   2805   1.1  jdolecek 		goto dma_error;
   2806   1.1  jdolecek 	}
   2807   1.1  jdolecek 
   2808   1.1  jdolecek 	counter_enter();
   2809   1.1  jdolecek 	counter_u64_add_protected(tx_ring->tx_stats.cnt, 1);
   2810   1.1  jdolecek 	counter_u64_add_protected(tx_ring->tx_stats.bytes,
   2811   1.1  jdolecek 	    (*mbuf)->m_pkthdr.len);
   2812   1.1  jdolecek 
   2813   1.1  jdolecek 	counter_u64_add_protected(adapter->hw_stats.tx_packets, 1);
   2814   1.1  jdolecek 	counter_u64_add_protected(adapter->hw_stats.tx_bytes,
   2815   1.1  jdolecek 	    (*mbuf)->m_pkthdr.len);
   2816   1.1  jdolecek 	counter_exit();
   2817   1.1  jdolecek 
   2818   1.1  jdolecek 	tx_info->tx_descs = nb_hw_desc;
   2819   1.1  jdolecek 	getbinuptime(&tx_info->timestamp);
   2820   1.1  jdolecek 	tx_info->print_once = true;
   2821   1.1  jdolecek 
   2822   1.1  jdolecek 	tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use,
   2823   1.1  jdolecek 	    tx_ring->ring_size);
   2824   1.1  jdolecek 
   2825   1.4  jdolecek 	bus_dmamap_sync(adapter->sc_dmat, tx_info->map, 0,
   2826   1.4  jdolecek 	    tx_info->map->dm_mapsize, BUS_DMASYNC_PREWRITE);
   2827   1.1  jdolecek 
   2828   1.1  jdolecek 	return (0);
   2829   1.1  jdolecek 
   2830   1.1  jdolecek dma_error:
   2831   1.1  jdolecek 	tx_info->mbuf = NULL;
   2832   1.2  jdolecek 	bus_dmamap_unload(adapter->sc_dmat, tx_info->map);
   2833   1.1  jdolecek 
   2834   1.1  jdolecek 	return (rc);
   2835   1.1  jdolecek }
   2836   1.1  jdolecek 
   2837   1.1  jdolecek static void
   2838   1.1  jdolecek ena_start_xmit(struct ena_ring *tx_ring)
   2839   1.1  jdolecek {
   2840   1.1  jdolecek 	struct mbuf *mbuf;
   2841   1.1  jdolecek 	struct ena_adapter *adapter = tx_ring->adapter;
   2842   1.1  jdolecek 	struct ena_com_io_sq* io_sq;
   2843   1.1  jdolecek 	int ena_qid;
   2844   1.1  jdolecek 	int acum_pkts = 0;
   2845   1.1  jdolecek 	int ret = 0;
   2846   1.1  jdolecek 
   2847   1.4  jdolecek 	if (unlikely((if_getdrvflags(adapter->ifp) & IFF_RUNNING) == 0))
   2848   1.1  jdolecek 		return;
   2849   1.1  jdolecek 
   2850   1.1  jdolecek 	if (unlikely(!adapter->link_status))
   2851   1.1  jdolecek 		return;
   2852   1.1  jdolecek 
   2853   1.1  jdolecek 	ena_qid = ENA_IO_TXQ_IDX(tx_ring->que->id);
   2854   1.1  jdolecek 	io_sq = &adapter->ena_dev->io_sq_queues[ena_qid];
   2855   1.1  jdolecek 
   2856   1.1  jdolecek 	while ((mbuf = drbr_peek(adapter->ifp, tx_ring->br)) != NULL) {
   2857   1.1  jdolecek 		ena_trace(ENA_DBG | ENA_TXPTH, "\ndequeued mbuf %p with flags %#x and"
   2858   1.1  jdolecek 		    " header csum flags %#jx",
   2859   1.1  jdolecek 		    mbuf, mbuf->m_flags, (uint64_t)mbuf->m_pkthdr.csum_flags);
   2860   1.1  jdolecek 
   2861   1.1  jdolecek 		if (unlikely(!ena_com_sq_have_enough_space(io_sq,
   2862   1.1  jdolecek 		    ENA_TX_CLEANUP_THRESHOLD)))
   2863   1.1  jdolecek 			ena_tx_cleanup(tx_ring);
   2864   1.1  jdolecek 
   2865   1.1  jdolecek 		if (unlikely((ret = ena_xmit_mbuf(tx_ring, &mbuf)) != 0)) {
   2866   1.1  jdolecek 			if (ret == ENA_COM_NO_MEM) {
   2867   1.1  jdolecek 				drbr_putback(adapter->ifp, tx_ring->br, mbuf);
   2868   1.1  jdolecek 			} else if (ret == ENA_COM_NO_SPACE) {
   2869   1.1  jdolecek 				drbr_putback(adapter->ifp, tx_ring->br, mbuf);
   2870   1.1  jdolecek 			} else {
   2871   1.1  jdolecek 				m_freem(mbuf);
   2872   1.1  jdolecek 				drbr_advance(adapter->ifp, tx_ring->br);
   2873   1.1  jdolecek 			}
   2874   1.1  jdolecek 
   2875   1.1  jdolecek 			break;
   2876   1.1  jdolecek 		}
   2877   1.1  jdolecek 
   2878   1.1  jdolecek 		drbr_advance(adapter->ifp, tx_ring->br);
   2879   1.1  jdolecek 
   2880   1.1  jdolecek 		if (unlikely((if_getdrvflags(adapter->ifp) &
   2881   1.4  jdolecek 		    IFF_RUNNING) == 0))
   2882   1.1  jdolecek 			return;
   2883   1.1  jdolecek 
   2884   1.1  jdolecek 		acum_pkts++;
   2885   1.1  jdolecek 
   2886   1.4  jdolecek 		/*
   2887   1.4  jdolecek 		 * If there's a BPF listener, bounce a copy of this frame
   2888   1.4  jdolecek 		 * to him.
   2889   1.4  jdolecek 		 */
   2890   1.5   msaitoh 		bpf_mtap(adapter->ifp, mbuf, BPF_D_OUT);
   2891   1.1  jdolecek 
   2892   1.1  jdolecek 		if (unlikely(acum_pkts == DB_THRESHOLD)) {
   2893   1.1  jdolecek 			acum_pkts = 0;
   2894   1.1  jdolecek 			wmb();
   2895   1.1  jdolecek 			/* Trigger the dma engine */
   2896   1.1  jdolecek 			ena_com_write_sq_doorbell(io_sq);
   2897   1.1  jdolecek 			counter_u64_add(tx_ring->tx_stats.doorbells, 1);
   2898   1.1  jdolecek 		}
   2899   1.1  jdolecek 
   2900   1.1  jdolecek 	}
   2901   1.1  jdolecek 
   2902   1.1  jdolecek 	if (likely(acum_pkts != 0)) {
   2903   1.1  jdolecek 		wmb();
   2904   1.1  jdolecek 		/* Trigger the dma engine */
   2905   1.1  jdolecek 		ena_com_write_sq_doorbell(io_sq);
   2906   1.1  jdolecek 		counter_u64_add(tx_ring->tx_stats.doorbells, 1);
   2907   1.1  jdolecek 	}
   2908   1.1  jdolecek 
   2909   1.1  jdolecek 	if (!ena_com_sq_have_enough_space(io_sq, ENA_TX_CLEANUP_THRESHOLD))
   2910   1.1  jdolecek 		ena_tx_cleanup(tx_ring);
   2911   1.1  jdolecek }
   2912   1.1  jdolecek 
   2913   1.1  jdolecek static void
   2914   1.4  jdolecek ena_deferred_mq_start(struct work *wk, void *arg)
   2915   1.1  jdolecek {
   2916   1.1  jdolecek 	struct ena_ring *tx_ring = (struct ena_ring *)arg;
   2917   1.1  jdolecek 	struct ifnet *ifp = tx_ring->adapter->ifp;
   2918   1.1  jdolecek 
   2919  1.10  jmcneill 	atomic_swap_uint(&tx_ring->task_pending, 0);
   2920  1.10  jmcneill 
   2921   1.1  jdolecek 	while (!drbr_empty(ifp, tx_ring->br) &&
   2922   1.4  jdolecek 	    (if_getdrvflags(ifp) & IFF_RUNNING) != 0) {
   2923   1.1  jdolecek 		ENA_RING_MTX_LOCK(tx_ring);
   2924   1.1  jdolecek 		ena_start_xmit(tx_ring);
   2925   1.1  jdolecek 		ENA_RING_MTX_UNLOCK(tx_ring);
   2926   1.1  jdolecek 	}
   2927   1.1  jdolecek }
   2928   1.1  jdolecek 
   2929   1.1  jdolecek static int
   2930   1.2  jdolecek ena_mq_start(struct ifnet *ifp, struct mbuf *m)
   2931   1.1  jdolecek {
   2932   1.1  jdolecek 	struct ena_adapter *adapter = ifp->if_softc;
   2933   1.1  jdolecek 	struct ena_ring *tx_ring;
   2934   1.1  jdolecek 	int ret, is_drbr_empty;
   2935   1.1  jdolecek 	uint32_t i;
   2936   1.1  jdolecek 
   2937   1.4  jdolecek 	if (unlikely((if_getdrvflags(adapter->ifp) & IFF_RUNNING) == 0))
   2938   1.1  jdolecek 		return (ENODEV);
   2939   1.1  jdolecek 
   2940   1.1  jdolecek 	/* Which queue to use */
   2941   1.1  jdolecek 	/*
   2942   1.1  jdolecek 	 * If everything is setup correctly, it should be the
   2943   1.1  jdolecek 	 * same bucket that the current CPU we're on is.
   2944   1.1  jdolecek 	 * It should improve performance.
   2945   1.1  jdolecek 	 */
   2946   1.4  jdolecek #if 0
   2947   1.1  jdolecek 	if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
   2948   1.1  jdolecek #ifdef	RSS
   2949   1.1  jdolecek 		if (rss_hash2bucket(m->m_pkthdr.flowid,
   2950   1.1  jdolecek 		    M_HASHTYPE_GET(m), &i) == 0) {
   2951   1.1  jdolecek 			i = i % adapter->num_queues;
   2952   1.1  jdolecek 
   2953   1.1  jdolecek 		} else
   2954   1.1  jdolecek #endif
   2955   1.1  jdolecek 		{
   2956   1.1  jdolecek 			i = m->m_pkthdr.flowid % adapter->num_queues;
   2957   1.1  jdolecek 		}
   2958   1.1  jdolecek 	} else {
   2959   1.4  jdolecek #endif
   2960   1.4  jdolecek 		i = cpu_index(curcpu()) % adapter->num_queues;
   2961   1.4  jdolecek #if 0
   2962   1.1  jdolecek 	}
   2963   1.4  jdolecek #endif
   2964   1.1  jdolecek 	tx_ring = &adapter->tx_ring[i];
   2965   1.1  jdolecek 
   2966   1.1  jdolecek 	/* Check if drbr is empty before putting packet */
   2967   1.1  jdolecek 	is_drbr_empty = drbr_empty(ifp, tx_ring->br);
   2968   1.1  jdolecek 	ret = drbr_enqueue(ifp, tx_ring->br, m);
   2969   1.1  jdolecek 	if (unlikely(ret != 0)) {
   2970  1.10  jmcneill 		if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
   2971  1.10  jmcneill 			workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
   2972  1.10  jmcneill 			    curcpu());
   2973   1.1  jdolecek 		return (ret);
   2974   1.1  jdolecek 	}
   2975   1.1  jdolecek 
   2976   1.1  jdolecek 	if ((is_drbr_empty != 0) && (ENA_RING_MTX_TRYLOCK(tx_ring) != 0)) {
   2977   1.1  jdolecek 		ena_start_xmit(tx_ring);
   2978   1.1  jdolecek 		ENA_RING_MTX_UNLOCK(tx_ring);
   2979   1.1  jdolecek 	} else {
   2980  1.10  jmcneill 		if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
   2981  1.10  jmcneill 			workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
   2982  1.10  jmcneill 			    curcpu());
   2983   1.1  jdolecek 	}
   2984   1.1  jdolecek 
   2985   1.1  jdolecek 	return (0);
   2986   1.1  jdolecek }
   2987   1.1  jdolecek 
   2988   1.4  jdolecek #if 0
   2989   1.1  jdolecek static void
   2990   1.2  jdolecek ena_qflush(struct ifnet *ifp)
   2991   1.1  jdolecek {
   2992   1.1  jdolecek 	struct ena_adapter *adapter = ifp->if_softc;
   2993   1.1  jdolecek 	struct ena_ring *tx_ring = adapter->tx_ring;
   2994   1.1  jdolecek 	int i;
   2995   1.1  jdolecek 
   2996   1.1  jdolecek 	for(i = 0; i < adapter->num_queues; ++i, ++tx_ring)
   2997   1.1  jdolecek 		if (!drbr_empty(ifp, tx_ring->br)) {
   2998   1.1  jdolecek 			ENA_RING_MTX_LOCK(tx_ring);
   2999   1.1  jdolecek 			drbr_flush(ifp, tx_ring->br);
   3000   1.1  jdolecek 			ENA_RING_MTX_UNLOCK(tx_ring);
   3001   1.1  jdolecek 		}
   3002   1.1  jdolecek 
   3003   1.1  jdolecek 	if_qflush(ifp);
   3004   1.1  jdolecek }
   3005   1.4  jdolecek #endif
   3006   1.1  jdolecek 
   3007   1.1  jdolecek static int
   3008   1.4  jdolecek ena_calc_io_queue_num(struct pci_attach_args *pa,
   3009   1.4  jdolecek     struct ena_adapter *adapter,
   3010   1.1  jdolecek     struct ena_com_dev_get_features_ctx *get_feat_ctx)
   3011   1.1  jdolecek {
   3012   1.1  jdolecek 	int io_sq_num, io_cq_num, io_queue_num;
   3013   1.1  jdolecek 
   3014   1.1  jdolecek 	io_sq_num = get_feat_ctx->max_queues.max_sq_num;
   3015   1.1  jdolecek 	io_cq_num = get_feat_ctx->max_queues.max_cq_num;
   3016   1.1  jdolecek 
   3017   1.1  jdolecek 	io_queue_num = min_t(int, mp_ncpus, ENA_MAX_NUM_IO_QUEUES);
   3018   1.1  jdolecek 	io_queue_num = min_t(int, io_queue_num, io_sq_num);
   3019   1.1  jdolecek 	io_queue_num = min_t(int, io_queue_num, io_cq_num);
   3020   1.1  jdolecek 	/* 1 IRQ for for mgmnt and 1 IRQ for each TX/RX pair */
   3021   1.1  jdolecek 	io_queue_num = min_t(int, io_queue_num,
   3022   1.4  jdolecek 	    pci_msix_count(pa->pa_pc, pa->pa_tag) - 1);
   3023   1.1  jdolecek #ifdef	RSS
   3024   1.1  jdolecek 	io_queue_num = min_t(int, io_queue_num, rss_getnumbuckets());
   3025   1.1  jdolecek #endif
   3026   1.1  jdolecek 
   3027   1.1  jdolecek 	return (io_queue_num);
   3028   1.1  jdolecek }
   3029   1.1  jdolecek 
   3030   1.1  jdolecek static int
   3031   1.1  jdolecek ena_calc_queue_size(struct ena_adapter *adapter, uint16_t *max_tx_sgl_size,
   3032   1.1  jdolecek     uint16_t *max_rx_sgl_size, struct ena_com_dev_get_features_ctx *feat)
   3033   1.1  jdolecek {
   3034   1.1  jdolecek 	uint32_t queue_size = ENA_DEFAULT_RING_SIZE;
   3035   1.1  jdolecek 	uint32_t v;
   3036   1.1  jdolecek 	uint32_t q;
   3037   1.1  jdolecek 
   3038   1.1  jdolecek 	queue_size = min_t(uint32_t, queue_size,
   3039   1.1  jdolecek 	    feat->max_queues.max_cq_depth);
   3040   1.1  jdolecek 	queue_size = min_t(uint32_t, queue_size,
   3041   1.1  jdolecek 	    feat->max_queues.max_sq_depth);
   3042   1.1  jdolecek 
   3043   1.1  jdolecek 	/* round down to the nearest power of 2 */
   3044   1.1  jdolecek 	v = queue_size;
   3045   1.1  jdolecek 	while (v != 0) {
   3046   1.1  jdolecek 		if (powerof2(queue_size) != 0)
   3047   1.1  jdolecek 			break;
   3048   1.1  jdolecek 		v /= 2;
   3049   1.1  jdolecek 		q = rounddown2(queue_size, v);
   3050   1.1  jdolecek 		if (q != 0) {
   3051   1.1  jdolecek 			queue_size = q;
   3052   1.1  jdolecek 			break;
   3053   1.1  jdolecek 		}
   3054   1.1  jdolecek 	}
   3055   1.1  jdolecek 
   3056   1.1  jdolecek 	if (unlikely(queue_size == 0)) {
   3057   1.1  jdolecek 		device_printf(adapter->pdev, "Invalid queue size\n");
   3058   1.1  jdolecek 		return (ENA_COM_FAULT);
   3059   1.1  jdolecek 	}
   3060   1.1  jdolecek 
   3061   1.1  jdolecek 	*max_tx_sgl_size = min_t(uint16_t, ENA_PKT_MAX_BUFS,
   3062   1.1  jdolecek 	    feat->max_queues.max_packet_tx_descs);
   3063   1.1  jdolecek 	*max_rx_sgl_size = min_t(uint16_t, ENA_PKT_MAX_BUFS,
   3064   1.1  jdolecek 	    feat->max_queues.max_packet_rx_descs);
   3065   1.1  jdolecek 
   3066   1.1  jdolecek 	return (queue_size);
   3067   1.1  jdolecek }
   3068   1.1  jdolecek 
   3069   1.4  jdolecek #if 0
   3070   1.1  jdolecek static int
   3071   1.1  jdolecek ena_rss_init_default(struct ena_adapter *adapter)
   3072   1.1  jdolecek {
   3073   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   3074   1.1  jdolecek 	device_t dev = adapter->pdev;
   3075   1.1  jdolecek 	int qid, rc, i;
   3076   1.1  jdolecek 
   3077   1.1  jdolecek 	rc = ena_com_rss_init(ena_dev, ENA_RX_RSS_TABLE_LOG_SIZE);
   3078   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3079   1.1  jdolecek 		device_printf(dev, "Cannot init indirect table\n");
   3080   1.1  jdolecek 		return (rc);
   3081   1.1  jdolecek 	}
   3082   1.1  jdolecek 
   3083   1.1  jdolecek 	for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) {
   3084   1.1  jdolecek #ifdef	RSS
   3085   1.1  jdolecek 		qid = rss_get_indirection_to_bucket(i);
   3086   1.1  jdolecek 		qid = qid % adapter->num_queues;
   3087   1.1  jdolecek #else
   3088   1.1  jdolecek 		qid = i % adapter->num_queues;
   3089   1.1  jdolecek #endif
   3090   1.1  jdolecek 		rc = ena_com_indirect_table_fill_entry(ena_dev, i,
   3091   1.1  jdolecek 		    ENA_IO_RXQ_IDX(qid));
   3092   1.1  jdolecek 		if (unlikely((rc != 0) && (rc != EOPNOTSUPP))) {
   3093   1.1  jdolecek 			device_printf(dev, "Cannot fill indirect table\n");
   3094   1.1  jdolecek 			goto err_rss_destroy;
   3095   1.1  jdolecek 		}
   3096   1.1  jdolecek 	}
   3097   1.1  jdolecek 
   3098   1.1  jdolecek 	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL,
   3099   1.1  jdolecek 	    ENA_HASH_KEY_SIZE, 0xFFFFFFFF);
   3100   1.1  jdolecek 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP))) {
   3101   1.1  jdolecek 		device_printf(dev, "Cannot fill hash function\n");
   3102   1.1  jdolecek 		goto err_rss_destroy;
   3103   1.1  jdolecek 	}
   3104   1.1  jdolecek 
   3105   1.1  jdolecek 	rc = ena_com_set_default_hash_ctrl(ena_dev);
   3106   1.1  jdolecek 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP))) {
   3107   1.1  jdolecek 		device_printf(dev, "Cannot fill hash control\n");
   3108   1.1  jdolecek 		goto err_rss_destroy;
   3109   1.1  jdolecek 	}
   3110   1.1  jdolecek 
   3111   1.1  jdolecek 	return (0);
   3112   1.1  jdolecek 
   3113   1.1  jdolecek err_rss_destroy:
   3114   1.1  jdolecek 	ena_com_rss_destroy(ena_dev);
   3115   1.1  jdolecek 	return (rc);
   3116   1.1  jdolecek }
   3117   1.1  jdolecek 
   3118   1.1  jdolecek static void
   3119   1.1  jdolecek ena_rss_init_default_deferred(void *arg)
   3120   1.1  jdolecek {
   3121   1.1  jdolecek 	struct ena_adapter *adapter;
   3122   1.1  jdolecek 	devclass_t dc;
   3123   1.1  jdolecek 	int max;
   3124   1.1  jdolecek 	int rc;
   3125   1.1  jdolecek 
   3126   1.1  jdolecek 	dc = devclass_find("ena");
   3127   1.1  jdolecek 	if (unlikely(dc == NULL)) {
   3128   1.1  jdolecek 		ena_trace(ENA_ALERT, "No devclass ena\n");
   3129   1.1  jdolecek 		return;
   3130   1.1  jdolecek 	}
   3131   1.1  jdolecek 
   3132   1.1  jdolecek 	max = devclass_get_maxunit(dc);
   3133   1.1  jdolecek 	while (max-- >= 0) {
   3134   1.1  jdolecek 		adapter = devclass_get_softc(dc, max);
   3135   1.1  jdolecek 		if (adapter != NULL) {
   3136   1.1  jdolecek 			rc = ena_rss_init_default(adapter);
   3137   1.1  jdolecek 			adapter->rss_support = true;
   3138   1.1  jdolecek 			if (unlikely(rc != 0)) {
   3139   1.1  jdolecek 				device_printf(adapter->pdev,
   3140   1.1  jdolecek 				    "WARNING: RSS was not properly initialized,"
   3141   1.1  jdolecek 				    " it will affect bandwidth\n");
   3142   1.1  jdolecek 				adapter->rss_support = false;
   3143   1.1  jdolecek 			}
   3144   1.1  jdolecek 		}
   3145   1.1  jdolecek 	}
   3146   1.1  jdolecek }
   3147   1.1  jdolecek SYSINIT(ena_rss_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, ena_rss_init_default_deferred, NULL);
   3148   1.4  jdolecek #endif
   3149   1.1  jdolecek 
   3150   1.1  jdolecek static void
   3151   1.1  jdolecek ena_config_host_info(struct ena_com_dev *ena_dev)
   3152   1.1  jdolecek {
   3153   1.1  jdolecek 	struct ena_admin_host_info *host_info;
   3154   1.1  jdolecek 	int rc;
   3155   1.1  jdolecek 
   3156   1.1  jdolecek 	/* Allocate only the host info */
   3157   1.1  jdolecek 	rc = ena_com_allocate_host_info(ena_dev);
   3158   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3159   1.1  jdolecek 		ena_trace(ENA_ALERT, "Cannot allocate host info\n");
   3160   1.1  jdolecek 		return;
   3161   1.1  jdolecek 	}
   3162   1.1  jdolecek 
   3163   1.1  jdolecek 	host_info = ena_dev->host_attr.host_info;
   3164   1.1  jdolecek 
   3165   1.1  jdolecek 	host_info->os_type = ENA_ADMIN_OS_FREEBSD;
   3166   1.1  jdolecek 	host_info->kernel_ver = osreldate;
   3167   1.1  jdolecek 
   3168   1.2  jdolecek 	snprintf(host_info->kernel_ver_str, sizeof(host_info->kernel_ver_str),
   3169   1.2  jdolecek 	    "%d", osreldate);
   3170   1.1  jdolecek 	host_info->os_dist = 0;
   3171   1.1  jdolecek 	strncpy(host_info->os_dist_str, osrelease,
   3172   1.1  jdolecek 	    sizeof(host_info->os_dist_str) - 1);
   3173   1.1  jdolecek 
   3174   1.1  jdolecek 	host_info->driver_version =
   3175   1.1  jdolecek 		(DRV_MODULE_VER_MAJOR) |
   3176   1.1  jdolecek 		(DRV_MODULE_VER_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) |
   3177   1.1  jdolecek 		(DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT);
   3178   1.1  jdolecek 
   3179   1.1  jdolecek 	rc = ena_com_set_host_attributes(ena_dev);
   3180   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3181   1.1  jdolecek 		if (rc == EOPNOTSUPP)
   3182   1.1  jdolecek 			ena_trace(ENA_WARNING, "Cannot set host attributes\n");
   3183   1.1  jdolecek 		else
   3184   1.1  jdolecek 			ena_trace(ENA_ALERT, "Cannot set host attributes\n");
   3185   1.1  jdolecek 
   3186   1.1  jdolecek 		goto err;
   3187   1.1  jdolecek 	}
   3188   1.1  jdolecek 
   3189   1.1  jdolecek 	return;
   3190   1.1  jdolecek 
   3191   1.1  jdolecek err:
   3192   1.1  jdolecek 	ena_com_delete_host_info(ena_dev);
   3193   1.1  jdolecek }
   3194   1.1  jdolecek 
   3195   1.1  jdolecek static int
   3196   1.1  jdolecek ena_device_init(struct ena_adapter *adapter, device_t pdev,
   3197   1.1  jdolecek     struct ena_com_dev_get_features_ctx *get_feat_ctx, int *wd_active)
   3198   1.1  jdolecek {
   3199   1.1  jdolecek 	struct ena_com_dev* ena_dev = adapter->ena_dev;
   3200   1.1  jdolecek 	bool readless_supported;
   3201   1.1  jdolecek 	uint32_t aenq_groups;
   3202   1.1  jdolecek 	int dma_width;
   3203   1.1  jdolecek 	int rc;
   3204   1.1  jdolecek 
   3205   1.1  jdolecek 	rc = ena_com_mmio_reg_read_request_init(ena_dev);
   3206   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3207   1.1  jdolecek 		device_printf(pdev, "failed to init mmio read less\n");
   3208   1.1  jdolecek 		return (rc);
   3209   1.1  jdolecek 	}
   3210   1.1  jdolecek 
   3211   1.1  jdolecek 	/*
   3212   1.1  jdolecek 	 * The PCIe configuration space revision id indicate if mmio reg
   3213   1.1  jdolecek 	 * read is disabled
   3214   1.1  jdolecek 	 */
   3215   1.4  jdolecek 	const int rev = PCI_REVISION(adapter->sc_pa.pa_class);
   3216   1.4  jdolecek 	readless_supported = ((rev & ENA_MMIO_DISABLE_REG_READ) == 0);
   3217   1.1  jdolecek 	ena_com_set_mmio_read_mode(ena_dev, readless_supported);
   3218   1.1  jdolecek 
   3219   1.1  jdolecek 	rc = ena_com_dev_reset(ena_dev, ENA_REGS_RESET_NORMAL);
   3220   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3221   1.1  jdolecek 		device_printf(pdev, "Can not reset device\n");
   3222   1.1  jdolecek 		goto err_mmio_read_less;
   3223   1.1  jdolecek 	}
   3224   1.1  jdolecek 
   3225   1.1  jdolecek 	rc = ena_com_validate_version(ena_dev);
   3226   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3227   1.1  jdolecek 		device_printf(pdev, "device version is too low\n");
   3228   1.1  jdolecek 		goto err_mmio_read_less;
   3229   1.1  jdolecek 	}
   3230   1.1  jdolecek 
   3231   1.1  jdolecek 	dma_width = ena_com_get_dma_width(ena_dev);
   3232   1.1  jdolecek 	if (unlikely(dma_width < 0)) {
   3233   1.1  jdolecek 		device_printf(pdev, "Invalid dma width value %d", dma_width);
   3234   1.1  jdolecek 		rc = dma_width;
   3235   1.1  jdolecek 		goto err_mmio_read_less;
   3236   1.1  jdolecek 	}
   3237   1.1  jdolecek 	adapter->dma_width = dma_width;
   3238   1.1  jdolecek 
   3239   1.1  jdolecek 	/* ENA admin level init */
   3240   1.1  jdolecek 	rc = ena_com_admin_init(ena_dev, &aenq_handlers, true);
   3241   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3242   1.1  jdolecek 		device_printf(pdev,
   3243   1.1  jdolecek 		    "Can not initialize ena admin queue with device\n");
   3244   1.1  jdolecek 		goto err_mmio_read_less;
   3245   1.1  jdolecek 	}
   3246   1.1  jdolecek 
   3247   1.1  jdolecek 	/*
   3248   1.1  jdolecek 	 * To enable the msix interrupts the driver needs to know the number
   3249   1.1  jdolecek 	 * of queues. So the driver uses polling mode to retrieve this
   3250   1.1  jdolecek 	 * information
   3251   1.1  jdolecek 	 */
   3252   1.1  jdolecek 	ena_com_set_admin_polling_mode(ena_dev, true);
   3253   1.1  jdolecek 
   3254   1.1  jdolecek 	ena_config_host_info(ena_dev);
   3255   1.1  jdolecek 
   3256   1.1  jdolecek 	/* Get Device Attributes */
   3257   1.1  jdolecek 	rc = ena_com_get_dev_attr_feat(ena_dev, get_feat_ctx);
   3258   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3259   1.1  jdolecek 		device_printf(pdev,
   3260   1.1  jdolecek 		    "Cannot get attribute for ena device rc: %d\n", rc);
   3261   1.1  jdolecek 		goto err_admin_init;
   3262   1.1  jdolecek 	}
   3263   1.1  jdolecek 
   3264   1.1  jdolecek 	aenq_groups = BIT(ENA_ADMIN_LINK_CHANGE) | BIT(ENA_ADMIN_KEEP_ALIVE);
   3265   1.1  jdolecek 
   3266   1.1  jdolecek 	aenq_groups &= get_feat_ctx->aenq.supported_groups;
   3267   1.1  jdolecek 	rc = ena_com_set_aenq_config(ena_dev, aenq_groups);
   3268   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3269   1.1  jdolecek 		device_printf(pdev, "Cannot configure aenq groups rc: %d\n", rc);
   3270   1.1  jdolecek 		goto err_admin_init;
   3271   1.1  jdolecek 	}
   3272   1.1  jdolecek 
   3273   1.1  jdolecek 	*wd_active = !!(aenq_groups & BIT(ENA_ADMIN_KEEP_ALIVE));
   3274   1.1  jdolecek 
   3275   1.1  jdolecek 	return (0);
   3276   1.1  jdolecek 
   3277   1.1  jdolecek err_admin_init:
   3278   1.1  jdolecek 	ena_com_delete_host_info(ena_dev);
   3279   1.1  jdolecek 	ena_com_admin_destroy(ena_dev);
   3280   1.1  jdolecek err_mmio_read_less:
   3281   1.1  jdolecek 	ena_com_mmio_reg_read_request_destroy(ena_dev);
   3282   1.1  jdolecek 
   3283   1.1  jdolecek 	return (rc);
   3284   1.1  jdolecek }
   3285   1.1  jdolecek 
   3286   1.1  jdolecek static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
   3287   1.1  jdolecek     int io_vectors)
   3288   1.1  jdolecek {
   3289   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   3290   1.1  jdolecek 	int rc;
   3291   1.1  jdolecek 
   3292   1.1  jdolecek 	rc = ena_enable_msix(adapter);
   3293   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3294   1.1  jdolecek 		device_printf(adapter->pdev, "Error with MSI-X enablement\n");
   3295   1.1  jdolecek 		return (rc);
   3296   1.1  jdolecek 	}
   3297   1.1  jdolecek 
   3298   1.1  jdolecek 	rc = ena_request_mgmnt_irq(adapter);
   3299   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3300   1.1  jdolecek 		device_printf(adapter->pdev, "Cannot setup mgmnt queue intr\n");
   3301   1.1  jdolecek 		goto err_disable_msix;
   3302   1.1  jdolecek 	}
   3303   1.1  jdolecek 
   3304   1.1  jdolecek 	ena_com_set_admin_polling_mode(ena_dev, false);
   3305   1.1  jdolecek 
   3306   1.1  jdolecek 	ena_com_admin_aenq_enable(ena_dev);
   3307   1.1  jdolecek 
   3308   1.1  jdolecek 	return (0);
   3309   1.1  jdolecek 
   3310   1.1  jdolecek err_disable_msix:
   3311   1.1  jdolecek 	ena_disable_msix(adapter);
   3312   1.1  jdolecek 
   3313   1.1  jdolecek 	return (rc);
   3314   1.1  jdolecek }
   3315   1.1  jdolecek 
   3316   1.1  jdolecek /* Function called on ENA_ADMIN_KEEP_ALIVE event */
   3317   1.1  jdolecek static void ena_keep_alive_wd(void *adapter_data,
   3318   1.1  jdolecek     struct ena_admin_aenq_entry *aenq_e)
   3319   1.1  jdolecek {
   3320   1.1  jdolecek 	struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
   3321   1.1  jdolecek 	struct ena_admin_aenq_keep_alive_desc *desc;
   3322   1.1  jdolecek 	sbintime_t stime;
   3323   1.1  jdolecek 	uint64_t rx_drops;
   3324   1.1  jdolecek 
   3325   1.1  jdolecek 	desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e;
   3326   1.1  jdolecek 
   3327   1.1  jdolecek 	rx_drops = ((uint64_t)desc->rx_drops_high << 32) | desc->rx_drops_low;
   3328   1.1  jdolecek 	counter_u64_zero(adapter->hw_stats.rx_drops);
   3329   1.1  jdolecek 	counter_u64_add(adapter->hw_stats.rx_drops, rx_drops);
   3330   1.1  jdolecek 
   3331   1.1  jdolecek 	stime = getsbinuptime();
   3332   1.4  jdolecek 	(void) atomic_swap_64(&adapter->keep_alive_timestamp, stime);
   3333   1.1  jdolecek }
   3334   1.1  jdolecek 
   3335   1.1  jdolecek /* Check for keep alive expiration */
   3336   1.1  jdolecek static void check_for_missing_keep_alive(struct ena_adapter *adapter)
   3337   1.1  jdolecek {
   3338   1.1  jdolecek 	sbintime_t timestamp, time;
   3339   1.1  jdolecek 
   3340   1.1  jdolecek 	if (adapter->wd_active == 0)
   3341   1.1  jdolecek 		return;
   3342   1.1  jdolecek 
   3343   1.1  jdolecek 	if (likely(adapter->keep_alive_timeout == 0))
   3344   1.1  jdolecek 		return;
   3345   1.1  jdolecek 
   3346   1.4  jdolecek 	/* FreeBSD uses atomic_load_acq_64() in place of the membar + read */
   3347   1.4  jdolecek 	membar_sync();
   3348   1.4  jdolecek 	timestamp = adapter->keep_alive_timestamp;
   3349   1.4  jdolecek 
   3350   1.1  jdolecek 	time = getsbinuptime() - timestamp;
   3351   1.1  jdolecek 	if (unlikely(time > adapter->keep_alive_timeout)) {
   3352   1.1  jdolecek 		device_printf(adapter->pdev,
   3353   1.1  jdolecek 		    "Keep alive watchdog timeout.\n");
   3354   1.1  jdolecek 		counter_u64_add(adapter->dev_stats.wd_expired, 1);
   3355   1.1  jdolecek 		adapter->reset_reason = ENA_REGS_RESET_KEEP_ALIVE_TO;
   3356   1.1  jdolecek 		adapter->trigger_reset = true;
   3357   1.1  jdolecek 	}
   3358   1.1  jdolecek }
   3359   1.1  jdolecek 
   3360   1.1  jdolecek /* Check if admin queue is enabled */
   3361   1.1  jdolecek static void check_for_admin_com_state(struct ena_adapter *adapter)
   3362   1.1  jdolecek {
   3363   1.1  jdolecek 	if (unlikely(ena_com_get_admin_running_state(adapter->ena_dev) ==
   3364   1.1  jdolecek 	    false)) {
   3365   1.1  jdolecek 		device_printf(adapter->pdev,
   3366   1.1  jdolecek 		    "ENA admin queue is not in running state!\n");
   3367   1.1  jdolecek 		counter_u64_add(adapter->dev_stats.admin_q_pause, 1);
   3368   1.1  jdolecek 		adapter->reset_reason = ENA_REGS_RESET_ADMIN_TO;
   3369   1.1  jdolecek 		adapter->trigger_reset = true;
   3370   1.1  jdolecek 	}
   3371   1.1  jdolecek }
   3372   1.1  jdolecek 
   3373   1.1  jdolecek static int
   3374   1.1  jdolecek check_missing_comp_in_queue(struct ena_adapter *adapter,
   3375   1.1  jdolecek     struct ena_ring *tx_ring)
   3376   1.1  jdolecek {
   3377   1.1  jdolecek 	struct bintime curtime, time;
   3378   1.1  jdolecek 	struct ena_tx_buffer *tx_buf;
   3379   1.1  jdolecek 	uint32_t missed_tx = 0;
   3380   1.1  jdolecek 	int i;
   3381   1.1  jdolecek 
   3382   1.1  jdolecek 	getbinuptime(&curtime);
   3383   1.1  jdolecek 
   3384   1.1  jdolecek 	for (i = 0; i < tx_ring->ring_size; i++) {
   3385   1.1  jdolecek 		tx_buf = &tx_ring->tx_buffer_info[i];
   3386   1.1  jdolecek 
   3387   1.1  jdolecek 		if (bintime_isset(&tx_buf->timestamp) == 0)
   3388   1.1  jdolecek 			continue;
   3389   1.1  jdolecek 
   3390   1.1  jdolecek 		time = curtime;
   3391   1.1  jdolecek 		bintime_sub(&time, &tx_buf->timestamp);
   3392   1.1  jdolecek 
   3393   1.1  jdolecek 		/* Check again if packet is still waiting */
   3394   1.1  jdolecek 		if (unlikely(bttosbt(time) > adapter->missing_tx_timeout)) {
   3395   1.1  jdolecek 
   3396   1.1  jdolecek 			if (!tx_buf->print_once)
   3397   1.1  jdolecek 				ena_trace(ENA_WARNING, "Found a Tx that wasn't "
   3398   1.1  jdolecek 				    "completed on time, qid %d, index %d.\n",
   3399   1.1  jdolecek 				    tx_ring->qid, i);
   3400   1.1  jdolecek 
   3401   1.1  jdolecek 			tx_buf->print_once = true;
   3402   1.1  jdolecek 			missed_tx++;
   3403   1.1  jdolecek 			counter_u64_add(tx_ring->tx_stats.missing_tx_comp, 1);
   3404   1.1  jdolecek 
   3405   1.1  jdolecek 			if (unlikely(missed_tx >
   3406   1.1  jdolecek 			    adapter->missing_tx_threshold)) {
   3407   1.1  jdolecek 				device_printf(adapter->pdev,
   3408   1.1  jdolecek 				    "The number of lost tx completion "
   3409   1.1  jdolecek 				    "is above the threshold (%d > %d). "
   3410   1.1  jdolecek 				    "Reset the device\n",
   3411   1.1  jdolecek 				    missed_tx, adapter->missing_tx_threshold);
   3412   1.1  jdolecek 				adapter->reset_reason =
   3413   1.1  jdolecek 				    ENA_REGS_RESET_MISS_TX_CMPL;
   3414   1.1  jdolecek 				adapter->trigger_reset = true;
   3415   1.1  jdolecek 				return (EIO);
   3416   1.1  jdolecek 			}
   3417   1.1  jdolecek 		}
   3418   1.1  jdolecek 	}
   3419   1.1  jdolecek 
   3420   1.1  jdolecek 	return (0);
   3421   1.1  jdolecek }
   3422   1.1  jdolecek 
   3423   1.1  jdolecek /*
   3424   1.1  jdolecek  * Check for TX which were not completed on time.
   3425   1.1  jdolecek  * Timeout is defined by "missing_tx_timeout".
   3426   1.1  jdolecek  * Reset will be performed if number of incompleted
   3427   1.1  jdolecek  * transactions exceeds "missing_tx_threshold".
   3428   1.1  jdolecek  */
   3429   1.1  jdolecek static void
   3430   1.1  jdolecek check_for_missing_tx_completions(struct ena_adapter *adapter)
   3431   1.1  jdolecek {
   3432   1.1  jdolecek 	struct ena_ring *tx_ring;
   3433   1.1  jdolecek 	int i, budget, rc;
   3434   1.1  jdolecek 
   3435   1.1  jdolecek 	/* Make sure the driver doesn't turn the device in other process */
   3436   1.1  jdolecek 	rmb();
   3437   1.1  jdolecek 
   3438   1.1  jdolecek 	if (!adapter->up)
   3439   1.1  jdolecek 		return;
   3440   1.1  jdolecek 
   3441   1.1  jdolecek 	if (adapter->trigger_reset)
   3442   1.1  jdolecek 		return;
   3443   1.1  jdolecek 
   3444   1.1  jdolecek 	if (adapter->missing_tx_timeout == 0)
   3445   1.1  jdolecek 		return;
   3446   1.1  jdolecek 
   3447   1.1  jdolecek 	budget = adapter->missing_tx_max_queues;
   3448   1.1  jdolecek 
   3449   1.1  jdolecek 	for (i = adapter->next_monitored_tx_qid; i < adapter->num_queues; i++) {
   3450   1.1  jdolecek 		tx_ring = &adapter->tx_ring[i];
   3451   1.1  jdolecek 
   3452   1.1  jdolecek 		rc = check_missing_comp_in_queue(adapter, tx_ring);
   3453   1.1  jdolecek 		if (unlikely(rc != 0))
   3454   1.1  jdolecek 			return;
   3455   1.1  jdolecek 
   3456   1.1  jdolecek 		budget--;
   3457   1.1  jdolecek 		if (budget == 0) {
   3458   1.1  jdolecek 			i++;
   3459   1.1  jdolecek 			break;
   3460   1.1  jdolecek 		}
   3461   1.1  jdolecek 	}
   3462   1.1  jdolecek 
   3463   1.1  jdolecek 	adapter->next_monitored_tx_qid = i % adapter->num_queues;
   3464   1.1  jdolecek }
   3465   1.1  jdolecek 
   3466   1.1  jdolecek /* trigger deferred rx cleanup after 2 consecutive detections */
   3467   1.1  jdolecek #define EMPTY_RX_REFILL 2
   3468   1.1  jdolecek /* For the rare case where the device runs out of Rx descriptors and the
   3469   1.1  jdolecek  * msix handler failed to refill new Rx descriptors (due to a lack of memory
   3470   1.1  jdolecek  * for example).
   3471   1.1  jdolecek  * This case will lead to a deadlock:
   3472   1.1  jdolecek  * The device won't send interrupts since all the new Rx packets will be dropped
   3473   1.1  jdolecek  * The msix handler won't allocate new Rx descriptors so the device won't be
   3474   1.1  jdolecek  * able to send new packets.
   3475   1.1  jdolecek  *
   3476   1.1  jdolecek  * When such a situation is detected - execute rx cleanup task in another thread
   3477   1.1  jdolecek  */
   3478   1.1  jdolecek static void
   3479   1.1  jdolecek check_for_empty_rx_ring(struct ena_adapter *adapter)
   3480   1.1  jdolecek {
   3481   1.1  jdolecek 	struct ena_ring *rx_ring;
   3482   1.1  jdolecek 	int i, refill_required;
   3483   1.1  jdolecek 
   3484   1.1  jdolecek 	if (!adapter->up)
   3485   1.1  jdolecek 		return;
   3486   1.1  jdolecek 
   3487   1.1  jdolecek 	if (adapter->trigger_reset)
   3488   1.1  jdolecek 		return;
   3489   1.1  jdolecek 
   3490   1.1  jdolecek 	for (i = 0; i < adapter->num_queues; i++) {
   3491   1.1  jdolecek 		rx_ring = &adapter->rx_ring[i];
   3492   1.1  jdolecek 
   3493   1.1  jdolecek 		refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq);
   3494   1.1  jdolecek 		if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
   3495   1.1  jdolecek 			rx_ring->empty_rx_queue++;
   3496   1.1  jdolecek 
   3497   1.1  jdolecek 			if (rx_ring->empty_rx_queue >= EMPTY_RX_REFILL)	{
   3498   1.1  jdolecek 				counter_u64_add(rx_ring->rx_stats.empty_rx_ring,
   3499   1.1  jdolecek 				    1);
   3500   1.1  jdolecek 
   3501   1.1  jdolecek 				device_printf(adapter->pdev,
   3502   1.1  jdolecek 				    "trigger refill for ring %d\n", i);
   3503   1.1  jdolecek 
   3504  1.10  jmcneill 				if (atomic_cas_uint(&rx_ring->task_pending, 0, 1) == 0)
   3505  1.10  jmcneill 					workqueue_enqueue(rx_ring->cmpl_tq,
   3506  1.10  jmcneill 					    &rx_ring->cmpl_task, curcpu());
   3507   1.1  jdolecek 				rx_ring->empty_rx_queue = 0;
   3508   1.1  jdolecek 			}
   3509   1.1  jdolecek 		} else {
   3510   1.1  jdolecek 			rx_ring->empty_rx_queue = 0;
   3511   1.1  jdolecek 		}
   3512   1.1  jdolecek 	}
   3513   1.1  jdolecek }
   3514   1.1  jdolecek 
   3515   1.1  jdolecek static void
   3516   1.1  jdolecek ena_timer_service(void *data)
   3517   1.1  jdolecek {
   3518   1.1  jdolecek 	struct ena_adapter *adapter = (struct ena_adapter *)data;
   3519   1.1  jdolecek 	struct ena_admin_host_info *host_info =
   3520   1.1  jdolecek 	    adapter->ena_dev->host_attr.host_info;
   3521   1.1  jdolecek 
   3522   1.1  jdolecek 	check_for_missing_keep_alive(adapter);
   3523   1.1  jdolecek 
   3524   1.1  jdolecek 	check_for_admin_com_state(adapter);
   3525   1.1  jdolecek 
   3526   1.1  jdolecek 	check_for_missing_tx_completions(adapter);
   3527   1.1  jdolecek 
   3528   1.1  jdolecek 	check_for_empty_rx_ring(adapter);
   3529   1.1  jdolecek 
   3530   1.1  jdolecek 	if (host_info != NULL)
   3531   1.1  jdolecek 		ena_update_host_info(host_info, adapter->ifp);
   3532   1.1  jdolecek 
   3533   1.1  jdolecek 	if (unlikely(adapter->trigger_reset)) {
   3534   1.1  jdolecek 		device_printf(adapter->pdev, "Trigger reset is on\n");
   3535   1.4  jdolecek 		workqueue_enqueue(adapter->reset_tq, &adapter->reset_task,
   3536   1.4  jdolecek 		    curcpu());
   3537   1.1  jdolecek 		return;
   3538   1.1  jdolecek 	}
   3539   1.1  jdolecek 
   3540   1.1  jdolecek 	/*
   3541   1.1  jdolecek 	 * Schedule another timeout one second from now.
   3542   1.1  jdolecek 	 */
   3543   1.4  jdolecek 	callout_schedule(&adapter->timer_service, hz);
   3544   1.1  jdolecek }
   3545   1.1  jdolecek 
   3546   1.1  jdolecek static void
   3547   1.4  jdolecek ena_reset_task(struct work *wk, void *arg)
   3548   1.1  jdolecek {
   3549   1.1  jdolecek 	struct ena_com_dev_get_features_ctx get_feat_ctx;
   3550   1.1  jdolecek 	struct ena_adapter *adapter = (struct ena_adapter *)arg;
   3551   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   3552   1.1  jdolecek 	bool dev_up;
   3553   1.1  jdolecek 	int rc;
   3554   1.1  jdolecek 
   3555   1.1  jdolecek 	if (unlikely(!adapter->trigger_reset)) {
   3556   1.1  jdolecek 		device_printf(adapter->pdev,
   3557   1.1  jdolecek 		    "device reset scheduled but trigger_reset is off\n");
   3558   1.1  jdolecek 		return;
   3559   1.1  jdolecek 	}
   3560   1.1  jdolecek 
   3561   1.2  jdolecek 	rw_enter(&adapter->ioctl_sx, RW_WRITER);
   3562   1.1  jdolecek 
   3563   1.4  jdolecek 	callout_halt(&adapter->timer_service, &adapter->global_mtx);
   3564   1.1  jdolecek 
   3565   1.1  jdolecek 	dev_up = adapter->up;
   3566   1.1  jdolecek 
   3567   1.1  jdolecek 	ena_com_set_admin_running_state(ena_dev, false);
   3568   1.1  jdolecek 	ena_down(adapter);
   3569   1.1  jdolecek 	ena_free_mgmnt_irq(adapter);
   3570   1.1  jdolecek 	ena_disable_msix(adapter);
   3571   1.1  jdolecek 	ena_com_abort_admin_commands(ena_dev);
   3572   1.1  jdolecek 	ena_com_wait_for_abort_completion(ena_dev);
   3573   1.1  jdolecek 	ena_com_admin_destroy(ena_dev);
   3574   1.1  jdolecek 	ena_com_mmio_reg_read_request_destroy(ena_dev);
   3575   1.1  jdolecek 
   3576   1.1  jdolecek 	adapter->reset_reason = ENA_REGS_RESET_NORMAL;
   3577   1.1  jdolecek 	adapter->trigger_reset = false;
   3578   1.1  jdolecek 
   3579   1.1  jdolecek 	/* Finished destroy part. Restart the device */
   3580   1.1  jdolecek 	rc = ena_device_init(adapter, adapter->pdev, &get_feat_ctx,
   3581   1.1  jdolecek 	    &adapter->wd_active);
   3582   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3583   1.1  jdolecek 		device_printf(adapter->pdev,
   3584   1.1  jdolecek 		    "ENA device init failed! (err: %d)\n", rc);
   3585   1.1  jdolecek 		goto err_dev_free;
   3586   1.1  jdolecek 	}
   3587   1.1  jdolecek 
   3588   1.4  jdolecek 	/* XXX dealloc and realloc MSI-X, probably a waste */
   3589   1.1  jdolecek 	rc = ena_enable_msix_and_set_admin_interrupts(adapter,
   3590   1.1  jdolecek 	    adapter->num_queues);
   3591   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3592   1.1  jdolecek 		device_printf(adapter->pdev, "Enable MSI-X failed\n");
   3593   1.1  jdolecek 		goto err_com_free;
   3594   1.1  jdolecek 	}
   3595   1.1  jdolecek 
   3596   1.1  jdolecek 	/* If the interface was up before the reset bring it up */
   3597   1.1  jdolecek 	if (dev_up) {
   3598   1.1  jdolecek 		rc = ena_up(adapter);
   3599   1.1  jdolecek 		if (unlikely(rc != 0)) {
   3600   1.1  jdolecek 			device_printf(adapter->pdev,
   3601   1.1  jdolecek 			    "Failed to create I/O queues\n");
   3602   1.1  jdolecek 			goto err_msix_free;
   3603   1.1  jdolecek 		}
   3604   1.1  jdolecek 	}
   3605   1.1  jdolecek 
   3606   1.4  jdolecek 	callout_reset(&adapter->timer_service, hz,
   3607   1.4  jdolecek 	    ena_timer_service, (void *)adapter);
   3608   1.1  jdolecek 
   3609   1.2  jdolecek 	rw_exit(&adapter->ioctl_sx);
   3610   1.1  jdolecek 
   3611   1.1  jdolecek 	return;
   3612   1.1  jdolecek 
   3613   1.1  jdolecek err_msix_free:
   3614   1.1  jdolecek 	ena_free_mgmnt_irq(adapter);
   3615   1.1  jdolecek 	ena_disable_msix(adapter);
   3616   1.1  jdolecek err_com_free:
   3617   1.1  jdolecek 	ena_com_admin_destroy(ena_dev);
   3618   1.1  jdolecek err_dev_free:
   3619   1.1  jdolecek 	device_printf(adapter->pdev, "ENA reset failed!\n");
   3620   1.1  jdolecek 	adapter->running = false;
   3621   1.2  jdolecek 	rw_exit(&adapter->ioctl_sx);
   3622   1.1  jdolecek }
   3623   1.1  jdolecek 
   3624   1.1  jdolecek /**
   3625   1.1  jdolecek  * ena_attach - Device Initialization Routine
   3626   1.1  jdolecek  * @pdev: device information struct
   3627   1.1  jdolecek  *
   3628   1.1  jdolecek  * Returns 0 on success, otherwise on failure.
   3629   1.1  jdolecek  *
   3630   1.1  jdolecek  * ena_attach initializes an adapter identified by a device structure.
   3631   1.1  jdolecek  * The OS initialization, configuring of the adapter private structure,
   3632   1.1  jdolecek  * and a hardware reset occur.
   3633   1.1  jdolecek  **/
   3634   1.4  jdolecek static void
   3635   1.2  jdolecek ena_attach(device_t parent, device_t self, void *aux)
   3636   1.1  jdolecek {
   3637   1.2  jdolecek 	struct pci_attach_args *pa = aux;
   3638   1.1  jdolecek 	struct ena_com_dev_get_features_ctx get_feat_ctx;
   3639   1.1  jdolecek 	static int version_printed;
   3640   1.8  jmcneill 	struct ena_adapter *adapter = device_private(self);
   3641   1.1  jdolecek 	struct ena_com_dev *ena_dev = NULL;
   3642   1.1  jdolecek 	uint16_t tx_sgl_size = 0;
   3643   1.1  jdolecek 	uint16_t rx_sgl_size = 0;
   3644   1.2  jdolecek 	pcireg_t reg;
   3645   1.1  jdolecek 	int io_queue_num;
   3646   1.1  jdolecek 	int queue_size;
   3647   1.1  jdolecek 	int rc;
   3648   1.1  jdolecek 
   3649   1.2  jdolecek 	adapter->pdev = self;
   3650   1.2  jdolecek 	adapter->ifp = &adapter->sc_ec.ec_if;
   3651   1.4  jdolecek 	adapter->sc_pa = *pa;	/* used after attach for adapter reset too */
   3652   1.2  jdolecek 
   3653   1.2  jdolecek 	if (pci_dma64_available(pa))
   3654   1.2  jdolecek 		adapter->sc_dmat = pa->pa_dmat64;
   3655   1.2  jdolecek 	else
   3656   1.2  jdolecek 		adapter->sc_dmat = pa->pa_dmat;
   3657   1.2  jdolecek 
   3658   1.2  jdolecek 	pci_aprint_devinfo(pa, NULL);
   3659   1.2  jdolecek 
   3660   1.2  jdolecek 	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
   3661   1.2  jdolecek 	if ((reg & PCI_COMMAND_MASTER_ENABLE) == 0) {
   3662   1.2  jdolecek 		reg |= PCI_COMMAND_MASTER_ENABLE;
   3663   1.2  jdolecek         	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);
   3664   1.2  jdolecek 	}
   3665   1.2  jdolecek 
   3666   1.2  jdolecek 	mutex_init(&adapter->global_mtx, MUTEX_DEFAULT, IPL_NET);
   3667   1.2  jdolecek 	rw_init(&adapter->ioctl_sx);
   3668   1.1  jdolecek 
   3669   1.1  jdolecek 	/* Set up the timer service */
   3670   1.1  jdolecek 	adapter->keep_alive_timeout = DEFAULT_KEEP_ALIVE_TO;
   3671   1.1  jdolecek 	adapter->missing_tx_timeout = DEFAULT_TX_CMP_TO;
   3672   1.1  jdolecek 	adapter->missing_tx_max_queues = DEFAULT_TX_MONITORED_QUEUES;
   3673   1.1  jdolecek 	adapter->missing_tx_threshold = DEFAULT_TX_CMP_THRESHOLD;
   3674   1.1  jdolecek 
   3675   1.1  jdolecek 	if (version_printed++ == 0)
   3676   1.2  jdolecek 		device_printf(parent, "%s\n", ena_version);
   3677   1.1  jdolecek 
   3678   1.4  jdolecek 	rc = ena_allocate_pci_resources(pa, adapter);
   3679   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3680   1.2  jdolecek 		device_printf(parent, "PCI resource allocation failed!\n");
   3681   1.1  jdolecek 		ena_free_pci_resources(adapter);
   3682   1.4  jdolecek 		return;
   3683   1.1  jdolecek 	}
   3684   1.1  jdolecek 
   3685   1.1  jdolecek 	/* Allocate memory for ena_dev structure */
   3686   1.1  jdolecek 	ena_dev = malloc(sizeof(struct ena_com_dev), M_DEVBUF,
   3687   1.1  jdolecek 	    M_WAITOK | M_ZERO);
   3688   1.1  jdolecek 
   3689   1.1  jdolecek 	adapter->ena_dev = ena_dev;
   3690   1.2  jdolecek 	ena_dev->dmadev = self;
   3691   1.1  jdolecek 	ena_dev->bus = malloc(sizeof(struct ena_bus), M_DEVBUF,
   3692   1.1  jdolecek 	    M_WAITOK | M_ZERO);
   3693   1.1  jdolecek 
   3694   1.1  jdolecek 	/* Store register resources */
   3695   1.4  jdolecek 	((struct ena_bus*)(ena_dev->bus))->reg_bar_t = adapter->sc_btag;
   3696   1.4  jdolecek 	((struct ena_bus*)(ena_dev->bus))->reg_bar_h = adapter->sc_bhandle;
   3697   1.1  jdolecek 
   3698   1.1  jdolecek 	ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
   3699   1.1  jdolecek 
   3700   1.1  jdolecek 	/* Device initialization */
   3701   1.4  jdolecek 	rc = ena_device_init(adapter, self, &get_feat_ctx, &adapter->wd_active);
   3702   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3703   1.4  jdolecek 		device_printf(self, "ENA device init failed! (err: %d)\n", rc);
   3704   1.1  jdolecek 		rc = ENXIO;
   3705   1.1  jdolecek 		goto err_bus_free;
   3706   1.1  jdolecek 	}
   3707   1.1  jdolecek 
   3708   1.1  jdolecek 	adapter->keep_alive_timestamp = getsbinuptime();
   3709   1.1  jdolecek 
   3710   1.1  jdolecek 	adapter->tx_offload_cap = get_feat_ctx.offload.tx;
   3711   1.1  jdolecek 
   3712   1.1  jdolecek 	/* Set for sure that interface is not up */
   3713   1.1  jdolecek 	adapter->up = false;
   3714   1.1  jdolecek 
   3715   1.1  jdolecek 	memcpy(adapter->mac_addr, get_feat_ctx.dev_attr.mac_addr,
   3716   1.1  jdolecek 	    ETHER_ADDR_LEN);
   3717   1.1  jdolecek 
   3718   1.1  jdolecek 	/* calculate IO queue number to create */
   3719   1.4  jdolecek 	io_queue_num = ena_calc_io_queue_num(pa, adapter, &get_feat_ctx);
   3720   1.1  jdolecek 
   3721   1.1  jdolecek 	ENA_ASSERT(io_queue_num > 0, "Invalid queue number: %d\n",
   3722   1.1  jdolecek 	    io_queue_num);
   3723   1.1  jdolecek 	adapter->num_queues = io_queue_num;
   3724   1.1  jdolecek 
   3725   1.1  jdolecek 	adapter->max_mtu = get_feat_ctx.dev_attr.max_mtu;
   3726   1.1  jdolecek 
   3727   1.1  jdolecek 	/* calculatre ring sizes */
   3728   1.1  jdolecek 	queue_size = ena_calc_queue_size(adapter,&tx_sgl_size,
   3729   1.1  jdolecek 	    &rx_sgl_size, &get_feat_ctx);
   3730   1.1  jdolecek 	if (unlikely((queue_size <= 0) || (io_queue_num <= 0))) {
   3731   1.1  jdolecek 		rc = ENA_COM_FAULT;
   3732   1.1  jdolecek 		goto err_com_free;
   3733   1.1  jdolecek 	}
   3734   1.1  jdolecek 
   3735   1.1  jdolecek 	adapter->reset_reason = ENA_REGS_RESET_NORMAL;
   3736   1.1  jdolecek 
   3737   1.1  jdolecek 	adapter->tx_ring_size = queue_size;
   3738   1.1  jdolecek 	adapter->rx_ring_size = queue_size;
   3739   1.1  jdolecek 
   3740   1.1  jdolecek 	adapter->max_tx_sgl_size = tx_sgl_size;
   3741   1.1  jdolecek 	adapter->max_rx_sgl_size = rx_sgl_size;
   3742   1.1  jdolecek 
   3743   1.4  jdolecek #if 0
   3744   1.1  jdolecek 	/* set up dma tags for rx and tx buffers */
   3745   1.1  jdolecek 	rc = ena_setup_tx_dma_tag(adapter);
   3746   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3747   1.4  jdolecek 		device_printf(self, "Failed to create TX DMA tag\n");
   3748   1.1  jdolecek 		goto err_com_free;
   3749   1.1  jdolecek 	}
   3750   1.1  jdolecek 
   3751   1.1  jdolecek 	rc = ena_setup_rx_dma_tag(adapter);
   3752   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3753   1.4  jdolecek 		device_printf(self, "Failed to create RX DMA tag\n");
   3754   1.1  jdolecek 		goto err_tx_tag_free;
   3755   1.1  jdolecek 	}
   3756   1.4  jdolecek #endif
   3757   1.1  jdolecek 
   3758   1.1  jdolecek 	/* initialize rings basic information */
   3759   1.4  jdolecek 	device_printf(self, "initalize %d io queues\n", io_queue_num);
   3760   1.1  jdolecek 	ena_init_io_rings(adapter);
   3761   1.1  jdolecek 
   3762   1.1  jdolecek 	/* setup network interface */
   3763   1.4  jdolecek 	rc = ena_setup_ifnet(self, adapter, &get_feat_ctx);
   3764   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3765   1.4  jdolecek 		device_printf(self, "Error with network interface setup\n");
   3766   1.1  jdolecek 		goto err_io_free;
   3767   1.1  jdolecek 	}
   3768   1.1  jdolecek 
   3769   1.1  jdolecek 	rc = ena_enable_msix_and_set_admin_interrupts(adapter, io_queue_num);
   3770   1.1  jdolecek 	if (unlikely(rc != 0)) {
   3771   1.4  jdolecek 		device_printf(self,
   3772   1.1  jdolecek 		    "Failed to enable and set the admin interrupts\n");
   3773   1.1  jdolecek 		goto err_ifp_free;
   3774   1.1  jdolecek 	}
   3775   1.1  jdolecek 
   3776  1.10  jmcneill 	callout_init(&adapter->timer_service, CALLOUT_MPSAFE);
   3777  1.10  jmcneill 
   3778   1.1  jdolecek 	/* Initialize reset task queue */
   3779  1.10  jmcneill 	rc = workqueue_create(&adapter->reset_tq, "ena_reset_enq",
   3780  1.10  jmcneill 	    ena_reset_task, adapter, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
   3781   1.4  jdolecek 	if (unlikely(rc != 0)) {
   3782   1.4  jdolecek 		ena_trace(ENA_ALERT,
   3783   1.4  jdolecek 		    "Unable to create workqueue for reset task\n");
   3784   1.4  jdolecek 		goto err_ifp_free;
   3785   1.4  jdolecek 	}
   3786   1.1  jdolecek 
   3787   1.1  jdolecek 	/* Initialize statistics */
   3788   1.4  jdolecek 	ena_alloc_counters_dev(&adapter->dev_stats, io_queue_num);
   3789   1.4  jdolecek 	ena_alloc_counters_hwstats(&adapter->hw_stats, io_queue_num);
   3790   1.4  jdolecek #if 0
   3791   1.1  jdolecek 	ena_sysctl_add_nodes(adapter);
   3792   1.4  jdolecek #endif
   3793   1.1  jdolecek 
   3794   1.1  jdolecek 	/* Tell the stack that the interface is not active */
   3795   1.4  jdolecek 	if_setdrvflagbits(adapter->ifp, IFF_OACTIVE, IFF_RUNNING);
   3796   1.1  jdolecek 
   3797   1.1  jdolecek 	adapter->running = true;
   3798   1.4  jdolecek 	return;
   3799   1.1  jdolecek 
   3800   1.1  jdolecek err_ifp_free:
   3801   1.1  jdolecek 	if_detach(adapter->ifp);
   3802   1.1  jdolecek 	if_free(adapter->ifp);
   3803   1.1  jdolecek err_io_free:
   3804   1.1  jdolecek 	ena_free_all_io_rings_resources(adapter);
   3805   1.4  jdolecek #if 0
   3806   1.1  jdolecek 	ena_free_rx_dma_tag(adapter);
   3807   1.1  jdolecek err_tx_tag_free:
   3808   1.1  jdolecek 	ena_free_tx_dma_tag(adapter);
   3809   1.4  jdolecek #endif
   3810   1.1  jdolecek err_com_free:
   3811   1.1  jdolecek 	ena_com_admin_destroy(ena_dev);
   3812   1.1  jdolecek 	ena_com_delete_host_info(ena_dev);
   3813   1.1  jdolecek 	ena_com_mmio_reg_read_request_destroy(ena_dev);
   3814   1.1  jdolecek err_bus_free:
   3815   1.1  jdolecek 	free(ena_dev->bus, M_DEVBUF);
   3816   1.1  jdolecek 	free(ena_dev, M_DEVBUF);
   3817   1.1  jdolecek 	ena_free_pci_resources(adapter);
   3818   1.1  jdolecek }
   3819   1.1  jdolecek 
   3820   1.1  jdolecek /**
   3821   1.1  jdolecek  * ena_detach - Device Removal Routine
   3822   1.1  jdolecek  * @pdev: device information struct
   3823   1.1  jdolecek  *
   3824   1.1  jdolecek  * ena_detach is called by the device subsystem to alert the driver
   3825   1.1  jdolecek  * that it should release a PCI device.
   3826   1.1  jdolecek  **/
   3827   1.1  jdolecek static int
   3828   1.4  jdolecek ena_detach(device_t pdev, int flags)
   3829   1.1  jdolecek {
   3830   1.2  jdolecek 	struct ena_adapter *adapter = device_private(pdev);
   3831   1.1  jdolecek 	struct ena_com_dev *ena_dev = adapter->ena_dev;
   3832   1.4  jdolecek #if 0
   3833   1.1  jdolecek 	int rc;
   3834   1.4  jdolecek #endif
   3835   1.1  jdolecek 
   3836   1.1  jdolecek 	/* Make sure VLANS are not using driver */
   3837   1.4  jdolecek 	if (VLAN_ATTACHED(&adapter->sc_ec)) {
   3838   1.1  jdolecek 		device_printf(adapter->pdev ,"VLAN is in use, detach first\n");
   3839   1.1  jdolecek 		return (EBUSY);
   3840   1.1  jdolecek 	}
   3841   1.1  jdolecek 
   3842   1.1  jdolecek 	/* Free reset task and callout */
   3843   1.4  jdolecek 	callout_halt(&adapter->timer_service, &adapter->global_mtx);
   3844  1.10  jmcneill 	callout_destroy(&adapter->timer_service);
   3845   1.4  jdolecek 	workqueue_wait(adapter->reset_tq, &adapter->reset_task);
   3846   1.4  jdolecek 	workqueue_destroy(adapter->reset_tq);
   3847   1.4  jdolecek 	adapter->reset_tq = NULL;
   3848   1.1  jdolecek 
   3849   1.2  jdolecek 	rw_enter(&adapter->ioctl_sx, RW_WRITER);
   3850   1.1  jdolecek 	ena_down(adapter);
   3851   1.2  jdolecek 	rw_exit(&adapter->ioctl_sx);
   3852   1.1  jdolecek 
   3853   1.1  jdolecek 	if (adapter->ifp != NULL) {
   3854   1.1  jdolecek 		ether_ifdetach(adapter->ifp);
   3855   1.1  jdolecek 		if_free(adapter->ifp);
   3856   1.1  jdolecek 	}
   3857   1.1  jdolecek 
   3858   1.1  jdolecek 	ena_free_all_io_rings_resources(adapter);
   3859   1.1  jdolecek 
   3860   1.2  jdolecek 	ena_free_counters((struct evcnt *)&adapter->hw_stats,
   3861   1.1  jdolecek 	    sizeof(struct ena_hw_stats));
   3862   1.2  jdolecek 	ena_free_counters((struct evcnt *)&adapter->dev_stats,
   3863   1.1  jdolecek 	    sizeof(struct ena_stats_dev));
   3864   1.1  jdolecek 
   3865   1.1  jdolecek 	if (likely(adapter->rss_support))
   3866   1.1  jdolecek 		ena_com_rss_destroy(ena_dev);
   3867   1.1  jdolecek 
   3868   1.4  jdolecek #if 0
   3869   1.1  jdolecek 	rc = ena_free_rx_dma_tag(adapter);
   3870   1.1  jdolecek 	if (unlikely(rc != 0))
   3871   1.1  jdolecek 		device_printf(adapter->pdev,
   3872   1.1  jdolecek 		    "Unmapped RX DMA tag associations\n");
   3873   1.1  jdolecek 
   3874   1.1  jdolecek 	rc = ena_free_tx_dma_tag(adapter);
   3875   1.1  jdolecek 	if (unlikely(rc != 0))
   3876   1.1  jdolecek 		device_printf(adapter->pdev,
   3877   1.1  jdolecek 		    "Unmapped TX DMA tag associations\n");
   3878   1.4  jdolecek #endif
   3879   1.1  jdolecek 
   3880   1.1  jdolecek 	/* Reset the device only if the device is running. */
   3881   1.1  jdolecek 	if (adapter->running)
   3882   1.1  jdolecek 		ena_com_dev_reset(ena_dev, adapter->reset_reason);
   3883   1.1  jdolecek 
   3884   1.1  jdolecek 	ena_com_delete_host_info(ena_dev);
   3885   1.1  jdolecek 
   3886   1.1  jdolecek 	ena_free_irqs(adapter);
   3887   1.1  jdolecek 
   3888   1.1  jdolecek 	ena_com_abort_admin_commands(ena_dev);
   3889   1.1  jdolecek 
   3890   1.1  jdolecek 	ena_com_wait_for_abort_completion(ena_dev);
   3891   1.1  jdolecek 
   3892   1.1  jdolecek 	ena_com_admin_destroy(ena_dev);
   3893   1.1  jdolecek 
   3894   1.1  jdolecek 	ena_com_mmio_reg_read_request_destroy(ena_dev);
   3895   1.1  jdolecek 
   3896   1.1  jdolecek 	ena_free_pci_resources(adapter);
   3897   1.1  jdolecek 
   3898   1.2  jdolecek 	mutex_destroy(&adapter->global_mtx);
   3899   1.2  jdolecek 	rw_destroy(&adapter->ioctl_sx);
   3900   1.1  jdolecek 
   3901   1.1  jdolecek 	if (ena_dev->bus != NULL)
   3902   1.1  jdolecek 		free(ena_dev->bus, M_DEVBUF);
   3903   1.1  jdolecek 
   3904   1.1  jdolecek 	if (ena_dev != NULL)
   3905   1.1  jdolecek 		free(ena_dev, M_DEVBUF);
   3906   1.1  jdolecek 
   3907   1.4  jdolecek 	return 0;
   3908   1.1  jdolecek }
   3909   1.1  jdolecek 
   3910   1.1  jdolecek /******************************************************************************
   3911   1.1  jdolecek  ******************************** AENQ Handlers *******************************
   3912   1.1  jdolecek  *****************************************************************************/
   3913   1.1  jdolecek /**
   3914   1.1  jdolecek  * ena_update_on_link_change:
   3915   1.1  jdolecek  * Notify the network interface about the change in link status
   3916   1.1  jdolecek  **/
   3917   1.1  jdolecek static void
   3918   1.1  jdolecek ena_update_on_link_change(void *adapter_data,
   3919   1.1  jdolecek     struct ena_admin_aenq_entry *aenq_e)
   3920   1.1  jdolecek {
   3921   1.1  jdolecek 	struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
   3922   1.1  jdolecek 	struct ena_admin_aenq_link_change_desc *aenq_desc;
   3923   1.1  jdolecek 	int status;
   3924   1.2  jdolecek 	struct ifnet *ifp;
   3925   1.1  jdolecek 
   3926   1.1  jdolecek 	aenq_desc = (struct ena_admin_aenq_link_change_desc *)aenq_e;
   3927   1.1  jdolecek 	ifp = adapter->ifp;
   3928   1.1  jdolecek 	status = aenq_desc->flags &
   3929   1.1  jdolecek 	    ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK;
   3930   1.1  jdolecek 
   3931   1.1  jdolecek 	if (status != 0) {
   3932   1.1  jdolecek 		device_printf(adapter->pdev, "link is UP\n");
   3933   1.1  jdolecek 		if_link_state_change(ifp, LINK_STATE_UP);
   3934   1.1  jdolecek 	} else if (status == 0) {
   3935   1.1  jdolecek 		device_printf(adapter->pdev, "link is DOWN\n");
   3936   1.1  jdolecek 		if_link_state_change(ifp, LINK_STATE_DOWN);
   3937   1.1  jdolecek 	} else {
   3938   1.1  jdolecek 		device_printf(adapter->pdev, "invalid value recvd\n");
   3939   1.1  jdolecek 		BUG();
   3940   1.1  jdolecek 	}
   3941   1.1  jdolecek 
   3942   1.1  jdolecek 	adapter->link_status = status;
   3943   1.1  jdolecek }
   3944   1.1  jdolecek 
   3945   1.1  jdolecek /**
   3946   1.1  jdolecek  * This handler will called for unknown event group or unimplemented handlers
   3947   1.1  jdolecek  **/
   3948   1.1  jdolecek static void
   3949   1.1  jdolecek unimplemented_aenq_handler(void *data,
   3950   1.1  jdolecek     struct ena_admin_aenq_entry *aenq_e)
   3951   1.1  jdolecek {
   3952   1.1  jdolecek 	return;
   3953   1.1  jdolecek }
   3954   1.1  jdolecek 
   3955   1.1  jdolecek static struct ena_aenq_handlers aenq_handlers = {
   3956   1.1  jdolecek     .handlers = {
   3957   1.1  jdolecek 	    [ENA_ADMIN_LINK_CHANGE] = ena_update_on_link_change,
   3958   1.1  jdolecek 	    [ENA_ADMIN_KEEP_ALIVE] = ena_keep_alive_wd,
   3959   1.1  jdolecek     },
   3960   1.1  jdolecek     .unimplemented_handler = unimplemented_aenq_handler
   3961   1.1  jdolecek };
   3962   1.1  jdolecek 
   3963   1.2  jdolecek #ifdef __FreeBSD__
   3964   1.1  jdolecek /*********************************************************************
   3965   1.1  jdolecek  *  FreeBSD Device Interface Entry Points
   3966   1.1  jdolecek  *********************************************************************/
   3967   1.1  jdolecek 
   3968   1.1  jdolecek static device_method_t ena_methods[] = {
   3969   1.1  jdolecek     /* Device interface */
   3970   1.1  jdolecek     DEVMETHOD(device_probe, ena_probe),
   3971   1.1  jdolecek     DEVMETHOD(device_attach, ena_attach),
   3972   1.1  jdolecek     DEVMETHOD(device_detach, ena_detach),
   3973   1.1  jdolecek     DEVMETHOD_END
   3974   1.1  jdolecek };
   3975   1.1  jdolecek 
   3976   1.1  jdolecek static driver_t ena_driver = {
   3977   1.1  jdolecek     "ena", ena_methods, sizeof(struct ena_adapter),
   3978   1.1  jdolecek };
   3979   1.1  jdolecek 
   3980   1.1  jdolecek devclass_t ena_devclass;
   3981   1.1  jdolecek DRIVER_MODULE(ena, pci, ena_driver, ena_devclass, 0, 0);
   3982   1.1  jdolecek MODULE_DEPEND(ena, pci, 1, 1, 1);
   3983   1.1  jdolecek MODULE_DEPEND(ena, ether, 1, 1, 1);
   3984   1.1  jdolecek 
   3985   1.1  jdolecek /*********************************************************************/
   3986   1.2  jdolecek #endif /* __FreeBSD__ */
   3987   1.4  jdolecek 
   3988   1.4  jdolecek #ifdef __NetBSD__
   3989   1.4  jdolecek CFATTACH_DECL_NEW(ena, sizeof(struct ena_adapter), ena_probe, ena_attach,
   3990   1.4  jdolecek 	ena_detach, NULL);
   3991   1.4  jdolecek #endif /* __NetBSD */
   3992