060d8fef37efcbd2c0d8d9fbb6fa52732456c6d8
[dpdk.git] / drivers / net / sfc / sfc_ef10.h
1 /*-
2  *   BSD LICENSE
3  *
4  * Copyright (c) 2017 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * This software was jointly developed between OKTET Labs (under contract
8  * for Solarflare) and Solarflare Communications, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  *    this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  *    this list of conditions and the following disclaimer in the documentation
17  *    and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #ifndef _SFC_EF10_H
33 #define _SFC_EF10_H
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 /* Number of events in one cache line */
40 #define SFC_EF10_EV_PER_CACHE_LINE \
41         (RTE_CACHE_LINE_SIZE / sizeof(efx_qword_t))
42
43 #define SFC_EF10_EV_QCLEAR_MASK         (~(SFC_EF10_EV_PER_CACHE_LINE - 1))
44
45 #if defined(SFC_EF10_EV_QCLEAR_USE_EFX)
46 static inline void
47 sfc_ef10_ev_qclear_cache_line(void *ptr)
48 {
49         efx_qword_t *entry = ptr;
50         unsigned int i;
51
52         for (i = 0; i < SFC_EF10_EV_PER_CACHE_LINE; ++i)
53                 EFX_SET_QWORD(entry[i]);
54 }
55 #else
56 /*
57  * It is possible to do it using AVX2 and AVX512F, but it shows less
58  * performance.
59  */
60 static inline void
61 sfc_ef10_ev_qclear_cache_line(void *ptr)
62 {
63         const __m128i val = _mm_set1_epi64x(UINT64_MAX);
64         __m128i *addr = ptr;
65         unsigned int i;
66
67         RTE_BUILD_BUG_ON(sizeof(val) > RTE_CACHE_LINE_SIZE);
68         RTE_BUILD_BUG_ON(RTE_CACHE_LINE_SIZE % sizeof(val) != 0);
69
70         for (i = 0; i < RTE_CACHE_LINE_SIZE / sizeof(val); ++i)
71                 _mm_store_si128(&addr[i], val);
72 }
73 #endif
74
75 static inline void
76 sfc_ef10_ev_qclear(efx_qword_t *hw_ring, unsigned int ptr_mask,
77                    unsigned int old_read_ptr, unsigned int read_ptr)
78 {
79         const unsigned int clear_ptr = read_ptr & SFC_EF10_EV_QCLEAR_MASK;
80         unsigned int old_clear_ptr = old_read_ptr & SFC_EF10_EV_QCLEAR_MASK;
81
82         while (old_clear_ptr != clear_ptr) {
83                 sfc_ef10_ev_qclear_cache_line(
84                         &hw_ring[old_clear_ptr & ptr_mask]);
85                 old_clear_ptr += SFC_EF10_EV_PER_CACHE_LINE;
86         }
87
88         /*
89          * No barriers here.
90          * Functions which push doorbell should care about correct
91          * ordering: store instructions which fill in EvQ ring should be
92          * retired from CPU and DMA sync before doorbell which will allow
93          * to use these event entries.
94          */
95 }
96
97 static inline bool
98 sfc_ef10_ev_present(const efx_qword_t ev)
99 {
100         return ~EFX_QWORD_FIELD(ev, EFX_DWORD_0) |
101                ~EFX_QWORD_FIELD(ev, EFX_DWORD_1);
102 }
103
104 #ifdef __cplusplus
105 }
106 #endif
107 #endif /* _SFC_EF10_H */