net/sfc: support choice of FW subvariant without Tx checksum
[dpdk.git] / drivers / net / sfc / efsys.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2016-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #ifndef _SFC_COMMON_EFSYS_H
11 #define _SFC_COMMON_EFSYS_H
12
13 #include <stdbool.h>
14
15 #include <rte_spinlock.h>
16 #include <rte_byteorder.h>
17 #include <rte_debug.h>
18 #include <rte_memzone.h>
19 #include <rte_memory.h>
20 #include <rte_memcpy.h>
21 #include <rte_cycles.h>
22 #include <rte_prefetch.h>
23 #include <rte_common.h>
24 #include <rte_malloc.h>
25 #include <rte_log.h>
26 #include <rte_io.h>
27
28 #include "sfc_debug.h"
29 #include "sfc_log.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #define EFSYS_HAS_UINT64 1
36 #define EFSYS_USE_UINT64 1
37 #define EFSYS_HAS_SSE2_M128 1
38
39 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
40 #define EFSYS_IS_BIG_ENDIAN 1
41 #define EFSYS_IS_LITTLE_ENDIAN 0
42 #elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
43 #define EFSYS_IS_BIG_ENDIAN 0
44 #define EFSYS_IS_LITTLE_ENDIAN 1
45 #else
46 #error "Cannot determine system endianness"
47 #endif
48 #include "efx_types.h"
49
50
51 #ifndef _NOTE
52 #define _NOTE(s)
53 #endif
54
55 typedef bool boolean_t;
56
57 #ifndef B_FALSE
58 #define B_FALSE false
59 #endif
60 #ifndef B_TRUE
61 #define B_TRUE  true
62 #endif
63
64 /*
65  * RTE_MAX() and RTE_MIN() cannot be used since braced-group within
66  * expression allowed only inside a function, but MAX() is used as
67  * a number of elements in array.
68  */
69 #ifndef MAX
70 #define MAX(v1, v2)     ((v1) > (v2) ? (v1) : (v2))
71 #endif
72 #ifndef MIN
73 #define MIN(v1, v2)     ((v1) < (v2) ? (v1) : (v2))
74 #endif
75
76 /* There are macros for alignment in DPDK, but we need to make a proper
77  * correspondence here, if we want to re-use them at all
78  */
79 #ifndef IS_P2ALIGNED
80 #define IS_P2ALIGNED(v, a)      ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
81 #endif
82
83 #ifndef P2ROUNDUP
84 #define P2ROUNDUP(x, align)     (-(-(x) & -(align)))
85 #endif
86
87 #ifndef P2ALIGN
88 #define P2ALIGN(_x, _a)         ((_x) & -(_a))
89 #endif
90
91 #ifndef IS2P
92 #define ISP2(x)                 rte_is_power_of_2(x)
93 #endif
94
95 #define ENOTACTIVE      ENOTCONN
96
97 static inline void
98 prefetch_read_many(const volatile void *addr)
99 {
100         rte_prefetch0(addr);
101 }
102
103 static inline void
104 prefetch_read_once(const volatile void *addr)
105 {
106         rte_prefetch_non_temporal(addr);
107 }
108
109 /* Modifiers used for Windows builds */
110 #define __in
111 #define __in_opt
112 #define __in_ecount(_n)
113 #define __in_ecount_opt(_n)
114 #define __in_bcount(_n)
115 #define __in_bcount_opt(_n)
116
117 #define __out
118 #define __out_opt
119 #define __out_ecount(_n)
120 #define __out_ecount_opt(_n)
121 #define __out_bcount(_n)
122 #define __out_bcount_opt(_n)
123 #define __out_bcount_part(_n, _l)
124 #define __out_bcount_part_opt(_n, _l)
125
126 #define __deref_out
127
128 #define __inout
129 #define __inout_opt
130 #define __inout_ecount(_n)
131 #define __inout_ecount_opt(_n)
132 #define __inout_bcount(_n)
133 #define __inout_bcount_opt(_n)
134 #define __inout_bcount_full_opt(_n)
135
136 #define __deref_out_bcount_opt(n)
137
138 #define __checkReturn
139 #define __success(_x)
140
141 #define __drv_when(_p, _c)
142
143 /* Code inclusion options */
144
145
146 #define EFSYS_OPT_NAMES 1
147
148 /* Disable SFN5xxx/SFN6xxx since it requires specific support in the PMD */
149 #define EFSYS_OPT_SIENA 0
150 /* Enable SFN7xxx support */
151 #define EFSYS_OPT_HUNTINGTON 1
152 /* Enable SFN8xxx support */
153 #define EFSYS_OPT_MEDFORD 1
154 /* Enable SFN2xxx support */
155 #define EFSYS_OPT_MEDFORD2 1
156 #ifdef RTE_LIBRTE_SFC_EFX_DEBUG
157 #define EFSYS_OPT_CHECK_REG 1
158 #else
159 #define EFSYS_OPT_CHECK_REG 0
160 #endif
161
162 /* MCDI is required for SFN7xxx and SFN8xx */
163 #define EFSYS_OPT_MCDI 1
164 #define EFSYS_OPT_MCDI_LOGGING 1
165 #define EFSYS_OPT_MCDI_PROXY_AUTH 1
166
167 #define EFSYS_OPT_MAC_STATS 1
168
169 #define EFSYS_OPT_LOOPBACK 0
170
171 #define EFSYS_OPT_MON_MCDI 0
172 #define EFSYS_OPT_MON_STATS 0
173
174 #define EFSYS_OPT_PHY_STATS 0
175 #define EFSYS_OPT_BIST 0
176 #define EFSYS_OPT_PHY_LED_CONTROL 0
177 #define EFSYS_OPT_PHY_FLAGS 0
178
179 #define EFSYS_OPT_VPD 0
180 #define EFSYS_OPT_NVRAM 0
181 #define EFSYS_OPT_BOOTCFG 0
182 #define EFSYS_OPT_IMAGE_LAYOUT 0
183
184 #define EFSYS_OPT_DIAG 0
185 #define EFSYS_OPT_RX_SCALE 1
186 #define EFSYS_OPT_QSTATS 0
187 /* Filters support is required for SFN7xxx and SFN8xx */
188 #define EFSYS_OPT_FILTER 1
189 #define EFSYS_OPT_RX_SCATTER 0
190
191 #define EFSYS_OPT_EV_PREFETCH 0
192
193 #define EFSYS_OPT_DECODE_INTR_FATAL 0
194
195 #define EFSYS_OPT_LICENSING 0
196
197 #define EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0
198
199 #define EFSYS_OPT_RX_PACKED_STREAM 0
200
201 #define EFSYS_OPT_TUNNEL 1
202
203 #define EFSYS_OPT_FW_SUBVARIANT_AWARE 1
204
205 /* ID */
206
207 typedef struct __efsys_identifier_s efsys_identifier_t;
208
209
210 #define EFSYS_PROBE(_name)                                              \
211         do { } while (0)
212
213 #define EFSYS_PROBE1(_name, _type1, _arg1)                              \
214         do { } while (0)
215
216 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)               \
217         do { } while (0)
218
219 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,               \
220                      _type3, _arg3)                                     \
221         do { } while (0)
222
223 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,               \
224                      _type3, _arg3, _type4, _arg4)                      \
225         do { } while (0)
226
227 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
228                      _type3, _arg3, _type4, _arg4, _type5, _arg5)       \
229         do { } while (0)
230
231 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
232                      _type3, _arg3, _type4, _arg4, _type5, _arg5,       \
233                      _type6, _arg6)                                     \
234         do { } while (0)
235
236 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
237                      _type3, _arg3, _type4, _arg4, _type5, _arg5,       \
238                      _type6, _arg6, _type7, _arg7)                      \
239         do { } while (0)
240
241
242 /* DMA */
243
244 typedef rte_iova_t efsys_dma_addr_t;
245
246 typedef struct efsys_mem_s {
247         const struct rte_memzone        *esm_mz;
248         /*
249          * Ideally it should have volatile qualifier to denote that
250          * the memory may be updated by someone else. However, it adds
251          * qualifier discard warnings when the pointer or its derivative
252          * is passed to memset() or rte_mov16().
253          * So, skip the qualifier here, but make sure that it is added
254          * below in access macros.
255          */
256         void                            *esm_base;
257         efsys_dma_addr_t                esm_addr;
258 } efsys_mem_t;
259
260
261 #define EFSYS_MEM_ZERO(_esmp, _size)                                    \
262         do {                                                            \
263                 (void)memset((void *)(_esmp)->esm_base, 0, (_size));    \
264                                                                         \
265                 _NOTE(CONSTANTCONDITION);                               \
266         } while (B_FALSE)
267
268 #define EFSYS_MEM_READD(_esmp, _offset, _edp)                           \
269         do {                                                            \
270                 volatile uint8_t  *_base = (_esmp)->esm_base;           \
271                 volatile uint32_t *_addr;                               \
272                                                                         \
273                 _NOTE(CONSTANTCONDITION);                               \
274                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
275                                                                         \
276                 _addr = (volatile uint32_t *)(_base + (_offset));       \
277                 (_edp)->ed_u32[0] = _addr[0];                           \
278                                                                         \
279                 EFSYS_PROBE2(mem_readl, unsigned int, (_offset),        \
280                                          uint32_t, (_edp)->ed_u32[0]);  \
281                                                                         \
282                 _NOTE(CONSTANTCONDITION);                               \
283         } while (B_FALSE)
284
285 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp)                           \
286         do {                                                            \
287                 volatile uint8_t  *_base = (_esmp)->esm_base;           \
288                 volatile uint64_t *_addr;                               \
289                                                                         \
290                 _NOTE(CONSTANTCONDITION);                               \
291                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
292                                                                         \
293                 _addr = (volatile uint64_t *)(_base + (_offset));       \
294                 (_eqp)->eq_u64[0] = _addr[0];                           \
295                                                                         \
296                 EFSYS_PROBE3(mem_readq, unsigned int, (_offset),        \
297                                          uint32_t, (_eqp)->eq_u32[1],   \
298                                          uint32_t, (_eqp)->eq_u32[0]);  \
299                                                                         \
300                 _NOTE(CONSTANTCONDITION);                               \
301         } while (B_FALSE)
302
303 #define EFSYS_MEM_READO(_esmp, _offset, _eop)                           \
304         do {                                                            \
305                 volatile uint8_t *_base = (_esmp)->esm_base;            \
306                 volatile __m128i *_addr;                                \
307                                                                         \
308                 _NOTE(CONSTANTCONDITION);                               \
309                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
310                                                                         \
311                 _addr = (volatile __m128i *)(_base + (_offset));        \
312                 (_eop)->eo_u128[0] = _addr[0];                          \
313                                                                         \
314                 EFSYS_PROBE5(mem_reado, unsigned int, (_offset),        \
315                                          uint32_t, (_eop)->eo_u32[3],   \
316                                          uint32_t, (_eop)->eo_u32[2],   \
317                                          uint32_t, (_eop)->eo_u32[1],   \
318                                          uint32_t, (_eop)->eo_u32[0]);  \
319                                                                         \
320                 _NOTE(CONSTANTCONDITION);                               \
321         } while (B_FALSE)
322
323
324 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp)                          \
325         do {                                                            \
326                 volatile uint8_t  *_base = (_esmp)->esm_base;           \
327                 volatile uint32_t *_addr;                               \
328                                                                         \
329                 _NOTE(CONSTANTCONDITION);                               \
330                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
331                                                                         \
332                 EFSYS_PROBE2(mem_writed, unsigned int, (_offset),       \
333                                          uint32_t, (_edp)->ed_u32[0]);  \
334                                                                         \
335                 _addr = (volatile uint32_t *)(_base + (_offset));       \
336                 _addr[0] = (_edp)->ed_u32[0];                           \
337                                                                         \
338                 _NOTE(CONSTANTCONDITION);                               \
339         } while (B_FALSE)
340
341 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)                          \
342         do {                                                            \
343                 volatile uint8_t  *_base = (_esmp)->esm_base;           \
344                 volatile uint64_t *_addr;                               \
345                                                                         \
346                 _NOTE(CONSTANTCONDITION);                               \
347                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
348                                                                         \
349                 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset),       \
350                                          uint32_t, (_eqp)->eq_u32[1],   \
351                                          uint32_t, (_eqp)->eq_u32[0]);  \
352                                                                         \
353                 _addr = (volatile uint64_t *)(_base + (_offset));       \
354                 _addr[0] = (_eqp)->eq_u64[0];                           \
355                                                                         \
356                 _NOTE(CONSTANTCONDITION);                               \
357         } while (B_FALSE)
358
359 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop)                          \
360         do {                                                            \
361                 volatile uint8_t *_base = (_esmp)->esm_base;            \
362                 volatile __m128i *_addr;                                \
363                                                                         \
364                 _NOTE(CONSTANTCONDITION);                               \
365                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
366                                                                         \
367                                                                         \
368                 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset),       \
369                                          uint32_t, (_eop)->eo_u32[3],   \
370                                          uint32_t, (_eop)->eo_u32[2],   \
371                                          uint32_t, (_eop)->eo_u32[1],   \
372                                          uint32_t, (_eop)->eo_u32[0]);  \
373                                                                         \
374                 _addr = (volatile __m128i *)(_base + (_offset));        \
375                 _addr[0] = (_eop)->eo_u128[0];                          \
376                                                                         \
377                 _NOTE(CONSTANTCONDITION);                               \
378         } while (B_FALSE)
379
380
381 #define EFSYS_MEM_SIZE(_esmp)                                           \
382         ((_esmp)->esm_mz->len)
383
384 #define EFSYS_MEM_ADDR(_esmp)                                           \
385         ((_esmp)->esm_addr)
386
387 #define EFSYS_MEM_IS_NULL(_esmp)                                        \
388         ((_esmp)->esm_base == NULL)
389
390 #define EFSYS_MEM_PREFETCH(_esmp, _offset)                              \
391         do {                                                            \
392                 volatile uint8_t *_base = (_esmp)->esm_base;            \
393                                                                         \
394                 rte_prefetch0(_base + (_offset));                       \
395         } while (0)
396
397
398 /* BAR */
399
400 typedef struct efsys_bar_s {
401         rte_spinlock_t          esb_lock;
402         int                     esb_rid;
403         struct rte_pci_device   *esb_dev;
404         /*
405          * Ideally it should have volatile qualifier to denote that
406          * the memory may be updated by someone else. However, it adds
407          * qualifier discard warnings when the pointer or its derivative
408          * is passed to memset() or rte_mov16().
409          * So, skip the qualifier here, but make sure that it is added
410          * below in access macros.
411          */
412         void                    *esb_base;
413 } efsys_bar_t;
414
415 #define SFC_BAR_LOCK_INIT(_esbp, _ifname)                               \
416         do {                                                            \
417                 rte_spinlock_init(&(_esbp)->esb_lock);                  \
418                 _NOTE(CONSTANTCONDITION);                               \
419         } while (B_FALSE)
420 #define SFC_BAR_LOCK_DESTROY(_esbp)     ((void)0)
421 #define SFC_BAR_LOCK(_esbp)             rte_spinlock_lock(&(_esbp)->esb_lock)
422 #define SFC_BAR_UNLOCK(_esbp)           rte_spinlock_unlock(&(_esbp)->esb_lock)
423
424 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock)                    \
425         do {                                                            \
426                 volatile uint8_t  *_base = (_esbp)->esb_base;           \
427                 volatile uint32_t *_addr;                               \
428                                                                         \
429                 _NOTE(CONSTANTCONDITION);                               \
430                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
431                 _NOTE(CONSTANTCONDITION);                               \
432                 if (_lock)                                              \
433                         SFC_BAR_LOCK(_esbp);                            \
434                                                                         \
435                 _addr = (volatile uint32_t *)(_base + (_offset));       \
436                 rte_rmb();                                              \
437                 (_edp)->ed_u32[0] = rte_read32_relaxed(_addr);          \
438                                                                         \
439                 EFSYS_PROBE2(bar_readd, unsigned int, (_offset),        \
440                                          uint32_t, (_edp)->ed_u32[0]);  \
441                                                                         \
442                 _NOTE(CONSTANTCONDITION);                               \
443                 if (_lock)                                              \
444                         SFC_BAR_UNLOCK(_esbp);                          \
445                 _NOTE(CONSTANTCONDITION);                               \
446         } while (B_FALSE)
447
448 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp)                           \
449         do {                                                            \
450                 volatile uint8_t  *_base = (_esbp)->esb_base;           \
451                 volatile uint64_t *_addr;                               \
452                                                                         \
453                 _NOTE(CONSTANTCONDITION);                               \
454                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
455                                                                         \
456                 SFC_BAR_LOCK(_esbp);                                    \
457                                                                         \
458                 _addr = (volatile uint64_t *)(_base + (_offset));       \
459                 rte_rmb();                                              \
460                 (_eqp)->eq_u64[0] = rte_read64_relaxed(_addr);          \
461                                                                         \
462                 EFSYS_PROBE3(bar_readq, unsigned int, (_offset),        \
463                                          uint32_t, (_eqp)->eq_u32[1],   \
464                                          uint32_t, (_eqp)->eq_u32[0]);  \
465                                                                         \
466                 SFC_BAR_UNLOCK(_esbp);                                  \
467                 _NOTE(CONSTANTCONDITION);                               \
468         } while (B_FALSE)
469
470 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)                    \
471         do {                                                            \
472                 volatile uint8_t *_base = (_esbp)->esb_base;            \
473                 volatile __m128i *_addr;                                \
474                                                                         \
475                 _NOTE(CONSTANTCONDITION);                               \
476                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
477                                                                         \
478                 _NOTE(CONSTANTCONDITION);                               \
479                 if (_lock)                                              \
480                         SFC_BAR_LOCK(_esbp);                            \
481                                                                         \
482                 _addr = (volatile __m128i *)(_base + (_offset));        \
483                 rte_rmb();                                              \
484                 /* There is no rte_read128_relaxed() yet */             \
485                 (_eop)->eo_u128[0] = _addr[0];                          \
486                                                                         \
487                 EFSYS_PROBE5(bar_reado, unsigned int, (_offset),        \
488                                          uint32_t, (_eop)->eo_u32[3],   \
489                                          uint32_t, (_eop)->eo_u32[2],   \
490                                          uint32_t, (_eop)->eo_u32[1],   \
491                                          uint32_t, (_eop)->eo_u32[0]);  \
492                                                                         \
493                 _NOTE(CONSTANTCONDITION);                               \
494                 if (_lock)                                              \
495                         SFC_BAR_UNLOCK(_esbp);                          \
496                 _NOTE(CONSTANTCONDITION);                               \
497         } while (B_FALSE)
498
499
500 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock)                   \
501         do {                                                            \
502                 volatile uint8_t  *_base = (_esbp)->esb_base;           \
503                 volatile uint32_t *_addr;                               \
504                                                                         \
505                 _NOTE(CONSTANTCONDITION);                               \
506                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
507                                                                         \
508                 _NOTE(CONSTANTCONDITION);                               \
509                 if (_lock)                                              \
510                         SFC_BAR_LOCK(_esbp);                            \
511                                                                         \
512                 EFSYS_PROBE2(bar_writed, unsigned int, (_offset),       \
513                                          uint32_t, (_edp)->ed_u32[0]);  \
514                                                                         \
515                 _addr = (volatile uint32_t *)(_base + (_offset));       \
516                 rte_write32_relaxed((_edp)->ed_u32[0], _addr);          \
517                 rte_wmb();                                              \
518                                                                         \
519                 _NOTE(CONSTANTCONDITION);                               \
520                 if (_lock)                                              \
521                         SFC_BAR_UNLOCK(_esbp);                          \
522                 _NOTE(CONSTANTCONDITION);                               \
523         } while (B_FALSE)
524
525 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)                          \
526         do {                                                            \
527                 volatile uint8_t  *_base = (_esbp)->esb_base;           \
528                 volatile uint64_t *_addr;                               \
529                                                                         \
530                 _NOTE(CONSTANTCONDITION);                               \
531                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
532                                                                         \
533                 SFC_BAR_LOCK(_esbp);                                    \
534                                                                         \
535                 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset),       \
536                                          uint32_t, (_eqp)->eq_u32[1],   \
537                                          uint32_t, (_eqp)->eq_u32[0]);  \
538                                                                         \
539                 _addr = (volatile uint64_t *)(_base + (_offset));       \
540                 rte_write64_relaxed((_eqp)->eq_u64[0], _addr);          \
541                 rte_wmb();                                              \
542                                                                         \
543                 SFC_BAR_UNLOCK(_esbp);                                  \
544                 _NOTE(CONSTANTCONDITION);                               \
545         } while (B_FALSE)
546
547 /*
548  * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
549  * (required by PIO hardware).
550  *
551  * Neither VFIO, nor UIO, nor NIC UIO (on FreeBSD) support
552  * write-combined memory mapped to user-land, so just abort if used.
553  */
554 #define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp)                       \
555         do {                                                            \
556                 rte_panic("Write-combined BAR access not supported");   \
557         } while (B_FALSE)
558
559 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)                   \
560         do {                                                            \
561                 volatile uint8_t *_base = (_esbp)->esb_base;            \
562                 volatile __m128i *_addr;                                \
563                                                                         \
564                 _NOTE(CONSTANTCONDITION);                               \
565                 SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
566                                                                         \
567                 _NOTE(CONSTANTCONDITION);                               \
568                 if (_lock)                                              \
569                         SFC_BAR_LOCK(_esbp);                            \
570                                                                         \
571                 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset),       \
572                                          uint32_t, (_eop)->eo_u32[3],   \
573                                          uint32_t, (_eop)->eo_u32[2],   \
574                                          uint32_t, (_eop)->eo_u32[1],   \
575                                          uint32_t, (_eop)->eo_u32[0]);  \
576                                                                         \
577                 _addr = (volatile __m128i *)(_base + (_offset));        \
578                 /* There is no rte_write128_relaxed() yet */            \
579                 _addr[0] = (_eop)->eo_u128[0];                          \
580                 rte_wmb();                                              \
581                                                                         \
582                 _NOTE(CONSTANTCONDITION);                               \
583                 if (_lock)                                              \
584                         SFC_BAR_UNLOCK(_esbp);                          \
585                 _NOTE(CONSTANTCONDITION);                               \
586         } while (B_FALSE)
587
588 /* Use the standard octo-word write for doorbell writes */
589 #define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop)                 \
590         do {                                                            \
591                 EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE);  \
592                 _NOTE(CONSTANTCONDITION);                               \
593         } while (B_FALSE)
594
595 /* SPIN */
596
597 #define EFSYS_SPIN(_us)                                                 \
598         do {                                                            \
599                 rte_delay_us(_us);                                      \
600                 _NOTE(CONSTANTCONDITION);                               \
601         } while (B_FALSE)
602
603 #define EFSYS_SLEEP EFSYS_SPIN
604
605 /* BARRIERS */
606
607 #define EFSYS_MEM_READ_BARRIER()        rte_rmb()
608 #define EFSYS_PIO_WRITE_BARRIER()       rte_io_wmb()
609
610 /* DMA SYNC */
611
612 /*
613  * DPDK does not provide any DMA syncing API, and no PMD drivers
614  * have any traces of explicit DMA syncing.
615  * DMA mapping is assumed to be coherent.
616  */
617
618 #define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size)        ((void)0)
619
620 /* Just avoid store and compiler (impliciltly) reordering */
621 #define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size)        rte_wmb()
622
623 /* TIMESTAMP */
624
625 typedef uint64_t efsys_timestamp_t;
626
627 #define EFSYS_TIMESTAMP(_usp)                                           \
628         do {                                                            \
629                 *(_usp) = rte_get_timer_cycles() * 1000000 /            \
630                         rte_get_timer_hz();                             \
631                 _NOTE(CONSTANTCONDITION);                               \
632         } while (B_FALSE)
633
634 /* KMEM */
635
636 #define EFSYS_KMEM_ALLOC(_esip, _size, _p)                              \
637         do {                                                            \
638                 (_esip) = (_esip);                                      \
639                 (_p) = rte_zmalloc("sfc", (_size), 0);                  \
640                 _NOTE(CONSTANTCONDITION);                               \
641         } while (B_FALSE)
642
643 #define EFSYS_KMEM_FREE(_esip, _size, _p)                               \
644         do {                                                            \
645                 (void)(_esip);                                          \
646                 (void)(_size);                                          \
647                 rte_free((_p));                                         \
648                 _NOTE(CONSTANTCONDITION);                               \
649         } while (B_FALSE)
650
651 /* LOCK */
652
653 typedef rte_spinlock_t efsys_lock_t;
654
655 #define SFC_EFSYS_LOCK_INIT(_eslp, _ifname, _label)     \
656         rte_spinlock_init((_eslp))
657 #define SFC_EFSYS_LOCK_DESTROY(_eslp) ((void)0)
658 #define SFC_EFSYS_LOCK(_eslp)                           \
659         rte_spinlock_lock((_eslp))
660 #define SFC_EFSYS_UNLOCK(_eslp)                         \
661         rte_spinlock_unlock((_eslp))
662 #define SFC_EFSYS_LOCK_ASSERT_OWNED(_eslp)              \
663         SFC_ASSERT(rte_spinlock_is_locked((_eslp)))
664
665 typedef int efsys_lock_state_t;
666
667 #define EFSYS_LOCK_MAGIC        0x000010c4
668
669 #define EFSYS_LOCK(_lockp, _state)                              \
670         do {                                                    \
671                 SFC_EFSYS_LOCK(_lockp);                         \
672                 (_state) = EFSYS_LOCK_MAGIC;                    \
673                 _NOTE(CONSTANTCONDITION);                       \
674         } while (B_FALSE)
675
676 #define EFSYS_UNLOCK(_lockp, _state)                            \
677         do {                                                    \
678                 SFC_ASSERT((_state) == EFSYS_LOCK_MAGIC);       \
679                 SFC_EFSYS_UNLOCK(_lockp);                       \
680                 _NOTE(CONSTANTCONDITION);                       \
681         } while (B_FALSE)
682
683 /* STAT */
684
685 typedef uint64_t        efsys_stat_t;
686
687 #define EFSYS_STAT_INCR(_knp, _delta)                           \
688         do {                                                    \
689                 *(_knp) += (_delta);                            \
690                 _NOTE(CONSTANTCONDITION);                       \
691         } while (B_FALSE)
692
693 #define EFSYS_STAT_DECR(_knp, _delta)                           \
694         do {                                                    \
695                 *(_knp) -= (_delta);                            \
696                 _NOTE(CONSTANTCONDITION);                       \
697         } while (B_FALSE)
698
699 #define EFSYS_STAT_SET(_knp, _val)                              \
700         do {                                                    \
701                 *(_knp) = (_val);                               \
702                 _NOTE(CONSTANTCONDITION);                       \
703         } while (B_FALSE)
704
705 #define EFSYS_STAT_SET_QWORD(_knp, _valp)                       \
706         do {                                                    \
707                 *(_knp) = rte_le_to_cpu_64((_valp)->eq_u64[0]); \
708                 _NOTE(CONSTANTCONDITION);                       \
709         } while (B_FALSE)
710
711 #define EFSYS_STAT_SET_DWORD(_knp, _valp)                       \
712         do {                                                    \
713                 *(_knp) = rte_le_to_cpu_32((_valp)->ed_u32[0]); \
714                 _NOTE(CONSTANTCONDITION);                       \
715         } while (B_FALSE)
716
717 #define EFSYS_STAT_INCR_QWORD(_knp, _valp)                              \
718         do {                                                            \
719                 *(_knp) += rte_le_to_cpu_64((_valp)->eq_u64[0]);        \
720                 _NOTE(CONSTANTCONDITION);                               \
721         } while (B_FALSE)
722
723 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp)                              \
724         do {                                                            \
725                 *(_knp) -= rte_le_to_cpu_64((_valp)->eq_u64[0]);        \
726                 _NOTE(CONSTANTCONDITION);                               \
727         } while (B_FALSE)
728
729 /* ERR */
730
731 #if EFSYS_OPT_DECODE_INTR_FATAL
732 #define EFSYS_ERR(_esip, _code, _dword0, _dword1)                       \
733         do {                                                            \
734                 (void)(_esip);                                          \
735                 SFC_GENERIC_LOG(ERR, "FATAL ERROR #%u (0x%08x%08x)",    \
736                         (_code), (_dword0), (_dword1));                 \
737                 _NOTE(CONSTANTCONDITION);                               \
738         } while (B_FALSE)
739 #endif
740
741 /* ASSERT */
742
743 /* RTE_VERIFY from DPDK treats expressions with % operator incorrectly,
744  * so we re-implement it here
745  */
746 #ifdef RTE_LIBRTE_SFC_EFX_DEBUG
747 #define EFSYS_ASSERT(_exp)                                              \
748         do {                                                            \
749                 if (unlikely(!(_exp)))                                  \
750                         rte_panic("line %d\tassert \"%s\" failed\n",    \
751                                   __LINE__, (#_exp));                   \
752         } while (0)
753 #else
754 #define EFSYS_ASSERT(_exp)              (void)(_exp)
755 #endif
756
757 #define EFSYS_ASSERT3(_x, _op, _y, _t)  EFSYS_ASSERT((_t)(_x) _op (_t)(_y))
758
759 #define EFSYS_ASSERT3U(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, uint64_t)
760 #define EFSYS_ASSERT3S(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, int64_t)
761 #define EFSYS_ASSERT3P(_x, _op, _y)     EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
762
763 /* ROTATE */
764
765 #define EFSYS_HAS_ROTL_DWORD    0
766
767 #ifdef __cplusplus
768 }
769 #endif
770
771 #endif  /* _SFC_COMMON_EFSYS_H */