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