Branch data Line data Source code
1 : : /*
2 : : * SPDX-License-Identifier: BSD-3-Clause
3 : : * Copyright(c) 2023 Napatech A/S
4 : : */
5 : :
6 : : #include <unistd.h>
7 : : #include <stdlib.h>
8 : : #include <stdint.h>
9 : : #include <inttypes.h>
10 : : #include <assert.h>
11 : :
12 : : #include <rte_ethdev.h>
13 : : #include <rte_malloc.h>
14 : :
15 : : #include "ntlog.h"
16 : : #include "nt_util.h"
17 : :
18 : : static struct nt_util_vfio_impl vfio_cb;
19 : :
20 : : /* uses usleep which schedules out the calling thread */
21 : 0 : void nt_os_wait_usec(int val)
22 : : {
23 : 0 : rte_delay_us_sleep(val);
24 : 0 : }
25 : :
26 : : /* spins in a waiting loop calling pause asm instruction uses RDTSC - precise wait */
27 : 0 : void nt_os_wait_usec_poll(int val)
28 : : {
29 : 0 : rte_delay_us(val);
30 : 0 : }
31 : :
32 : 0 : uint64_t nt_os_get_time_monotonic_counter(void)
33 : : {
34 : 0 : return rte_get_timer_cycles();
35 : : }
36 : :
37 : : /* Allocation size matching minimum alignment of specified size */
38 [ # # ]: 0 : uint64_t nt_util_align_size(uint64_t size)
39 : : {
40 : 0 : uint64_t alignment_size = 1ULL << rte_log2_u64(size);
41 : 0 : return alignment_size;
42 : : }
43 : :
44 : 0 : void nt_util_vfio_init(struct nt_util_vfio_impl *impl)
45 : : {
46 : 0 : vfio_cb = *impl;
47 : 0 : }
48 : :
49 : 0 : struct nt_dma_s *nt_dma_alloc(uint64_t size, uint64_t align, int numa)
50 : : {
51 : : int res;
52 : : struct nt_dma_s *vfio_addr;
53 : :
54 : 0 : vfio_addr = rte_malloc(NULL, sizeof(struct nt_dma_s), 0);
55 : :
56 [ # # ]: 0 : if (!vfio_addr) {
57 : 0 : NT_LOG(ERR, GENERAL, "VFIO rte_malloc failed");
58 : 0 : return NULL;
59 : : }
60 : :
61 : 0 : void *addr = rte_malloc_socket(NULL, size, align, numa);
62 : :
63 [ # # ]: 0 : if (!addr) {
64 : 0 : rte_free(vfio_addr);
65 : 0 : NT_LOG(ERR, GENERAL, "VFIO rte_malloc_socket failed");
66 : 0 : return NULL;
67 : : }
68 : :
69 : 0 : res = vfio_cb.vfio_dma_map(0, addr, &vfio_addr->iova, nt_util_align_size(size));
70 : :
71 [ # # ]: 0 : if (res != 0) {
72 : 0 : rte_free(addr);
73 : 0 : rte_free(vfio_addr);
74 : 0 : NT_LOG(ERR, GENERAL, "VFIO nt_dma_map failed");
75 : 0 : return NULL;
76 : : }
77 : :
78 : 0 : vfio_addr->addr = (uint64_t)addr;
79 : 0 : vfio_addr->size = nt_util_align_size(size);
80 : :
81 : 0 : NT_LOG(DBG, GENERAL,
82 : : "VFIO DMA alloc addr=%" PRIX64 ", iova=%" PRIX64
83 : : ", size=%" PRIX64 "align=0x%" PRIX64,
84 : : vfio_addr->addr, vfio_addr->iova, vfio_addr->size, align);
85 : :
86 : 0 : return vfio_addr;
87 : : }
88 : :
89 : 0 : void nt_dma_free(struct nt_dma_s *vfio_addr)
90 : : {
91 : 0 : NT_LOG(DBG, GENERAL, "VFIO DMA free addr=%" PRIX64 ", iova=%" PRIX64 ", size=%" PRIX64,
92 : : vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
93 : :
94 : 0 : int res = vfio_cb.vfio_dma_unmap(0, (void *)vfio_addr->addr, vfio_addr->iova,
95 : : vfio_addr->size);
96 : :
97 [ # # ]: 0 : if (res != 0) {
98 : 0 : NT_LOG(WRN, GENERAL,
99 : : "VFIO DMA free FAILED addr=%" PRIX64 ", iova=%" PRIX64 ", size=%" PRIX64,
100 : : vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
101 : : }
102 : :
103 : 0 : rte_free((void *)(vfio_addr->addr));
104 : 0 : rte_free(vfio_addr);
105 : 0 : }
106 : :
107 : : /* NOTE: please note the difference between RTE_ETH_SPEED_NUM_xxx and RTE_ETH_LINK_SPEED_xxx */
108 : 0 : int nt_link_speed_to_eth_speed_num(enum nt_link_speed_e nt_link_speed)
109 : : {
110 : : int eth_speed_num = RTE_ETH_SPEED_NUM_NONE;
111 : :
112 [ # # # # : 0 : switch (nt_link_speed) {
# # # #
# ]
113 : : case NT_LINK_SPEED_10M:
114 : : eth_speed_num = RTE_ETH_SPEED_NUM_10M;
115 : : break;
116 : :
117 : 0 : case NT_LINK_SPEED_100M:
118 : : eth_speed_num = RTE_ETH_SPEED_NUM_100M;
119 : 0 : break;
120 : :
121 : 0 : case NT_LINK_SPEED_1G:
122 : : eth_speed_num = RTE_ETH_SPEED_NUM_1G;
123 : 0 : break;
124 : :
125 : 0 : case NT_LINK_SPEED_10G:
126 : : eth_speed_num = RTE_ETH_SPEED_NUM_10G;
127 : 0 : break;
128 : :
129 : 0 : case NT_LINK_SPEED_25G:
130 : : eth_speed_num = RTE_ETH_SPEED_NUM_25G;
131 : 0 : break;
132 : :
133 : 0 : case NT_LINK_SPEED_40G:
134 : : eth_speed_num = RTE_ETH_SPEED_NUM_40G;
135 : 0 : break;
136 : :
137 : 0 : case NT_LINK_SPEED_50G:
138 : : eth_speed_num = RTE_ETH_SPEED_NUM_50G;
139 : 0 : break;
140 : :
141 : 0 : case NT_LINK_SPEED_100G:
142 : : eth_speed_num = RTE_ETH_SPEED_NUM_100G;
143 : 0 : break;
144 : :
145 : 0 : default:
146 : : eth_speed_num = RTE_ETH_SPEED_NUM_NONE;
147 : 0 : break;
148 : : }
149 : :
150 : 0 : return eth_speed_num;
151 : : }
152 : :
153 : 0 : uint32_t nt_link_speed_capa_to_eth_speed_capa(int nt_link_speed_capa)
154 : : {
155 : : uint32_t eth_speed_capa = 0;
156 : :
157 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_10M)
158 : : eth_speed_capa |= RTE_ETH_LINK_SPEED_10M;
159 : :
160 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_100M)
161 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_100M;
162 : :
163 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_1G)
164 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_1G;
165 : :
166 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_10G)
167 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_10G;
168 : :
169 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_25G)
170 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_25G;
171 : :
172 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_40G)
173 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_40G;
174 : :
175 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_50G)
176 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_50G;
177 : :
178 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_100G)
179 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_100G;
180 : :
181 : 0 : return eth_speed_capa;
182 : : }
183 : :
184 : : /* Converts link speed provided in Mbps to NT specific definitions.*/
185 : 0 : nt_link_speed_t convert_link_speed(int link_speed_mbps)
186 : : {
187 [ # # # # : 0 : switch (link_speed_mbps) {
# # # #
# ]
188 : : case 10:
189 : : return NT_LINK_SPEED_10M;
190 : :
191 : 0 : case 100:
192 : 0 : return NT_LINK_SPEED_100M;
193 : :
194 : 0 : case 1000:
195 : 0 : return NT_LINK_SPEED_1G;
196 : :
197 : 0 : case 10000:
198 : 0 : return NT_LINK_SPEED_10G;
199 : :
200 : 0 : case 40000:
201 : 0 : return NT_LINK_SPEED_40G;
202 : :
203 : 0 : case 100000:
204 : 0 : return NT_LINK_SPEED_100G;
205 : :
206 : 0 : case 50000:
207 : 0 : return NT_LINK_SPEED_50G;
208 : :
209 : 0 : case 25000:
210 : 0 : return NT_LINK_SPEED_25G;
211 : :
212 : 0 : default:
213 : 0 : return NT_LINK_SPEED_UNKNOWN;
214 : : }
215 : : }
216 : :
217 : 0 : int nt_link_duplex_to_eth_duplex(enum nt_link_duplex_e nt_link_duplex)
218 : : {
219 : : int eth_link_duplex = 0;
220 : :
221 [ # # ]: 0 : switch (nt_link_duplex) {
222 : 0 : case NT_LINK_DUPLEX_FULL:
223 : : eth_link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
224 : 0 : break;
225 : :
226 : : case NT_LINK_DUPLEX_HALF:
227 : : eth_link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
228 : : break;
229 : :
230 : : case NT_LINK_DUPLEX_UNKNOWN: /* fall-through */
231 : : default:
232 : : break;
233 : : }
234 : :
235 : 0 : return eth_link_duplex;
236 : : }
237 : :
238 : 0 : int string_to_u32(const char *key_str __rte_unused, const char *value_str, void *extra_args)
239 : : {
240 [ # # ]: 0 : if (!value_str || !extra_args)
241 : : return -1;
242 : :
243 : 0 : const uint32_t value = strtol(value_str, NULL, 0);
244 : 0 : *(uint32_t *)extra_args = value;
245 : 0 : return 0;
246 : : }
|