]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/dpdk/drivers/net/sfc/sfc_ef10.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / dpdk / drivers / net / sfc / sfc_ef10.h
CommitLineData
9f95a23c 1/* SPDX-License-Identifier: BSD-3-Clause
11fdf7f2 2 *
9f95a23c 3 * Copyright (c) 2017-2018 Solarflare Communications Inc.
11fdf7f2
TL
4 * All rights reserved.
5 *
6 * This software was jointly developed between OKTET Labs (under contract
7 * for Solarflare) and Solarflare Communications, Inc.
11fdf7f2
TL
8 */
9
10#ifndef _SFC_EF10_H
11#define _SFC_EF10_H
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17/* Number of events in one cache line */
18#define SFC_EF10_EV_PER_CACHE_LINE \
19 (RTE_CACHE_LINE_SIZE / sizeof(efx_qword_t))
20
21#define SFC_EF10_EV_QCLEAR_MASK (~(SFC_EF10_EV_PER_CACHE_LINE - 1))
22
23#if defined(SFC_EF10_EV_QCLEAR_USE_EFX)
24static inline void
25sfc_ef10_ev_qclear_cache_line(void *ptr)
26{
27 efx_qword_t *entry = ptr;
28 unsigned int i;
29
30 for (i = 0; i < SFC_EF10_EV_PER_CACHE_LINE; ++i)
31 EFX_SET_QWORD(entry[i]);
32}
33#else
34/*
35 * It is possible to do it using AVX2 and AVX512F, but it shows less
36 * performance.
37 */
38static inline void
39sfc_ef10_ev_qclear_cache_line(void *ptr)
40{
41 const __m128i val = _mm_set1_epi64x(UINT64_MAX);
42 __m128i *addr = ptr;
43 unsigned int i;
44
45 RTE_BUILD_BUG_ON(sizeof(val) > RTE_CACHE_LINE_SIZE);
46 RTE_BUILD_BUG_ON(RTE_CACHE_LINE_SIZE % sizeof(val) != 0);
47
48 for (i = 0; i < RTE_CACHE_LINE_SIZE / sizeof(val); ++i)
49 _mm_store_si128(&addr[i], val);
50}
51#endif
52
53static inline void
54sfc_ef10_ev_qclear(efx_qword_t *hw_ring, unsigned int ptr_mask,
55 unsigned int old_read_ptr, unsigned int read_ptr)
56{
57 const unsigned int clear_ptr = read_ptr & SFC_EF10_EV_QCLEAR_MASK;
58 unsigned int old_clear_ptr = old_read_ptr & SFC_EF10_EV_QCLEAR_MASK;
59
60 while (old_clear_ptr != clear_ptr) {
61 sfc_ef10_ev_qclear_cache_line(
62 &hw_ring[old_clear_ptr & ptr_mask]);
63 old_clear_ptr += SFC_EF10_EV_PER_CACHE_LINE;
64 }
65
66 /*
67 * No barriers here.
68 * Functions which push doorbell should care about correct
69 * ordering: store instructions which fill in EvQ ring should be
70 * retired from CPU and DMA sync before doorbell which will allow
71 * to use these event entries.
72 */
73}
74
75static inline bool
76sfc_ef10_ev_present(const efx_qword_t ev)
77{
78 return ~EFX_QWORD_FIELD(ev, EFX_DWORD_0) |
79 ~EFX_QWORD_FIELD(ev, EFX_DWORD_1);
80}
81
9f95a23c
TL
82
83/**
84 * Alignment requirement for value written to RX WPTR:
85 * the WPTR must be aligned to an 8 descriptor boundary.
86 */
87#define SFC_EF10_RX_WPTR_ALIGN 8u
88
89static inline void
90sfc_ef10_rx_qpush(volatile void *doorbell, unsigned int added,
91 unsigned int ptr_mask)
92{
93 efx_dword_t dword;
94
95 /* Hardware has alignment restriction for WPTR */
96 RTE_BUILD_BUG_ON(SFC_RX_REFILL_BULK % SFC_EF10_RX_WPTR_ALIGN != 0);
97 SFC_ASSERT(RTE_ALIGN(added, SFC_EF10_RX_WPTR_ALIGN) == added);
98
99 EFX_POPULATE_DWORD_1(dword, ERF_DZ_RX_DESC_WPTR, added & ptr_mask);
100
101 /* DMA sync to device is not required */
102
103 /*
104 * rte_write32() has rte_io_wmb() which guarantees that the STORE
105 * operations (i.e. Rx and event descriptor updates) that precede
106 * the rte_io_wmb() call are visible to NIC before the STORE
107 * operations that follow it (i.e. doorbell write).
108 */
109 rte_write32(dword.ed_u32[0], doorbell);
110}
111
112
113const uint32_t * sfc_ef10_supported_ptypes_get(uint32_t tunnel_encaps);
114
115
11fdf7f2
TL
116#ifdef __cplusplus
117}
118#endif
119#endif /* _SFC_EF10_H */