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