Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <sys/types.h>
6 : : #include <sys/stat.h>
7 : : #include <fcntl.h>
8 : : #include <sys/ioctl.h>
9 : : #include <sys/mman.h>
10 : : #include <unistd.h>
11 : : #include <inttypes.h>
12 : : #include <rte_version.h>
13 : : #include <eal_export.h>
14 : :
15 : : #include "sxe2_osal.h"
16 : : #include "sxe2_common_log.h"
17 : : #include "sxe2_ioctl_chnl.h"
18 : : #include "sxe2_ioctl_chnl_func.h"
19 : :
20 : : #define SXE2_CHR_DEV_NAME "/dev/sxe2-dpdk-"
21 : :
22 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_cmd_close)
23 : : void
24 : 0 : sxe2_drv_cmd_close(struct sxe2_common_device *cdev)
25 : : {
26 : 0 : cdev->config.kernel_reset = true;
27 : 0 : }
28 : :
29 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_cmd_exec)
30 : : int32_t
31 : 0 : sxe2_drv_cmd_exec(struct sxe2_common_device *cdev,
32 : : struct sxe2_drv_cmd_params *cmd_params)
33 : : {
34 : : int32_t cmd_fd;
35 : : int32_t ret = -EIO;
36 : :
37 [ # # ]: 0 : if (cdev->config.kernel_reset) {
38 : : ret = -EPERM;
39 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
40 : 0 : goto l_end;
41 : : }
42 : :
43 : 0 : cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
44 [ # # ]: 0 : if (cmd_fd < 0) {
45 : : ret = -EBADF;
46 : 0 : PMD_LOG_ERR(COM, "Fail to exec cmd, fd[%d] error", cmd_fd);
47 : 0 : goto l_end;
48 : : }
49 : :
50 : 0 : PMD_LOG_DEBUG(COM, "Exec drv cmd fd[%d] trace_id[0x%"PRIx64"]"
51 : : "opcode[0x%x] req_len[%d] resp_len[%d]",
52 : : cmd_fd, cmd_params->trace_id, cmd_params->opcode,
53 : : cmd_params->req_len, cmd_params->resp_len);
54 : :
55 : 0 : pthread_mutex_lock(&cdev->config.lock);
56 : 0 : ret = ioctl(cmd_fd, SXE2_COM_CMD_PASSTHROUGH, cmd_params);
57 [ # # ]: 0 : if (ret < 0) {
58 : 0 : PMD_LOG_ERR(COM, "Fail to exec cmd, fd[%d] opcode[0x%x] ret[%d], err:%s",
59 : : cmd_fd, cmd_params->opcode, ret, strerror(errno));
60 : 0 : ret = -errno;
61 : 0 : pthread_mutex_unlock(&cdev->config.lock);
62 : 0 : goto l_end;
63 : : }
64 : 0 : pthread_mutex_unlock(&cdev->config.lock);
65 : :
66 : 0 : l_end:
67 : 0 : return ret;
68 : : }
69 : :
70 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_open)
71 : : int32_t
72 : 0 : sxe2_drv_dev_open(struct sxe2_common_device *cdev, struct rte_pci_device *pci_dev)
73 : : {
74 : : int32_t ret = 0;
75 : : int32_t fd = 0;
76 : 0 : char drv_name[32] = {0};
77 : :
78 : 0 : snprintf(drv_name, sizeof(drv_name),
79 : : "%s%04"PRIx32":%02"PRIx8":%02"PRIx8".%"PRIx8,
80 : : SXE2_CHR_DEV_NAME,
81 : : pci_dev->addr.domain,
82 : 0 : pci_dev->addr.bus,
83 : 0 : pci_dev->addr.devid,
84 : 0 : pci_dev->addr.function);
85 : :
86 : : fd = open(drv_name, O_RDWR);
87 [ # # ]: 0 : if (fd < 0) {
88 : : ret = -EBADF;
89 : 0 : PMD_LOG_ERR(COM, "Fail to open device:%s, ret=%d, err:%s",
90 : : drv_name, ret, strerror(errno));
91 : 0 : goto l_end;
92 : : }
93 : :
94 : 0 : SXE2_CDEV_TO_CMD_FD(cdev) = fd;
95 : :
96 : 0 : PMD_LOG_INFO(COM, "Successfully opened device:%s, fd=%d",
97 : : drv_name, SXE2_CDEV_TO_CMD_FD(cdev));
98 : :
99 : 0 : l_end:
100 : 0 : return ret;
101 : : }
102 : :
103 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_close)
104 : : void
105 : 0 : sxe2_drv_dev_close(struct sxe2_common_device *cdev)
106 : : {
107 : 0 : int32_t fd = SXE2_CDEV_TO_CMD_FD(cdev);
108 : :
109 [ # # ]: 0 : if (fd >= 0)
110 : 0 : close(fd);
111 : 0 : PMD_LOG_INFO(COM, "closed device fd=%d", fd);
112 : 0 : SXE2_CDEV_TO_CMD_FD(cdev) = -1;
113 : 0 : }
114 : :
115 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_handshake)
116 : : int32_t
117 : 0 : sxe2_drv_dev_handshake(struct sxe2_common_device *cdev)
118 : : {
119 : : int32_t ret = 0;
120 : : int32_t cmd_fd = 0;
121 : : struct sxe2_ioctl_cmd_common_hdr cmd_params;
122 : :
123 [ # # ]: 0 : if (cdev->config.kernel_reset) {
124 : : ret = -EPERM;
125 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
126 : 0 : goto l_end;
127 : : }
128 : :
129 : 0 : cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
130 [ # # ]: 0 : if (cmd_fd < 0) {
131 : : ret = -EBADF;
132 : 0 : PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
133 : 0 : goto l_end;
134 : : }
135 : :
136 : 0 : PMD_LOG_DEBUG(COM, "Open fd=%d to handshake with kernel", cmd_fd);
137 : :
138 : : memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_cmd_common_hdr));
139 : 0 : cmd_params.dpdk_ver = SXE2_COM_VER;
140 : 0 : cmd_params.msg_len = sizeof(struct sxe2_ioctl_cmd_common_hdr);
141 : :
142 : 0 : pthread_mutex_lock(&cdev->config.lock);
143 : 0 : ret = ioctl(cmd_fd, SXE2_COM_CMD_HANDSHAKE, &cmd_params);
144 [ # # ]: 0 : if (ret < 0) {
145 : 0 : PMD_LOG_ERR(COM, "Failed to handshake, fd=%d, ret=%d, err:%s",
146 : : cmd_fd, ret, strerror(errno));
147 : : ret = -EIO;
148 : 0 : pthread_mutex_unlock(&cdev->config.lock);
149 : 0 : goto l_end;
150 : : }
151 : 0 : pthread_mutex_unlock(&cdev->config.lock);
152 : :
153 [ # # ]: 0 : if (cmd_params.cap & RTE_BIT32(SXE2_COM_CAP_IOMMU_MAP))
154 : 0 : cdev->config.support_iommu = true;
155 : : else
156 : 0 : cdev->config.support_iommu = false;
157 : :
158 : 0 : l_end:
159 : 0 : return ret;
160 : : }
161 : :
162 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_mmap)
163 : : void
164 : 0 : *sxe2_drv_dev_mmap(struct sxe2_common_device *cdev, uint8_t bar_idx, uint64_t len, uint64_t offset)
165 : : {
166 : : int32_t cmd_fd = 0;
167 : : void *virt = NULL;
168 : :
169 [ # # ]: 0 : if (cdev->config.kernel_reset) {
170 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
171 : 0 : goto l_err;
172 : : }
173 : :
174 : 0 : cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
175 [ # # ]: 0 : if (cmd_fd < 0) {
176 : 0 : PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
177 : 0 : goto l_err;
178 : : }
179 : :
180 : 0 : PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", src=0x%"PRIx64", offset=0x%"PRIx64"",
181 : : bar_idx, cmd_fd, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
182 : :
183 : 0 : virt = mmap(NULL, len, PROT_READ | PROT_WRITE,
184 : : MAP_SHARED, cmd_fd, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
185 [ # # ]: 0 : if (virt == MAP_FAILED) {
186 : 0 : PMD_LOG_ERR(COM, "Failed mmap, cmd_fd=%d, len=%"PRIu64", offset=0x%"PRIx64", err:%s",
187 : : cmd_fd, len, offset, strerror(errno));
188 : 0 : goto l_err;
189 : : }
190 : :
191 : : return virt;
192 : : l_err:
193 : : return NULL;
194 : : }
195 : :
196 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
197 : : int32_t
198 : 0 : sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
199 : : {
200 : : int32_t ret = 0;
201 : :
202 [ # # ]: 0 : if (cdev->config.kernel_reset) {
203 : : ret = -EPERM;
204 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
205 : 0 : goto l_end;
206 : : }
207 : :
208 : 0 : PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
209 : : virt, len);
210 : :
211 : 0 : ret = munmap(virt, len);
212 [ # # ]: 0 : if (ret < 0) {
213 : 0 : PMD_LOG_ERR(COM, "Failed to munmap, virt=%p, len=%"PRIu64", err:%s",
214 : : virt, len, strerror(errno));
215 : 0 : ret = -errno;
216 : 0 : goto l_end;
217 : : }
218 : :
219 : 0 : l_end:
220 : 0 : return ret;
221 : : }
222 : :
223 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_map)
224 : : int32_t
225 : 0 : sxe2_drv_dev_dma_map(struct sxe2_common_device *cdev, uint64_t vaddr,
226 : : uint64_t iova, uint64_t size)
227 : : {
228 : : struct sxe2_ioctl_iommu_dma_map cmd_params;
229 : : enum rte_iova_mode iova_mode;
230 : : int32_t ret = 0;
231 : : int32_t cmd_fd = 0;
232 : :
233 [ # # ]: 0 : if (cdev->config.kernel_reset) {
234 : : ret = -EPERM;
235 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
236 : 0 : goto l_end;
237 : : }
238 : :
239 : 0 : iova_mode = rte_eal_iova_mode();
240 [ # # ]: 0 : if (iova_mode == RTE_IOVA_PA) {
241 [ # # ]: 0 : if (cdev->config.support_iommu) {
242 : 0 : PMD_LOG_ERR(COM, "iommu not support pa mode");
243 : : ret = -EIO;
244 : : }
245 : 0 : goto l_end;
246 [ # # ]: 0 : } else if (iova_mode == RTE_IOVA_VA) {
247 [ # # ]: 0 : if (!cdev->config.support_iommu) {
248 : 0 : PMD_LOG_ERR(COM, "no iommu not support va mode, please use pa mode.");
249 : : ret = -EIO;
250 : 0 : goto l_end;
251 : : }
252 : : }
253 : :
254 : 0 : cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
255 [ # # ]: 0 : if (cmd_fd < 0) {
256 : : ret = -EBADF;
257 : 0 : PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
258 : 0 : goto l_end;
259 : : }
260 : :
261 : : memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_iommu_dma_map));
262 : 0 : cmd_params.vaddr = vaddr;
263 : 0 : cmd_params.iova = iova;
264 : 0 : cmd_params.size = size;
265 : :
266 : 0 : pthread_mutex_lock(&cdev->config.lock);
267 : 0 : ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_MAP, &cmd_params);
268 [ # # ]: 0 : if (ret < 0) {
269 : 0 : PMD_LOG_ERR(COM, "Failed to dma map, fd=%d, ret=%d, err:%s",
270 : : cmd_fd, ret, strerror(errno));
271 : : ret = -EIO;
272 : 0 : pthread_mutex_unlock(&cdev->config.lock);
273 : 0 : goto l_end;
274 : : }
275 : 0 : pthread_mutex_unlock(&cdev->config.lock);
276 : :
277 : 0 : l_end:
278 : 0 : return ret;
279 : : }
280 : :
281 : : RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_unmap)
282 : : int32_t
283 : 0 : sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
284 : : {
285 : : int32_t ret = 0;
286 : : int32_t cmd_fd = 0;
287 : : struct sxe2_ioctl_iommu_dma_unmap cmd_params;
288 : :
289 [ # # ]: 0 : if (cdev->config.kernel_reset) {
290 : : ret = -EPERM;
291 : 0 : PMD_LOG_WARN(COM, "kernel reset, need restart app.");
292 : 0 : goto l_end;
293 : : }
294 : :
295 [ # # ]: 0 : if (!cdev->config.support_iommu)
296 : 0 : goto l_end;
297 : :
298 : 0 : cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
299 [ # # ]: 0 : if (cmd_fd < 0) {
300 : : ret = -EBADF;
301 : 0 : PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
302 : 0 : goto l_end;
303 : : }
304 : :
305 : 0 : PMD_LOG_DEBUG(COM, "fd %d dma unmap iova=0x%"PRIX64"",
306 : : cmd_fd, iova);
307 : :
308 : : memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_iommu_dma_unmap));
309 : 0 : cmd_params.iova = iova;
310 : :
311 : 0 : pthread_mutex_lock(&cdev->config.lock);
312 : 0 : ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
313 [ # # ]: 0 : if (ret < 0) {
314 : 0 : PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
315 : : cmd_fd, ret, strerror(errno));
316 : : ret = -EIO;
317 : 0 : pthread_mutex_unlock(&cdev->config.lock);
318 : 0 : goto l_end;
319 : : }
320 : 0 : pthread_mutex_unlock(&cdev->config.lock);
321 : :
322 : 0 : l_end:
323 : 0 : return ret;
324 : : }
|