1 1.10 andvar /* $NetBSD: if_enavar.h,v 1.10 2024/02/09 22:08:35 andvar Exp $ */ 2 1.2 jdolecek 3 1.1 jdolecek /*- 4 1.1 jdolecek * BSD LICENSE 5 1.1 jdolecek * 6 1.1 jdolecek * Copyright (c) 2015-2017 Amazon.com, Inc. or its affiliates. 7 1.1 jdolecek * All rights reserved. 8 1.1 jdolecek * 9 1.1 jdolecek * Redistribution and use in source and binary forms, with or without 10 1.1 jdolecek * modification, are permitted provided that the following conditions 11 1.1 jdolecek * are met: 12 1.1 jdolecek * 13 1.1 jdolecek * 1. Redistributions of source code must retain the above copyright 14 1.1 jdolecek * notice, this list of conditions and the following disclaimer. 15 1.1 jdolecek * 16 1.1 jdolecek * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 jdolecek * notice, this list of conditions and the following disclaimer in the 18 1.1 jdolecek * documentation and/or other materials provided with the distribution. 19 1.1 jdolecek * 20 1.1 jdolecek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 1.1 jdolecek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 1.1 jdolecek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 1.1 jdolecek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 1.1 jdolecek * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 1.1 jdolecek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 1.1 jdolecek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 jdolecek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 jdolecek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 jdolecek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 1.1 jdolecek * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 jdolecek * 32 1.1 jdolecek * $FreeBSD: head/sys/dev/ena/ena.h 333450 2018-05-10 09:06:21Z mw $ 33 1.1 jdolecek * 34 1.1 jdolecek */ 35 1.1 jdolecek 36 1.1 jdolecek #ifndef ENA_H 37 1.1 jdolecek #define ENA_H 38 1.1 jdolecek 39 1.1 jdolecek #include <sys/types.h> 40 1.8 jmcneill #include <sys/atomic.h> 41 1.8 jmcneill #include <sys/pcq.h> 42 1.1 jdolecek 43 1.2 jdolecek #include "external/bsd/ena-com/ena_com.h" 44 1.2 jdolecek #include "external/bsd/ena-com/ena_eth_com.h" 45 1.1 jdolecek 46 1.1 jdolecek #define DRV_MODULE_VER_MAJOR 0 47 1.1 jdolecek #define DRV_MODULE_VER_MINOR 8 48 1.1 jdolecek #define DRV_MODULE_VER_SUBMINOR 1 49 1.1 jdolecek 50 1.1 jdolecek #define DRV_MODULE_NAME "ena" 51 1.1 jdolecek 52 1.1 jdolecek #ifndef DRV_MODULE_VERSION 53 1.1 jdolecek #define DRV_MODULE_VERSION \ 54 1.7 jmcneill ___STRING(DRV_MODULE_VER_MAJOR) "." \ 55 1.7 jmcneill ___STRING(DRV_MODULE_VER_MINOR) "." \ 56 1.7 jmcneill ___STRING(DRV_MODULE_VER_SUBMINOR) 57 1.1 jdolecek #endif 58 1.1 jdolecek #define DEVICE_NAME "Elastic Network Adapter (ENA)" 59 1.1 jdolecek #define DEVICE_DESC "ENA adapter" 60 1.1 jdolecek 61 1.1 jdolecek /* Calculate DMA mask - width for ena cannot exceed 48, so it is safe */ 62 1.1 jdolecek #define ENA_DMA_BIT_MASK(x) ((1ULL << (x)) - 1ULL) 63 1.1 jdolecek 64 1.1 jdolecek /* 1 for AENQ + ADMIN */ 65 1.1 jdolecek #define ENA_ADMIN_MSIX_VEC 1 66 1.1 jdolecek #define ENA_MAX_MSIX_VEC(io_queues) (ENA_ADMIN_MSIX_VEC + (io_queues)) 67 1.1 jdolecek 68 1.5 jmcneill #define ENA_REG_BAR PCI_BAR(0) 69 1.5 jmcneill #define ENA_MEM_BAR PCI_BAR(2) 70 1.1 jdolecek 71 1.1 jdolecek #define ENA_BUS_DMA_SEGS 32 72 1.1 jdolecek 73 1.1 jdolecek #define ENA_DEFAULT_RING_SIZE 1024 74 1.1 jdolecek 75 1.1 jdolecek #define ENA_RX_REFILL_THRESH_DIVIDER 8 76 1.1 jdolecek 77 1.1 jdolecek #define ENA_IRQNAME_SIZE 40 78 1.1 jdolecek 79 1.1 jdolecek #define ENA_PKT_MAX_BUFS 19 80 1.1 jdolecek 81 1.1 jdolecek #define ENA_RX_RSS_TABLE_LOG_SIZE 7 82 1.1 jdolecek #define ENA_RX_RSS_TABLE_SIZE (1 << ENA_RX_RSS_TABLE_LOG_SIZE) 83 1.1 jdolecek 84 1.1 jdolecek #define ENA_HASH_KEY_SIZE 40 85 1.1 jdolecek 86 1.1 jdolecek #define ENA_MAX_FRAME_LEN 10000 87 1.1 jdolecek #define ENA_MIN_FRAME_LEN 60 88 1.1 jdolecek 89 1.1 jdolecek #define ENA_TX_CLEANUP_THRESHOLD 128 90 1.1 jdolecek 91 1.1 jdolecek #define DB_THRESHOLD 64 92 1.1 jdolecek 93 1.1 jdolecek #define TX_COMMIT 32 94 1.1 jdolecek /* 95 1.1 jdolecek * TX budget for cleaning. It should be half of the RX budget to reduce amount 96 1.1 jdolecek * of TCP retransmissions. 97 1.1 jdolecek */ 98 1.1 jdolecek #define TX_BUDGET 128 99 1.1 jdolecek /* RX cleanup budget. -1 stands for infinity. */ 100 1.1 jdolecek #define RX_BUDGET 256 101 1.1 jdolecek /* 102 1.1 jdolecek * How many times we can repeat cleanup in the io irq handling routine if the 103 1.1 jdolecek * RX or TX budget was depleted. 104 1.1 jdolecek */ 105 1.1 jdolecek #define CLEAN_BUDGET 8 106 1.1 jdolecek 107 1.1 jdolecek #define RX_IRQ_INTERVAL 20 108 1.1 jdolecek #define TX_IRQ_INTERVAL 50 109 1.1 jdolecek 110 1.1 jdolecek #define ENA_MIN_MTU 128 111 1.1 jdolecek 112 1.1 jdolecek #define ENA_TSO_MAXSIZE 65536 113 1.1 jdolecek 114 1.1 jdolecek #define ENA_MMIO_DISABLE_REG_READ BIT(0) 115 1.1 jdolecek 116 1.1 jdolecek #define ENA_TX_RING_IDX_NEXT(idx, ring_size) (((idx) + 1) & ((ring_size) - 1)) 117 1.1 jdolecek 118 1.1 jdolecek #define ENA_RX_RING_IDX_NEXT(idx, ring_size) (((idx) + 1) & ((ring_size) - 1)) 119 1.1 jdolecek 120 1.1 jdolecek #define ENA_IO_TXQ_IDX(q) (2 * (q)) 121 1.1 jdolecek #define ENA_IO_RXQ_IDX(q) (2 * (q) + 1) 122 1.1 jdolecek 123 1.1 jdolecek #define ENA_MGMNT_IRQ_IDX 0 124 1.1 jdolecek #define ENA_IO_IRQ_FIRST_IDX 1 125 1.1 jdolecek #define ENA_IO_IRQ_IDX(q) (ENA_IO_IRQ_FIRST_IDX + (q)) 126 1.1 jdolecek 127 1.1 jdolecek /* 128 1.1 jdolecek * ENA device should send keep alive msg every 1 sec. 129 1.1 jdolecek * We wait for 6 sec just to be on the safe side. 130 1.1 jdolecek */ 131 1.1 jdolecek #define DEFAULT_KEEP_ALIVE_TO (SBT_1S * 6) 132 1.1 jdolecek 133 1.1 jdolecek /* Time in jiffies before concluding the transmitter is hung. */ 134 1.1 jdolecek #define DEFAULT_TX_CMP_TO (SBT_1S * 5) 135 1.1 jdolecek 136 1.1 jdolecek /* Number of queues to check for missing queues per timer tick */ 137 1.1 jdolecek #define DEFAULT_TX_MONITORED_QUEUES (4) 138 1.1 jdolecek 139 1.1 jdolecek /* Max number of timeouted packets before device reset */ 140 1.1 jdolecek #define DEFAULT_TX_CMP_THRESHOLD (128) 141 1.1 jdolecek 142 1.1 jdolecek /* 143 1.1 jdolecek * Supported PCI vendor and devices IDs 144 1.1 jdolecek */ 145 1.1 jdolecek #define PCI_VENDOR_ID_AMAZON 0x1d0f 146 1.1 jdolecek 147 1.1 jdolecek #define PCI_DEV_ID_ENA_PF 0x0ec2 148 1.1 jdolecek #define PCI_DEV_ID_ENA_LLQ_PF 0x1ec2 149 1.1 jdolecek #define PCI_DEV_ID_ENA_VF 0xec20 150 1.1 jdolecek #define PCI_DEV_ID_ENA_LLQ_VF 0xec21 151 1.1 jdolecek 152 1.8 jmcneill /* 153 1.8 jmcneill * Flags indicating current ENA driver state 154 1.8 jmcneill */ 155 1.8 jmcneill enum ena_flags_t { 156 1.8 jmcneill ENA_FLAG_DEVICE_RUNNING, 157 1.8 jmcneill ENA_FLAG_DEV_UP, 158 1.8 jmcneill ENA_FLAG_LINK_UP, 159 1.8 jmcneill ENA_FLAG_MSIX_ENABLED, 160 1.8 jmcneill ENA_FLAG_TRIGGER_RESET, 161 1.8 jmcneill ENA_FLAG_ONGOING_RESET, 162 1.8 jmcneill ENA_FLAG_DEV_UP_BEFORE_RESET, 163 1.8 jmcneill ENA_FLAG_RSS_ACTIVE, 164 1.8 jmcneill ENA_FLAGS_NUMBER = ENA_FLAG_RSS_ACTIVE 165 1.8 jmcneill }; 166 1.8 jmcneill 167 1.8 jmcneill #define ENA_FLAG_BITMASK(bit) (~(uint32_t)__BIT(bit)) 168 1.8 jmcneill #define ENA_FLAG_ZERO(adapter) (adapter)->flags = 0; 169 1.8 jmcneill #define ENA_FLAG_ISSET(bit, adapter) ((adapter)->flags & __BIT(bit)) 170 1.8 jmcneill #define ENA_FLAG_SET_ATOMIC(bit, adapter) \ 171 1.8 jmcneill atomic_or_32(&(adapter)->flags, __BIT(bit)) 172 1.8 jmcneill #define ENA_FLAG_CLEAR_ATOMIC(bit, adapter) \ 173 1.8 jmcneill atomic_and_32(&(adapter)->flags, ENA_FLAG_BITMASK(bit)) 174 1.8 jmcneill 175 1.3 jdolecek typedef __int64_t sbintime_t; 176 1.3 jdolecek 177 1.1 jdolecek struct msix_entry { 178 1.1 jdolecek int entry; 179 1.1 jdolecek int vector; 180 1.1 jdolecek }; 181 1.1 jdolecek 182 1.1 jdolecek typedef struct _ena_vendor_info_t { 183 1.1 jdolecek unsigned int vendor_id; 184 1.1 jdolecek unsigned int device_id; 185 1.1 jdolecek unsigned int index; 186 1.1 jdolecek } ena_vendor_info_t; 187 1.1 jdolecek 188 1.1 jdolecek struct ena_que { 189 1.1 jdolecek struct ena_adapter *adapter; 190 1.1 jdolecek struct ena_ring *tx_ring; 191 1.1 jdolecek struct ena_ring *rx_ring; 192 1.1 jdolecek uint32_t id; 193 1.1 jdolecek int cpu; 194 1.1 jdolecek }; 195 1.1 jdolecek 196 1.1 jdolecek struct ena_tx_buffer { 197 1.1 jdolecek struct mbuf *mbuf; 198 1.1 jdolecek /* # of ena desc for this specific mbuf 199 1.1 jdolecek * (includes data desc and metadata desc) */ 200 1.1 jdolecek unsigned int tx_descs; 201 1.1 jdolecek /* # of buffers used by this mbuf */ 202 1.1 jdolecek unsigned int num_of_bufs; 203 1.1 jdolecek bus_dmamap_t map; 204 1.1 jdolecek 205 1.1 jdolecek /* Used to detect missing tx packets */ 206 1.1 jdolecek struct bintime timestamp; 207 1.1 jdolecek bool print_once; 208 1.1 jdolecek 209 1.1 jdolecek struct ena_com_buf bufs[ENA_PKT_MAX_BUFS]; 210 1.1 jdolecek } __aligned(CACHE_LINE_SIZE); 211 1.1 jdolecek 212 1.1 jdolecek struct ena_rx_buffer { 213 1.1 jdolecek struct mbuf *mbuf; 214 1.1 jdolecek bus_dmamap_t map; 215 1.1 jdolecek struct ena_com_buf ena_buf; 216 1.1 jdolecek } __aligned(CACHE_LINE_SIZE); 217 1.1 jdolecek 218 1.1 jdolecek struct ena_stats_tx { 219 1.3 jdolecek char name[16]; 220 1.2 jdolecek struct evcnt cnt; 221 1.2 jdolecek struct evcnt bytes; 222 1.2 jdolecek struct evcnt prepare_ctx_err; 223 1.2 jdolecek struct evcnt dma_mapping_err; 224 1.2 jdolecek struct evcnt doorbells; 225 1.2 jdolecek struct evcnt missing_tx_comp; 226 1.2 jdolecek struct evcnt bad_req_id; 227 1.2 jdolecek struct evcnt collapse; 228 1.2 jdolecek struct evcnt collapse_err; 229 1.8 jmcneill struct evcnt pcq_drops; 230 1.1 jdolecek }; 231 1.1 jdolecek 232 1.1 jdolecek struct ena_stats_rx { 233 1.3 jdolecek char name[16]; 234 1.2 jdolecek struct evcnt cnt; 235 1.2 jdolecek struct evcnt bytes; 236 1.2 jdolecek struct evcnt refil_partial; 237 1.2 jdolecek struct evcnt bad_csum; 238 1.2 jdolecek struct evcnt mbuf_alloc_fail; 239 1.2 jdolecek struct evcnt dma_mapping_err; 240 1.2 jdolecek struct evcnt bad_desc_num; 241 1.2 jdolecek struct evcnt bad_req_id; 242 1.2 jdolecek struct evcnt empty_rx_ring; 243 1.1 jdolecek }; 244 1.1 jdolecek 245 1.8 jmcneill /* 246 1.8 jmcneill * Locking notes: 247 1.8 jmcneill * + For TX, a field in ena_ring is protected by ring_mtx (a spin mutex). 248 1.8 jmcneill * - protect them only when I/F is up. 249 1.8 jmcneill * - when I/F is down or attaching, detaching, no need to protect them. 250 1.8 jmcneill * + For RX, a field "stopping" is protected by ring_mtx (a spin mutex). 251 1.8 jmcneill * - other fields in ena_ring are not protected. 252 1.8 jmcneill * + a fields in ena_adapter is protected by global_mtx (a adaptive mutex). 253 1.8 jmcneill * 254 1.8 jmcneill * + a field marked "stable" is unlocked. 255 1.8 jmcneill * + a field marked "atomic" is unlocked, 256 1.8 jmcneill * but must use atomic ops to read/write. 257 1.8 jmcneill * 258 1.8 jmcneill * Lock order: 259 1.8 jmcneill * + global_mtx -> ring_mtx 260 1.8 jmcneill */ 261 1.1 jdolecek struct ena_ring { 262 1.1 jdolecek /* Holds the empty requests for TX/RX out of order completions */ 263 1.1 jdolecek union { 264 1.1 jdolecek uint16_t *free_tx_ids; 265 1.1 jdolecek uint16_t *free_rx_ids; 266 1.1 jdolecek }; 267 1.1 jdolecek struct ena_com_dev *ena_dev; 268 1.1 jdolecek struct ena_adapter *adapter; 269 1.1 jdolecek struct ena_com_io_cq *ena_com_io_cq; 270 1.1 jdolecek struct ena_com_io_sq *ena_com_io_sq; 271 1.1 jdolecek 272 1.1 jdolecek uint16_t qid; 273 1.1 jdolecek 274 1.1 jdolecek /* Determines if device will use LLQ or normal mode for TX */ 275 1.1 jdolecek enum ena_admin_placement_policy_type tx_mem_queue_type; 276 1.1 jdolecek /* The maximum length the driver can push to the device (For LLQ) */ 277 1.1 jdolecek uint8_t tx_max_header_size; 278 1.1 jdolecek 279 1.1 jdolecek struct ena_com_rx_buf_info ena_bufs[ENA_PKT_MAX_BUFS]; 280 1.1 jdolecek 281 1.1 jdolecek /* 282 1.1 jdolecek * Fields used for Adaptive Interrupt Modulation - to be implemented in 283 1.1 jdolecek * the future releases 284 1.1 jdolecek */ 285 1.1 jdolecek uint32_t smoothed_interval; 286 1.1 jdolecek enum ena_intr_moder_level moder_tbl_idx; 287 1.1 jdolecek 288 1.1 jdolecek struct ena_que *que; 289 1.2 jdolecek #ifdef LRO 290 1.1 jdolecek struct lro_ctrl lro; 291 1.2 jdolecek #endif 292 1.1 jdolecek 293 1.1 jdolecek uint16_t next_to_use; 294 1.1 jdolecek uint16_t next_to_clean; 295 1.1 jdolecek 296 1.1 jdolecek union { 297 1.10 andvar struct ena_tx_buffer *tx_buffer_info; /* context of tx packet */ 298 1.10 andvar struct ena_rx_buffer *rx_buffer_info; /* context of rx packet */ 299 1.1 jdolecek }; 300 1.1 jdolecek int ring_size; /* number of tx/rx_buffer_info's entries */ 301 1.1 jdolecek 302 1.8 jmcneill pcq_t *br; /* only for TX */ 303 1.1 jdolecek 304 1.2 jdolecek kmutex_t ring_mtx; 305 1.1 jdolecek char mtx_name[16]; 306 1.1 jdolecek 307 1.1 jdolecek union { 308 1.1 jdolecek struct { 309 1.2 jdolecek struct work enqueue_task; 310 1.2 jdolecek struct workqueue *enqueue_tq; 311 1.1 jdolecek }; 312 1.1 jdolecek struct { 313 1.8 jmcneill struct work cleanup_task; 314 1.8 jmcneill struct workqueue *cleanup_tq; 315 1.1 jdolecek }; 316 1.1 jdolecek }; 317 1.8 jmcneill u_int task_pending; /* atomic */ 318 1.8 jmcneill bool stopping; 319 1.1 jdolecek 320 1.1 jdolecek union { 321 1.1 jdolecek struct ena_stats_tx tx_stats; 322 1.1 jdolecek struct ena_stats_rx rx_stats; 323 1.1 jdolecek }; 324 1.1 jdolecek 325 1.1 jdolecek int empty_rx_queue; 326 1.1 jdolecek } __aligned(CACHE_LINE_SIZE); 327 1.1 jdolecek 328 1.1 jdolecek struct ena_stats_dev { 329 1.3 jdolecek char name[16]; 330 1.2 jdolecek struct evcnt wd_expired; 331 1.2 jdolecek struct evcnt interface_up; 332 1.2 jdolecek struct evcnt interface_down; 333 1.2 jdolecek struct evcnt admin_q_pause; 334 1.1 jdolecek }; 335 1.1 jdolecek 336 1.1 jdolecek struct ena_hw_stats { 337 1.3 jdolecek char name[16]; 338 1.2 jdolecek struct evcnt rx_packets; 339 1.2 jdolecek struct evcnt tx_packets; 340 1.1 jdolecek 341 1.2 jdolecek struct evcnt rx_bytes; 342 1.2 jdolecek struct evcnt tx_bytes; 343 1.1 jdolecek 344 1.2 jdolecek struct evcnt rx_drops; 345 1.1 jdolecek }; 346 1.1 jdolecek 347 1.1 jdolecek /* Board specific private data structure */ 348 1.1 jdolecek struct ena_adapter { 349 1.1 jdolecek struct ena_com_dev *ena_dev; 350 1.1 jdolecek 351 1.1 jdolecek /* OS defined structs */ 352 1.1 jdolecek device_t pdev; 353 1.2 jdolecek struct ethercom sc_ec; 354 1.2 jdolecek struct ifnet *ifp; /* set to point to sc_ec */ 355 1.1 jdolecek struct ifmedia media; 356 1.1 jdolecek 357 1.1 jdolecek /* OS resources */ 358 1.2 jdolecek kmutex_t global_mtx; 359 1.1 jdolecek 360 1.3 jdolecek void *sc_ihs[ENA_MAX_MSIX_VEC(ENA_MAX_NUM_IO_QUEUES)]; 361 1.3 jdolecek pci_intr_handle_t *sc_intrs; 362 1.3 jdolecek int sc_nintrs; 363 1.3 jdolecek struct pci_attach_args sc_pa; 364 1.3 jdolecek 365 1.3 jdolecek /* Registers */ 366 1.3 jdolecek bus_space_handle_t sc_bhandle; 367 1.3 jdolecek bus_space_tag_t sc_btag; 368 1.8 jmcneill bus_addr_t sc_memaddr; 369 1.8 jmcneill bus_size_t sc_mapsize; 370 1.1 jdolecek 371 1.2 jdolecek /* DMA tag used throughout the driver adapter for Tx and Rx */ 372 1.2 jdolecek bus_dma_tag_t sc_dmat; 373 1.1 jdolecek int dma_width; 374 1.1 jdolecek 375 1.1 jdolecek uint32_t max_mtu; 376 1.1 jdolecek 377 1.1 jdolecek uint16_t max_tx_sgl_size; 378 1.1 jdolecek uint16_t max_rx_sgl_size; 379 1.1 jdolecek 380 1.1 jdolecek uint32_t tx_offload_cap; 381 1.1 jdolecek 382 1.1 jdolecek /* Tx fast path data */ 383 1.1 jdolecek int num_queues; 384 1.1 jdolecek 385 1.1 jdolecek unsigned int tx_ring_size; 386 1.1 jdolecek unsigned int rx_ring_size; 387 1.1 jdolecek 388 1.1 jdolecek /* RSS*/ 389 1.1 jdolecek uint8_t rss_ind_tbl[ENA_RX_RSS_TABLE_SIZE]; 390 1.1 jdolecek bool rss_support; 391 1.9 jdolecek int initialized; 392 1.1 jdolecek 393 1.1 jdolecek uint8_t mac_addr[ETHER_ADDR_LEN]; 394 1.1 jdolecek /* mdio and phy*/ 395 1.1 jdolecek 396 1.8 jmcneill uint32_t flags; /* atomic */ 397 1.1 jdolecek 398 1.1 jdolecek /* Queue will represent one TX and one RX ring */ 399 1.1 jdolecek struct ena_que que[ENA_MAX_NUM_IO_QUEUES] 400 1.8 jmcneill __aligned(CACHE_LINE_SIZE); /* stable */ 401 1.1 jdolecek 402 1.1 jdolecek /* TX */ 403 1.1 jdolecek struct ena_ring tx_ring[ENA_MAX_NUM_IO_QUEUES] 404 1.1 jdolecek __aligned(CACHE_LINE_SIZE); 405 1.1 jdolecek 406 1.1 jdolecek /* RX */ 407 1.1 jdolecek struct ena_ring rx_ring[ENA_MAX_NUM_IO_QUEUES] 408 1.1 jdolecek __aligned(CACHE_LINE_SIZE); 409 1.1 jdolecek 410 1.1 jdolecek /* Timer service */ 411 1.1 jdolecek struct callout timer_service; 412 1.3 jdolecek sbintime_t keep_alive_timestamp; 413 1.1 jdolecek uint32_t next_monitored_tx_qid; 414 1.2 jdolecek struct work reset_task; 415 1.2 jdolecek struct workqueue *reset_tq; 416 1.1 jdolecek int wd_active; 417 1.3 jdolecek sbintime_t keep_alive_timeout; 418 1.3 jdolecek sbintime_t missing_tx_timeout; 419 1.1 jdolecek uint32_t missing_tx_max_queues; 420 1.1 jdolecek uint32_t missing_tx_threshold; 421 1.1 jdolecek 422 1.1 jdolecek /* Statistics */ 423 1.1 jdolecek struct ena_stats_dev dev_stats; 424 1.1 jdolecek struct ena_hw_stats hw_stats; 425 1.1 jdolecek 426 1.1 jdolecek enum ena_regs_reset_reason_types reset_reason; 427 1.1 jdolecek }; 428 1.1 jdolecek 429 1.2 jdolecek #define ENA_RING_MTX_LOCK(_ring) mutex_enter(&(_ring)->ring_mtx) 430 1.2 jdolecek #define ENA_RING_MTX_TRYLOCK(_ring) mutex_tryenter(&(_ring)->ring_mtx) 431 1.2 jdolecek #define ENA_RING_MTX_UNLOCK(_ring) mutex_exit(&(_ring)->ring_mtx) 432 1.8 jmcneill #define ENA_RING_MTX_OWNED(_ring) mutex_owned(&(_ring)->ring_mtx) 433 1.8 jmcneill 434 1.8 jmcneill #define ENA_CORE_MTX_LOCK(_adapter) mutex_enter(&(_adapter)->global_mtx) 435 1.8 jmcneill #define ENA_CORE_MTX_TRYLOCK(_adapter) mutex_tryenter(&(_adapter)->global_mtx) 436 1.8 jmcneill #define ENA_CORE_MTX_UNLOCK(_adapter) mutex_exit(&(_adapter)->global_mtx) 437 1.8 jmcneill #define ENA_CORE_MTX_OWNED(_adapter) mutex_owned(&(_adapter)->global_mtx) 438 1.1 jdolecek 439 1.1 jdolecek static inline int ena_mbuf_count(struct mbuf *mbuf) 440 1.1 jdolecek { 441 1.1 jdolecek int count = 1; 442 1.1 jdolecek 443 1.1 jdolecek while ((mbuf = mbuf->m_next) != NULL) 444 1.1 jdolecek ++count; 445 1.1 jdolecek 446 1.1 jdolecek return count; 447 1.1 jdolecek } 448 1.1 jdolecek 449 1.3 jdolecek /* provide FreeBSD-compatible macros */ 450 1.3 jdolecek #define if_getcapenable(ifp) (ifp)->if_capenable 451 1.3 jdolecek #define if_setcapenable(ifp, s) SET((ifp)->if_capenable, s) 452 1.3 jdolecek #define if_getcapabilities(ifp) (ifp)->if_capabilities 453 1.3 jdolecek #define if_setcapabilities(ifp, s) SET((ifp)->if_capabilities, s) 454 1.3 jdolecek #define if_setcapabilitiesbit(ifp, s, c) do { \ 455 1.3 jdolecek CLR((ifp)->if_capabilities, c); \ 456 1.3 jdolecek SET((ifp)->if_capabilities, s); \ 457 1.3 jdolecek } while (0) 458 1.3 jdolecek #define if_getsoftc(ifp) (ifp)->if_softc 459 1.3 jdolecek #define if_setmtu(ifp, new_mtu) (ifp)->if_mtu = (new_mtu) 460 1.3 jdolecek #define if_getdrvflags(ifp) (ifp)->if_flags 461 1.3 jdolecek #define if_setdrvflagbits(ifp, s, c) do { \ 462 1.3 jdolecek CLR((ifp)->if_flags, c); \ 463 1.3 jdolecek SET((ifp)->if_flags, s); \ 464 1.3 jdolecek } while (0) 465 1.3 jdolecek #define if_setflags(ifp, s) SET((ifp)->if_flags, s) 466 1.3 jdolecek #define if_sethwassistbits(ifp, s, c) do { \ 467 1.3 jdolecek CLR((ifp)->if_csum_flags_rx, c); \ 468 1.3 jdolecek SET((ifp)->if_csum_flags_rx, s); \ 469 1.3 jdolecek } while (0) 470 1.3 jdolecek #define if_clearhwassist(ifp) (ifp)->if_csum_flags_rx = 0 471 1.3 jdolecek #define if_setbaudrate(ifp, r) (ifp)->if_baudrate = (r) 472 1.3 jdolecek #define if_setdev(ifp, dev) do { } while (0) 473 1.3 jdolecek #define if_setsoftc(ifp, softc) (ifp)->if_softc = (softc) 474 1.3 jdolecek #define if_setinitfn(ifp, initfn) (ifp)->if_init = (initfn) 475 1.3 jdolecek #define if_settransmitfn(ifp, txfn) (ifp)->if_transmit = (txfn) 476 1.3 jdolecek #define if_setioctlfn(ifp, ioctlfn) (ifp)->if_ioctl = (ioctlfn) 477 1.3 jdolecek #define if_setsendqlen(ifp, sqlen) \ 478 1.4 riastrad IFQ_SET_MAXLEN(&(ifp)->if_snd, uimax(sqlen, IFQ_MAXLEN)) 479 1.3 jdolecek #define if_setsendqready(ifp) IFQ_SET_READY(&(ifp)->if_snd) 480 1.3 jdolecek #define if_setifheaderlen(ifp, len) (ifp)->if_hdrlen = (len) 481 1.3 jdolecek 482 1.3 jdolecek #define SBT_1S ((sbintime_t)1 << 32) 483 1.3 jdolecek #define bintime_clear(a) ((a)->sec = (a)->frac = 0) 484 1.3 jdolecek #define bintime_isset(a) ((a)->sec || (a)->frac) 485 1.3 jdolecek 486 1.3 jdolecek static __inline sbintime_t 487 1.3 jdolecek bttosbt(const struct bintime _bt) 488 1.3 jdolecek { 489 1.3 jdolecek return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32)); 490 1.3 jdolecek } 491 1.3 jdolecek 492 1.3 jdolecek static __inline sbintime_t 493 1.3 jdolecek getsbinuptime(void) 494 1.3 jdolecek { 495 1.3 jdolecek struct bintime _bt; 496 1.3 jdolecek 497 1.3 jdolecek getbinuptime(&_bt); 498 1.3 jdolecek return (bttosbt(_bt)); 499 1.3 jdolecek } 500 1.3 jdolecek 501 1.3 jdolecek /* Intentionally non-atomic, it's just unnecessary overhead */ 502 1.3 jdolecek #define counter_u64_add(x, cnt) (x).ev_count += (cnt) 503 1.3 jdolecek #define counter_u64_zero(x) (x).ev_count = 0 504 1.3 jdolecek #define counter_u64_free(x) evcnt_detach(&(x)) 505 1.3 jdolecek 506 1.3 jdolecek #define counter_u64_add_protected(x, cnt) (x).ev_count += (cnt) 507 1.3 jdolecek #define counter_enter() do {} while (0) 508 1.3 jdolecek #define counter_exit() do {} while (0) 509 1.3 jdolecek 510 1.3 jdolecek /* Misc other constants */ 511 1.3 jdolecek #define mp_ncpus ncpu 512 1.3 jdolecek #define osreldate __NetBSD_Version__ 513 1.3 jdolecek 514 1.3 jdolecek /* 515 1.3 jdolecek * XXX XXX XXX just to make compile, must provide replacement XXX XXX XXX 516 1.3 jdolecek * Other than that, TODO: 517 1.3 jdolecek * - decide whether to import <sys/buf_ring.h> 518 1.3 jdolecek * - recheck the M_CSUM/IPCAP mapping 519 1.3 jdolecek * - recheck workqueue use - FreeBSD taskqueues might have different semantics 520 1.3 jdolecek */ 521 1.3 jdolecek #define buf_ring_alloc(a, b, c, d) (void *)&a 522 1.3 jdolecek #define drbr_free(ifp, b) do { } while (0) 523 1.6 jmcneill #define drbr_flush(ifp, b) IFQ_PURGE(&(ifp)->if_snd) 524 1.6 jmcneill #define drbr_advance(ifp, b) \ 525 1.6 jmcneill ({ \ 526 1.6 jmcneill struct mbuf *__m; \ 527 1.6 jmcneill IFQ_DEQUEUE(&(ifp)->if_snd, __m); \ 528 1.6 jmcneill __m; \ 529 1.6 jmcneill }) 530 1.3 jdolecek #define drbr_putback(ifp, b, m) do { } while (0) 531 1.6 jmcneill #define drbr_empty(ifp, b) IFQ_IS_EMPTY(&(ifp)->if_snd) 532 1.6 jmcneill #define drbr_peek(ifp, b) \ 533 1.6 jmcneill ({ \ 534 1.6 jmcneill struct mbuf *__m; \ 535 1.6 jmcneill IFQ_POLL(&(ifp)->if_snd, __m); \ 536 1.6 jmcneill __m; \ 537 1.6 jmcneill }) 538 1.6 jmcneill #define drbr_enqueue(ifp, b, m) \ 539 1.6 jmcneill ({ \ 540 1.6 jmcneill int __err; \ 541 1.6 jmcneill IFQ_ENQUEUE(&(ifp)->if_snd, m, __err); \ 542 1.6 jmcneill __err; \ 543 1.6 jmcneill }) 544 1.3 jdolecek #define m_getjcl(a, b, c, d) NULL 545 1.3 jdolecek #define MJUM16BYTES MCLBYTES 546 1.6 jmcneill #define m_append(m, len, cp) ena_m_append(m, len, cp) 547 1.6 jmcneill #define m_collapse(m, how, maxfrags) m_defrag(m, how) /* XXX */ 548 1.3 jdolecek /* XXX XXX XXX */ 549 1.3 jdolecek 550 1.6 jmcneill static inline int 551 1.6 jmcneill ena_m_append(struct mbuf *m0, int len, const void *cpv) 552 1.6 jmcneill { 553 1.6 jmcneill struct mbuf *m, *n; 554 1.6 jmcneill int remainder, space; 555 1.6 jmcneill const char *cp = cpv; 556 1.6 jmcneill 557 1.6 jmcneill KASSERT(len != M_COPYALL); 558 1.6 jmcneill for (m = m0; m->m_next != NULL; m = m->m_next) 559 1.6 jmcneill continue; 560 1.6 jmcneill remainder = len; 561 1.6 jmcneill space = M_TRAILINGSPACE(m); 562 1.6 jmcneill if (space > 0) { 563 1.6 jmcneill /* 564 1.6 jmcneill * Copy into available space. 565 1.6 jmcneill */ 566 1.6 jmcneill if (space > remainder) 567 1.6 jmcneill space = remainder; 568 1.6 jmcneill memmove(mtod(m, char *) + m->m_len, cp, space); 569 1.6 jmcneill m->m_len += space; 570 1.6 jmcneill cp = cp + space, remainder -= space; 571 1.6 jmcneill } 572 1.6 jmcneill while (remainder > 0) { 573 1.6 jmcneill /* 574 1.6 jmcneill * Allocate a new mbuf; could check space 575 1.6 jmcneill * and allocate a cluster instead. 576 1.6 jmcneill */ 577 1.6 jmcneill n = m_get(M_DONTWAIT, m->m_type); 578 1.6 jmcneill if (n == NULL) 579 1.6 jmcneill break; 580 1.6 jmcneill n->m_len = uimin(MLEN, remainder); 581 1.6 jmcneill memmove(mtod(n, void *), cp, n->m_len); 582 1.6 jmcneill cp += n->m_len, remainder -= n->m_len; 583 1.6 jmcneill m->m_next = n; 584 1.6 jmcneill m = n; 585 1.6 jmcneill } 586 1.6 jmcneill if (m0->m_flags & M_PKTHDR) 587 1.6 jmcneill m0->m_pkthdr.len += len - remainder; 588 1.6 jmcneill return (remainder == 0); 589 1.6 jmcneill } 590 1.1 jdolecek #endif /* !(ENA_H) */ 591