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