if_enavar.h revision 1.8 1 1.8 jmcneill /* $NetBSD: if_enavar.h,v 1.8 2021/07/19 21:16:33 jmcneill 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.1 jdolecek struct ena_tx_buffer *tx_buffer_info; /* contex of tx packet */
298 1.1 jdolecek struct ena_rx_buffer *rx_buffer_info; /* contex 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.1 jdolecek
392 1.1 jdolecek uint8_t mac_addr[ETHER_ADDR_LEN];
393 1.1 jdolecek /* mdio and phy*/
394 1.1 jdolecek
395 1.8 jmcneill uint32_t flags; /* atomic */
396 1.1 jdolecek
397 1.1 jdolecek /* Queue will represent one TX and one RX ring */
398 1.1 jdolecek struct ena_que que[ENA_MAX_NUM_IO_QUEUES]
399 1.8 jmcneill __aligned(CACHE_LINE_SIZE); /* stable */
400 1.1 jdolecek
401 1.1 jdolecek /* TX */
402 1.1 jdolecek struct ena_ring tx_ring[ENA_MAX_NUM_IO_QUEUES]
403 1.1 jdolecek __aligned(CACHE_LINE_SIZE);
404 1.1 jdolecek
405 1.1 jdolecek /* RX */
406 1.1 jdolecek struct ena_ring rx_ring[ENA_MAX_NUM_IO_QUEUES]
407 1.1 jdolecek __aligned(CACHE_LINE_SIZE);
408 1.1 jdolecek
409 1.1 jdolecek /* Timer service */
410 1.1 jdolecek struct callout timer_service;
411 1.3 jdolecek sbintime_t keep_alive_timestamp;
412 1.1 jdolecek uint32_t next_monitored_tx_qid;
413 1.2 jdolecek struct work reset_task;
414 1.2 jdolecek struct workqueue *reset_tq;
415 1.1 jdolecek int wd_active;
416 1.3 jdolecek sbintime_t keep_alive_timeout;
417 1.3 jdolecek sbintime_t missing_tx_timeout;
418 1.1 jdolecek uint32_t missing_tx_max_queues;
419 1.1 jdolecek uint32_t missing_tx_threshold;
420 1.1 jdolecek
421 1.1 jdolecek /* Statistics */
422 1.1 jdolecek struct ena_stats_dev dev_stats;
423 1.1 jdolecek struct ena_hw_stats hw_stats;
424 1.1 jdolecek
425 1.1 jdolecek enum ena_regs_reset_reason_types reset_reason;
426 1.1 jdolecek };
427 1.1 jdolecek
428 1.2 jdolecek #define ENA_RING_MTX_LOCK(_ring) mutex_enter(&(_ring)->ring_mtx)
429 1.2 jdolecek #define ENA_RING_MTX_TRYLOCK(_ring) mutex_tryenter(&(_ring)->ring_mtx)
430 1.2 jdolecek #define ENA_RING_MTX_UNLOCK(_ring) mutex_exit(&(_ring)->ring_mtx)
431 1.8 jmcneill #define ENA_RING_MTX_OWNED(_ring) mutex_owned(&(_ring)->ring_mtx)
432 1.8 jmcneill
433 1.8 jmcneill #define ENA_CORE_MTX_LOCK(_adapter) mutex_enter(&(_adapter)->global_mtx)
434 1.8 jmcneill #define ENA_CORE_MTX_TRYLOCK(_adapter) mutex_tryenter(&(_adapter)->global_mtx)
435 1.8 jmcneill #define ENA_CORE_MTX_UNLOCK(_adapter) mutex_exit(&(_adapter)->global_mtx)
436 1.8 jmcneill #define ENA_CORE_MTX_OWNED(_adapter) mutex_owned(&(_adapter)->global_mtx)
437 1.1 jdolecek
438 1.1 jdolecek static inline int ena_mbuf_count(struct mbuf *mbuf)
439 1.1 jdolecek {
440 1.1 jdolecek int count = 1;
441 1.1 jdolecek
442 1.1 jdolecek while ((mbuf = mbuf->m_next) != NULL)
443 1.1 jdolecek ++count;
444 1.1 jdolecek
445 1.1 jdolecek return count;
446 1.1 jdolecek }
447 1.1 jdolecek
448 1.3 jdolecek /* provide FreeBSD-compatible macros */
449 1.3 jdolecek #define if_getcapenable(ifp) (ifp)->if_capenable
450 1.3 jdolecek #define if_setcapenable(ifp, s) SET((ifp)->if_capenable, s)
451 1.3 jdolecek #define if_getcapabilities(ifp) (ifp)->if_capabilities
452 1.3 jdolecek #define if_setcapabilities(ifp, s) SET((ifp)->if_capabilities, s)
453 1.3 jdolecek #define if_setcapabilitiesbit(ifp, s, c) do { \
454 1.3 jdolecek CLR((ifp)->if_capabilities, c); \
455 1.3 jdolecek SET((ifp)->if_capabilities, s); \
456 1.3 jdolecek } while (0)
457 1.3 jdolecek #define if_getsoftc(ifp) (ifp)->if_softc
458 1.3 jdolecek #define if_setmtu(ifp, new_mtu) (ifp)->if_mtu = (new_mtu)
459 1.3 jdolecek #define if_getdrvflags(ifp) (ifp)->if_flags
460 1.3 jdolecek #define if_setdrvflagbits(ifp, s, c) do { \
461 1.3 jdolecek CLR((ifp)->if_flags, c); \
462 1.3 jdolecek SET((ifp)->if_flags, s); \
463 1.3 jdolecek } while (0)
464 1.3 jdolecek #define if_setflags(ifp, s) SET((ifp)->if_flags, s)
465 1.3 jdolecek #define if_sethwassistbits(ifp, s, c) do { \
466 1.3 jdolecek CLR((ifp)->if_csum_flags_rx, c); \
467 1.3 jdolecek SET((ifp)->if_csum_flags_rx, s); \
468 1.3 jdolecek } while (0)
469 1.3 jdolecek #define if_clearhwassist(ifp) (ifp)->if_csum_flags_rx = 0
470 1.3 jdolecek #define if_setbaudrate(ifp, r) (ifp)->if_baudrate = (r)
471 1.3 jdolecek #define if_setdev(ifp, dev) do { } while (0)
472 1.3 jdolecek #define if_setsoftc(ifp, softc) (ifp)->if_softc = (softc)
473 1.3 jdolecek #define if_setinitfn(ifp, initfn) (ifp)->if_init = (initfn)
474 1.3 jdolecek #define if_settransmitfn(ifp, txfn) (ifp)->if_transmit = (txfn)
475 1.3 jdolecek #define if_setioctlfn(ifp, ioctlfn) (ifp)->if_ioctl = (ioctlfn)
476 1.3 jdolecek #define if_setsendqlen(ifp, sqlen) \
477 1.4 riastrad IFQ_SET_MAXLEN(&(ifp)->if_snd, uimax(sqlen, IFQ_MAXLEN))
478 1.3 jdolecek #define if_setsendqready(ifp) IFQ_SET_READY(&(ifp)->if_snd)
479 1.3 jdolecek #define if_setifheaderlen(ifp, len) (ifp)->if_hdrlen = (len)
480 1.3 jdolecek
481 1.3 jdolecek #define SBT_1S ((sbintime_t)1 << 32)
482 1.3 jdolecek #define bintime_clear(a) ((a)->sec = (a)->frac = 0)
483 1.3 jdolecek #define bintime_isset(a) ((a)->sec || (a)->frac)
484 1.3 jdolecek
485 1.3 jdolecek static __inline sbintime_t
486 1.3 jdolecek bttosbt(const struct bintime _bt)
487 1.3 jdolecek {
488 1.3 jdolecek return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32));
489 1.3 jdolecek }
490 1.3 jdolecek
491 1.3 jdolecek static __inline sbintime_t
492 1.3 jdolecek getsbinuptime(void)
493 1.3 jdolecek {
494 1.3 jdolecek struct bintime _bt;
495 1.3 jdolecek
496 1.3 jdolecek getbinuptime(&_bt);
497 1.3 jdolecek return (bttosbt(_bt));
498 1.3 jdolecek }
499 1.3 jdolecek
500 1.3 jdolecek /* Intentionally non-atomic, it's just unnecessary overhead */
501 1.3 jdolecek #define counter_u64_add(x, cnt) (x).ev_count += (cnt)
502 1.3 jdolecek #define counter_u64_zero(x) (x).ev_count = 0
503 1.3 jdolecek #define counter_u64_free(x) evcnt_detach(&(x))
504 1.3 jdolecek
505 1.3 jdolecek #define counter_u64_add_protected(x, cnt) (x).ev_count += (cnt)
506 1.3 jdolecek #define counter_enter() do {} while (0)
507 1.3 jdolecek #define counter_exit() do {} while (0)
508 1.3 jdolecek
509 1.3 jdolecek /* Misc other constants */
510 1.3 jdolecek #define mp_ncpus ncpu
511 1.3 jdolecek #define osreldate __NetBSD_Version__
512 1.3 jdolecek
513 1.3 jdolecek /*
514 1.3 jdolecek * XXX XXX XXX just to make compile, must provide replacement XXX XXX XXX
515 1.3 jdolecek * Other than that, TODO:
516 1.3 jdolecek * - decide whether to import <sys/buf_ring.h>
517 1.3 jdolecek * - recheck the M_CSUM/IPCAP mapping
518 1.3 jdolecek * - recheck workqueue use - FreeBSD taskqueues might have different semantics
519 1.3 jdolecek */
520 1.3 jdolecek #define buf_ring_alloc(a, b, c, d) (void *)&a
521 1.3 jdolecek #define drbr_free(ifp, b) do { } while (0)
522 1.6 jmcneill #define drbr_flush(ifp, b) IFQ_PURGE(&(ifp)->if_snd)
523 1.6 jmcneill #define drbr_advance(ifp, b) \
524 1.6 jmcneill ({ \
525 1.6 jmcneill struct mbuf *__m; \
526 1.6 jmcneill IFQ_DEQUEUE(&(ifp)->if_snd, __m); \
527 1.6 jmcneill __m; \
528 1.6 jmcneill })
529 1.3 jdolecek #define drbr_putback(ifp, b, m) do { } while (0)
530 1.6 jmcneill #define drbr_empty(ifp, b) IFQ_IS_EMPTY(&(ifp)->if_snd)
531 1.6 jmcneill #define drbr_peek(ifp, b) \
532 1.6 jmcneill ({ \
533 1.6 jmcneill struct mbuf *__m; \
534 1.6 jmcneill IFQ_POLL(&(ifp)->if_snd, __m); \
535 1.6 jmcneill __m; \
536 1.6 jmcneill })
537 1.6 jmcneill #define drbr_enqueue(ifp, b, m) \
538 1.6 jmcneill ({ \
539 1.6 jmcneill int __err; \
540 1.6 jmcneill IFQ_ENQUEUE(&(ifp)->if_snd, m, __err); \
541 1.6 jmcneill __err; \
542 1.6 jmcneill })
543 1.3 jdolecek #define m_getjcl(a, b, c, d) NULL
544 1.3 jdolecek #define MJUM16BYTES MCLBYTES
545 1.6 jmcneill #define m_append(m, len, cp) ena_m_append(m, len, cp)
546 1.6 jmcneill #define m_collapse(m, how, maxfrags) m_defrag(m, how) /* XXX */
547 1.3 jdolecek /* XXX XXX XXX */
548 1.3 jdolecek
549 1.6 jmcneill static inline int
550 1.6 jmcneill ena_m_append(struct mbuf *m0, int len, const void *cpv)
551 1.6 jmcneill {
552 1.6 jmcneill struct mbuf *m, *n;
553 1.6 jmcneill int remainder, space;
554 1.6 jmcneill const char *cp = cpv;
555 1.6 jmcneill
556 1.6 jmcneill KASSERT(len != M_COPYALL);
557 1.6 jmcneill for (m = m0; m->m_next != NULL; m = m->m_next)
558 1.6 jmcneill continue;
559 1.6 jmcneill remainder = len;
560 1.6 jmcneill space = M_TRAILINGSPACE(m);
561 1.6 jmcneill if (space > 0) {
562 1.6 jmcneill /*
563 1.6 jmcneill * Copy into available space.
564 1.6 jmcneill */
565 1.6 jmcneill if (space > remainder)
566 1.6 jmcneill space = remainder;
567 1.6 jmcneill memmove(mtod(m, char *) + m->m_len, cp, space);
568 1.6 jmcneill m->m_len += space;
569 1.6 jmcneill cp = cp + space, remainder -= space;
570 1.6 jmcneill }
571 1.6 jmcneill while (remainder > 0) {
572 1.6 jmcneill /*
573 1.6 jmcneill * Allocate a new mbuf; could check space
574 1.6 jmcneill * and allocate a cluster instead.
575 1.6 jmcneill */
576 1.6 jmcneill n = m_get(M_DONTWAIT, m->m_type);
577 1.6 jmcneill if (n == NULL)
578 1.6 jmcneill break;
579 1.6 jmcneill n->m_len = uimin(MLEN, remainder);
580 1.6 jmcneill memmove(mtod(n, void *), cp, n->m_len);
581 1.6 jmcneill cp += n->m_len, remainder -= n->m_len;
582 1.6 jmcneill m->m_next = n;
583 1.6 jmcneill m = n;
584 1.6 jmcneill }
585 1.6 jmcneill if (m0->m_flags & M_PKTHDR)
586 1.6 jmcneill m0->m_pkthdr.len += len - remainder;
587 1.6 jmcneill return (remainder == 0);
588 1.6 jmcneill }
589 1.1 jdolecek #endif /* !(ENA_H) */
590