xref: /dpdk/drivers/net/ntnic/ntutil/nt_util.c (revision 389fca7577cc89dd64b9ef37b6a6f64e6e1f68d2)
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 void nt_os_wait_usec(int val)
22 {
23 	rte_delay_us_sleep(val);
24 }
25 
26 uint64_t nt_os_get_time_monotonic_counter(void)
27 {
28 	return rte_get_timer_cycles();
29 }
30 
31 /* Allocation size matching minimum alignment of specified size */
32 uint64_t nt_util_align_size(uint64_t size)
33 {
34 	return 1 << rte_log2_u64(size);
35 }
36 
37 void nt_util_vfio_init(struct nt_util_vfio_impl *impl)
38 {
39 	vfio_cb = *impl;
40 }
41 
42 struct nt_dma_s *nt_dma_alloc(uint64_t size, uint64_t align, int numa)
43 {
44 	int res;
45 	struct nt_dma_s *vfio_addr;
46 
47 	vfio_addr = rte_malloc(NULL, sizeof(struct nt_dma_s), 0);
48 
49 	if (!vfio_addr) {
50 		NT_LOG(ERR, GENERAL, "VFIO rte_malloc failed\n");
51 		return NULL;
52 	}
53 
54 	void *addr = rte_malloc_socket(NULL, size, align, numa);
55 
56 	if (!addr) {
57 		rte_free(vfio_addr);
58 		NT_LOG(ERR, GENERAL, "VFIO rte_malloc_socket failed\n");
59 		return NULL;
60 	}
61 
62 	res = vfio_cb.vfio_dma_map(0, addr, &vfio_addr->iova, nt_util_align_size(size));
63 
64 	if (res != 0) {
65 		rte_free(addr);
66 		rte_free(vfio_addr);
67 		NT_LOG(ERR, GENERAL, "VFIO nt_dma_map failed\n");
68 		return NULL;
69 	}
70 
71 	vfio_addr->addr = (uint64_t)addr;
72 	vfio_addr->size = nt_util_align_size(size);
73 
74 	NT_LOG(DBG, GENERAL,
75 		"VFIO DMA alloc addr=%" PRIX64 ", iova=%" PRIX64
76 		", size=%" PRIX64 "align=0x%" PRIX64 "\n",
77 		vfio_addr->addr, vfio_addr->iova, vfio_addr->size, align);
78 
79 	return vfio_addr;
80 }
81 
82 void nt_dma_free(struct nt_dma_s *vfio_addr)
83 {
84 	NT_LOG(DBG, GENERAL, "VFIO DMA free addr=%" PRIX64 ", iova=%" PRIX64 ", size=%" PRIX64 "\n",
85 		vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
86 
87 	int res = vfio_cb.vfio_dma_unmap(0, (void *)vfio_addr->addr, vfio_addr->iova,
88 			vfio_addr->size);
89 
90 	if (res != 0) {
91 		NT_LOG(WRN, GENERAL,
92 			"VFIO DMA free FAILED addr=%" PRIX64 ", iova=%" PRIX64 ", size=%" PRIX64 "\n",
93 			vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
94 	}
95 
96 	rte_free((void *)(vfio_addr->addr));
97 	rte_free(vfio_addr);
98 }
99 
100 /* NOTE: please note the difference between RTE_ETH_SPEED_NUM_xxx and RTE_ETH_LINK_SPEED_xxx */
101 int nt_link_speed_to_eth_speed_num(enum nt_link_speed_e nt_link_speed)
102 {
103 	int eth_speed_num = RTE_ETH_SPEED_NUM_NONE;
104 
105 	switch (nt_link_speed) {
106 	case NT_LINK_SPEED_10M:
107 		eth_speed_num = RTE_ETH_SPEED_NUM_10M;
108 		break;
109 
110 	case NT_LINK_SPEED_100M:
111 		eth_speed_num = RTE_ETH_SPEED_NUM_100M;
112 		break;
113 
114 	case NT_LINK_SPEED_1G:
115 		eth_speed_num = RTE_ETH_SPEED_NUM_1G;
116 		break;
117 
118 	case NT_LINK_SPEED_10G:
119 		eth_speed_num = RTE_ETH_SPEED_NUM_10G;
120 		break;
121 
122 	case NT_LINK_SPEED_25G:
123 		eth_speed_num = RTE_ETH_SPEED_NUM_25G;
124 		break;
125 
126 	case NT_LINK_SPEED_40G:
127 		eth_speed_num = RTE_ETH_SPEED_NUM_40G;
128 		break;
129 
130 	case NT_LINK_SPEED_50G:
131 		eth_speed_num = RTE_ETH_SPEED_NUM_50G;
132 		break;
133 
134 	case NT_LINK_SPEED_100G:
135 		eth_speed_num = RTE_ETH_SPEED_NUM_100G;
136 		break;
137 
138 	default:
139 		eth_speed_num = RTE_ETH_SPEED_NUM_NONE;
140 		break;
141 	}
142 
143 	return eth_speed_num;
144 }
145 
146 uint32_t nt_link_speed_capa_to_eth_speed_capa(int nt_link_speed_capa)
147 {
148 	uint32_t eth_speed_capa = 0;
149 
150 	if (nt_link_speed_capa & NT_LINK_SPEED_10M)
151 		eth_speed_capa |= RTE_ETH_LINK_SPEED_10M;
152 
153 	if (nt_link_speed_capa & NT_LINK_SPEED_100M)
154 		eth_speed_capa |= RTE_ETH_LINK_SPEED_100M;
155 
156 	if (nt_link_speed_capa & NT_LINK_SPEED_1G)
157 		eth_speed_capa |= RTE_ETH_LINK_SPEED_1G;
158 
159 	if (nt_link_speed_capa & NT_LINK_SPEED_10G)
160 		eth_speed_capa |= RTE_ETH_LINK_SPEED_10G;
161 
162 	if (nt_link_speed_capa & NT_LINK_SPEED_25G)
163 		eth_speed_capa |= RTE_ETH_LINK_SPEED_25G;
164 
165 	if (nt_link_speed_capa & NT_LINK_SPEED_40G)
166 		eth_speed_capa |= RTE_ETH_LINK_SPEED_40G;
167 
168 	if (nt_link_speed_capa & NT_LINK_SPEED_50G)
169 		eth_speed_capa |= RTE_ETH_LINK_SPEED_50G;
170 
171 	if (nt_link_speed_capa & NT_LINK_SPEED_100G)
172 		eth_speed_capa |= RTE_ETH_LINK_SPEED_100G;
173 
174 	return eth_speed_capa;
175 }
176 
177 /* Converts link speed provided in Mbps to NT specific definitions.*/
178 nt_link_speed_t convert_link_speed(int link_speed_mbps)
179 {
180 	switch (link_speed_mbps) {
181 	case 10:
182 		return NT_LINK_SPEED_10M;
183 
184 	case 100:
185 		return NT_LINK_SPEED_100M;
186 
187 	case 1000:
188 		return NT_LINK_SPEED_1G;
189 
190 	case 10000:
191 		return NT_LINK_SPEED_10G;
192 
193 	case 40000:
194 		return NT_LINK_SPEED_40G;
195 
196 	case 100000:
197 		return NT_LINK_SPEED_100G;
198 
199 	case 50000:
200 		return NT_LINK_SPEED_50G;
201 
202 	case 25000:
203 		return NT_LINK_SPEED_25G;
204 
205 	default:
206 		return NT_LINK_SPEED_UNKNOWN;
207 	}
208 }
209 
210 int nt_link_duplex_to_eth_duplex(enum nt_link_duplex_e nt_link_duplex)
211 {
212 	int eth_link_duplex = 0;
213 
214 	switch (nt_link_duplex) {
215 	case NT_LINK_DUPLEX_FULL:
216 		eth_link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
217 		break;
218 
219 	case NT_LINK_DUPLEX_HALF:
220 		eth_link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
221 		break;
222 
223 	case NT_LINK_DUPLEX_UNKNOWN:	/* fall-through */
224 	default:
225 		break;
226 	}
227 
228 	return eth_link_duplex;
229 }
230