Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <fcntl.h>
7 : : #include <inttypes.h>
8 : : #include <limits.h>
9 : : #include <stdio.h>
10 : : #include <string.h>
11 : : #include <unistd.h>
12 : :
13 : : #include <bus_pci_driver.h>
14 : : #include <rte_atomic.h>
15 : : #include <rte_common.h>
16 : : #include <rte_dev.h>
17 : : #include <rte_eal_paging.h>
18 : : #include <rte_errno.h>
19 : : #include <rte_lcore.h>
20 : : #include <rte_log.h>
21 : : #include <rte_malloc.h>
22 : : #include <rte_memzone.h>
23 : : #include <rte_pci.h>
24 : : #include <rte_rawdev.h>
25 : : #include <rte_rawdev_pmd.h>
26 : : #include <rte_spinlock.h>
27 : : #include <rte_branch_prediction.h>
28 : :
29 : : #include "gdtc_rawdev.h"
30 : :
31 : : /*
32 : : * User define:
33 : : * ep_id-bit[15:12] vfunc_num-bit[11:4] func_num-bit[3:1] vfunc_active-bit0
34 : : * host ep_id:5~8 zf ep_id:9
35 : : */
36 : : #define ZXDH_GDMA_ZF_USER 0x9000 /* ep4 pf0 */
37 : : #define ZXDH_GDMA_PF_NUM_SHIFT 1
38 : : #define ZXDH_GDMA_VF_NUM_SHIFT 4
39 : : #define ZXDH_GDMA_EP_ID_SHIFT 12
40 : : #define ZXDH_GDMA_VF_EN 1
41 : : #define ZXDH_GDMA_EPID_OFFSET 5
42 : :
43 : : /* Register offset */
44 : : #define ZXDH_GDMA_BASE_OFFSET 0x100000
45 : : #define ZXDH_GDMA_EXT_ADDR_OFFSET 0x218
46 : : #define ZXDH_GDMA_SAR_LOW_OFFSET 0x200
47 : : #define ZXDH_GDMA_DAR_LOW_OFFSET 0x204
48 : : #define ZXDH_GDMA_SAR_HIGH_OFFSET 0x234
49 : : #define ZXDH_GDMA_DAR_HIGH_OFFSET 0x238
50 : : #define ZXDH_GDMA_XFERSIZE_OFFSET 0x208
51 : : #define ZXDH_GDMA_CONTROL_OFFSET 0x230
52 : : #define ZXDH_GDMA_TC_STATUS_OFFSET 0x0
53 : : #define ZXDH_GDMA_STATUS_CLEAN_OFFSET 0x80
54 : : #define ZXDH_GDMA_LLI_L_OFFSET 0x21c
55 : : #define ZXDH_GDMA_LLI_H_OFFSET 0x220
56 : : #define ZXDH_GDMA_CHAN_CONTINUE_OFFSET 0x224
57 : : #define ZXDH_GDMA_TC_CNT_OFFSET 0x23c
58 : : #define ZXDH_GDMA_LLI_USER_OFFSET 0x228
59 : :
60 : : /* Control register */
61 : : #define ZXDH_GDMA_CHAN_ENABLE 0x1
62 : : #define ZXDH_GDMA_CHAN_DISABLE 0
63 : : #define ZXDH_GDMA_SOFT_CHAN 0x2
64 : : #define ZXDH_GDMA_TC_INTR_ENABLE 0x10
65 : : #define ZXDH_GDMA_ALL_INTR_ENABLE 0x30
66 : : #define ZXDH_GDMA_SBS_SHIFT 6 /* src burst size */
67 : : #define ZXDH_GDMA_SBL_SHIFT 9 /* src burst length */
68 : : #define ZXDH_GDMA_DBS_SHIFT 13 /* dest burst size */
69 : : #define ZXDH_GDMA_BURST_SIZE_MIN 0x1 /* 1 byte */
70 : : #define ZXDH_GDMA_BURST_SIZE_MEDIUM 0x4 /* 4 word */
71 : : #define ZXDH_GDMA_BURST_SIZE_MAX 0x6 /* 16 word */
72 : : #define ZXDH_GDMA_DEFAULT_BURST_LEN 0xf /* 16 beats */
73 : : #define ZXDH_GDMA_TC_CNT_ENABLE (1 << 27)
74 : : #define ZXDH_GDMA_CHAN_FORCE_CLOSE (1 << 31)
75 : :
76 : : /* TC count & Error interrupt status register */
77 : : #define ZXDH_GDMA_SRC_LLI_ERR (1 << 16)
78 : : #define ZXDH_GDMA_SRC_DATA_ERR (1 << 17)
79 : : #define ZXDH_GDMA_DST_ADDR_ERR (1 << 18)
80 : : #define ZXDH_GDMA_ERR_STATUS (1 << 19)
81 : : #define ZXDH_GDMA_ERR_INTR_ENABLE (1 << 20)
82 : : #define ZXDH_GDMA_TC_CNT_CLEAN (1)
83 : :
84 : : #define ZXDH_GDMA_CHAN_SHIFT 0x80
85 : : #define ZXDH_GDMA_LINK_END_NODE (1 << 30)
86 : : #define ZXDH_GDMA_CHAN_CONTINUE (1)
87 : :
88 : : #define LOW32_MASK 0xffffffff
89 : : #define LOW16_MASK 0xffff
90 : :
91 : : #define ZXDH_GDMA_TC_CNT_MAX 0x10000
92 : :
93 : : #define IDX_TO_ADDR(addr, idx, t) \
94 : : ((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc)))
95 : :
96 : : static int zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id);
97 : : static int zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id);
98 : :
99 : : char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
100 : : char dev_name[] = "zxdh_gdma";
101 : :
102 : : static inline struct zxdh_gdma_rawdev *
103 : : zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
104 : : {
105 : 0 : return rawdev->dev_private;
106 : : }
107 : :
108 : : static inline struct zxdh_gdma_queue *
109 : 0 : zxdh_gdma_get_queue(struct rte_rawdev *dev, uint16_t queue_id)
110 : : {
111 : : struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
112 : :
113 [ # # ]: 0 : if (queue_id >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
114 : 0 : ZXDH_PMD_LOG(ERR, "queue id %d is invalid", queue_id);
115 : 0 : return NULL;
116 : : }
117 : :
118 : 0 : return &(gdmadev->vqs[queue_id]);
119 : : }
120 : :
121 : : static uint32_t
122 : : zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
123 : : {
124 : : struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
125 : : uint32_t addr = 0;
126 : : uint32_t val = 0;
127 : :
128 : 0 : addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
129 : 0 : val = *(uint32_t *)(gdmadev->base_addr + addr);
130 : :
131 : : return val;
132 : : }
133 : :
134 : : static void
135 : : zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
136 : : {
137 : : struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
138 : : uint32_t addr = 0;
139 : :
140 : 0 : addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
141 : 0 : *(uint32_t *)(gdmadev->base_addr + addr) = val;
142 : 0 : }
143 : :
144 : : static int
145 : 0 : zxdh_gdma_rawdev_info_get(struct rte_rawdev *dev,
146 : : __rte_unused rte_rawdev_obj_t dev_info,
147 : : __rte_unused size_t dev_info_size)
148 : : {
149 [ # # ]: 0 : if (dev == NULL)
150 : 0 : return -EINVAL;
151 : :
152 : : return 0;
153 : : }
154 : :
155 : : static int
156 : 0 : zxdh_gdma_rawdev_configure(const struct rte_rawdev *dev,
157 : : rte_rawdev_obj_t config,
158 : : size_t config_size)
159 : : {
160 : : struct zxdh_gdma_config *gdma_config = NULL;
161 : :
162 : 0 : if ((dev == NULL) ||
163 [ # # # # ]: 0 : (config == NULL) ||
164 : : (config_size != sizeof(struct zxdh_gdma_config)))
165 : : return -EINVAL;
166 : :
167 : : gdma_config = (struct zxdh_gdma_config *)config;
168 [ # # ]: 0 : if (gdma_config->max_vqs > ZXDH_GDMA_TOTAL_CHAN_NUM) {
169 : 0 : ZXDH_PMD_LOG(ERR, "gdma supports up to %d queues", ZXDH_GDMA_TOTAL_CHAN_NUM);
170 : 0 : return -EINVAL;
171 : : }
172 : :
173 : : return 0;
174 : : }
175 : :
176 : : static int
177 : 0 : zxdh_gdma_rawdev_start(struct rte_rawdev *dev)
178 : : {
179 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
180 : :
181 [ # # ]: 0 : if (dev == NULL)
182 : : return -EINVAL;
183 : :
184 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
185 : 0 : gdmadev->device_state = ZXDH_GDMA_DEV_RUNNING;
186 : :
187 : 0 : return 0;
188 : : }
189 : :
190 : : static void
191 : 0 : zxdh_gdma_rawdev_stop(struct rte_rawdev *dev)
192 : : {
193 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
194 : :
195 [ # # ]: 0 : if (dev == NULL)
196 : : return;
197 : :
198 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
199 : 0 : gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
200 : : }
201 : :
202 : : static int
203 : 0 : zxdh_gdma_rawdev_reset(struct rte_rawdev *dev)
204 : : {
205 [ # # ]: 0 : if (dev == NULL)
206 : 0 : return -EINVAL;
207 : :
208 : : return 0;
209 : : }
210 : :
211 : : static int
212 : 0 : zxdh_gdma_rawdev_close(struct rte_rawdev *dev)
213 : : {
214 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
215 : : struct zxdh_gdma_queue *queue = NULL;
216 : : uint16_t queue_id = 0;
217 : :
218 [ # # ]: 0 : if (dev == NULL)
219 : : return -EINVAL;
220 : :
221 [ # # ]: 0 : for (queue_id = 0; queue_id < ZXDH_GDMA_TOTAL_CHAN_NUM; queue_id++) {
222 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
223 [ # # # # ]: 0 : if ((queue == NULL) || (queue->enable == 0))
224 : 0 : continue;
225 : :
226 : 0 : zxdh_gdma_queue_free(dev, queue_id);
227 : : }
228 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
229 : 0 : gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
230 : :
231 : 0 : return 0;
232 : : }
233 : :
234 : : static int
235 : 0 : zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
236 : : uint16_t queue_id,
237 : : rte_rawdev_obj_t queue_conf,
238 : : size_t conf_size)
239 : : {
240 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
241 : : struct zxdh_gdma_queue *queue = NULL;
242 : : struct zxdh_gdma_queue_config *qconfig = NULL;
243 : : struct zxdh_gdma_rbp *rbp = NULL;
244 : : uint16_t i = 0;
245 : : uint8_t is_txq = 0;
246 : : uint32_t src_user = 0;
247 : : uint32_t dst_user = 0;
248 : :
249 [ # # ]: 0 : if (dev == NULL)
250 : : return -EINVAL;
251 : :
252 [ # # ]: 0 : if ((queue_conf == NULL) || (conf_size != sizeof(struct zxdh_gdma_queue_config)))
253 : : return -EINVAL;
254 : :
255 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
256 : : qconfig = (struct zxdh_gdma_queue_config *)queue_conf;
257 : :
258 [ # # ]: 0 : for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
259 [ # # ]: 0 : if (gdmadev->vqs[i].enable == 0)
260 : : break;
261 : : }
262 [ # # ]: 0 : if (i >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
263 : 0 : ZXDH_PMD_LOG(ERR, "Failed to setup queue, no avail queues");
264 : 0 : return -1;
265 : : }
266 : : queue_id = i;
267 [ # # ]: 0 : if (zxdh_gdma_queue_init(dev, queue_id) != 0) {
268 : 0 : ZXDH_PMD_LOG(ERR, "Failed to init queue");
269 : 0 : return -1;
270 : : }
271 : : queue = &(gdmadev->vqs[queue_id]);
272 : :
273 : 0 : rbp = qconfig->rbp;
274 [ # # ]: 0 : if ((rbp->srbp != 0) && (rbp->drbp == 0)) {
275 : : is_txq = 0;
276 : : dst_user = ZXDH_GDMA_ZF_USER;
277 : 0 : src_user = ((rbp->spfid << ZXDH_GDMA_PF_NUM_SHIFT) |
278 : 0 : ((rbp->sportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
279 : :
280 [ # # ]: 0 : if (rbp->svfid != 0)
281 : 0 : src_user |= (ZXDH_GDMA_VF_EN |
282 : 0 : ((rbp->svfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
283 : :
284 : 0 : ZXDH_PMD_LOG(DEBUG, "rxq->qidx:%d setup src_user(ep:%d pf:%d vf:%d) success",
285 : : queue_id, (uint8_t)rbp->sportid, (uint8_t)rbp->spfid,
286 : : (uint8_t)rbp->svfid);
287 [ # # ]: 0 : } else if ((rbp->srbp == 0) && (rbp->drbp != 0)) {
288 : : is_txq = 1;
289 : : src_user = ZXDH_GDMA_ZF_USER;
290 : 0 : dst_user = ((rbp->dpfid << ZXDH_GDMA_PF_NUM_SHIFT) |
291 : 0 : ((rbp->dportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
292 : :
293 [ # # ]: 0 : if (rbp->dvfid != 0)
294 : 0 : dst_user |= (ZXDH_GDMA_VF_EN |
295 : 0 : ((rbp->dvfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
296 : :
297 : 0 : ZXDH_PMD_LOG(DEBUG, "txq->qidx:%d setup dst_user(ep:%d pf:%d vf:%d) success",
298 : : queue_id, (uint8_t)rbp->dportid, (uint8_t)rbp->dpfid,
299 : : (uint8_t)rbp->dvfid);
300 : : } else {
301 : 0 : ZXDH_PMD_LOG(ERR, "Failed to setup queue, srbp/drbp is invalid");
302 : 0 : return -EINVAL;
303 : : }
304 : 0 : queue->is_txq = is_txq;
305 : :
306 : : /* setup queue user info */
307 : 0 : queue->user = (src_user & LOW16_MASK) | (dst_user << 16);
308 : :
309 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_EXT_ADDR_OFFSET, queue->user);
310 : 0 : gdmadev->used_num++;
311 : :
312 : 0 : return queue_id;
313 : : }
314 : :
315 : : static int
316 : 0 : zxdh_gdma_rawdev_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
317 : : {
318 : : struct zxdh_gdma_queue *queue = NULL;
319 : :
320 [ # # ]: 0 : if (dev == NULL)
321 : : return -EINVAL;
322 : :
323 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
324 [ # # # # ]: 0 : if ((queue == NULL) || (queue->enable == 0))
325 : : return -EINVAL;
326 : :
327 : 0 : zxdh_gdma_queue_free(dev, queue_id);
328 : :
329 : 0 : return 0;
330 : : }
331 : :
332 : : static int
333 : 0 : zxdh_gdma_rawdev_get_attr(struct rte_rawdev *dev,
334 : : __rte_unused const char *attr_name,
335 : : uint64_t *attr_value)
336 : : {
337 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
338 : : struct zxdh_gdma_attr *gdma_attr = NULL;
339 : :
340 [ # # ]: 0 : if ((dev == NULL) || (attr_value == NULL))
341 : : return -EINVAL;
342 : :
343 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
344 : : gdma_attr = (struct zxdh_gdma_attr *)attr_value;
345 : 0 : gdma_attr->num_hw_queues = gdmadev->used_num;
346 : :
347 : 0 : return 0;
348 : : }
349 : :
350 : : static inline void
351 : : zxdh_gdma_control_cal(uint32_t *val, uint8_t tc_enable)
352 : : {
353 : : *val = (ZXDH_GDMA_CHAN_ENABLE |
354 : : ZXDH_GDMA_SOFT_CHAN |
355 : : (ZXDH_GDMA_DEFAULT_BURST_LEN << ZXDH_GDMA_SBL_SHIFT) |
356 : : (ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_SBS_SHIFT) |
357 : : (ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_DBS_SHIFT));
358 : :
359 : : if (tc_enable != 0)
360 : : *val |= ZXDH_GDMA_TC_CNT_ENABLE;
361 : : }
362 : :
363 : : static inline uint32_t
364 : 0 : zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
365 : : {
366 : : uint32_t src_user = 0;
367 : : uint32_t dst_user = 0;
368 : :
369 [ # # ]: 0 : if ((job->flags & ZXDH_GDMA_JOB_DIR_MASK) == 0) {
370 : 0 : ZXDH_PMD_LOG(DEBUG, "job flags:0x%x default user:0x%x",
371 : : job->flags, queue->user);
372 : 0 : return queue->user;
373 [ # # ]: 0 : } else if ((job->flags & ZXDH_GDMA_JOB_DIR_TX) != 0) {
374 : : src_user = ZXDH_GDMA_ZF_USER;
375 : 0 : dst_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
376 : 0 : ((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
377 : :
378 [ # # ]: 0 : if (job->vf_id != 0)
379 : 0 : dst_user |= (ZXDH_GDMA_VF_EN |
380 : 0 : ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
381 : : } else {
382 : : dst_user = ZXDH_GDMA_ZF_USER;
383 : 0 : src_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
384 : 0 : ((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
385 : :
386 [ # # ]: 0 : if (job->vf_id != 0)
387 : 0 : src_user |= (ZXDH_GDMA_VF_EN |
388 : 0 : ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
389 : : }
390 : 0 : ZXDH_PMD_LOG(DEBUG, "job flags:0x%x ep_id:%u, pf_id:%u, vf_id:%u, user:0x%x",
391 : : job->flags, job->ep_id, job->pf_id, job->vf_id,
392 : : (src_user & LOW16_MASK) | (dst_user << 16));
393 : :
394 : 0 : return (src_user & LOW16_MASK) | (dst_user << 16);
395 : : }
396 : :
397 : : static inline void
398 : 0 : zxdh_gdma_fill_bd(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
399 : : {
400 : : struct zxdh_gdma_buff_desc *bd = NULL;
401 : : uint32_t val = 0;
402 : : uint64_t next_bd_addr = 0;
403 : : uint16_t avail_idx = 0;
404 : :
405 : 0 : avail_idx = queue->ring.avail_idx;
406 [ # # ]: 0 : bd = &(queue->ring.desc[avail_idx]);
407 : : memset(bd, 0, sizeof(struct zxdh_gdma_buff_desc));
408 : :
409 : : /* data bd */
410 [ # # ]: 0 : if (job != NULL) {
411 : : zxdh_gdma_control_cal(&val, 1);
412 : 0 : next_bd_addr = IDX_TO_ADDR(queue->ring.ring_mem,
413 : : (avail_idx + 1) % ZXDH_GDMA_RING_SIZE, uint64_t);
414 : 0 : bd->SrcAddr_L = job->src & LOW32_MASK;
415 : 0 : bd->DstAddr_L = job->dest & LOW32_MASK;
416 : 0 : bd->SrcAddr_H = (job->src >> 32) & LOW32_MASK;
417 : 0 : bd->DstAddr_H = (job->dest >> 32) & LOW32_MASK;
418 : 0 : bd->Xpara = job->len;
419 : 0 : bd->ExtAddr = zxdh_gdma_user_get(queue, job);
420 : 0 : bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
421 : 0 : bd->LLI_Addr_H = next_bd_addr >> 38;
422 : 0 : bd->LLI_User = ZXDH_GDMA_ZF_USER;
423 : 0 : bd->Control = val;
424 : : } else {
425 : : zxdh_gdma_control_cal(&val, 0);
426 : 0 : next_bd_addr = IDX_TO_ADDR(queue->ring.ring_mem, avail_idx, uint64_t);
427 : 0 : bd->ExtAddr = queue->user;
428 : 0 : bd->LLI_User = ZXDH_GDMA_ZF_USER;
429 : 0 : bd->Control = val;
430 : 0 : bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
431 : 0 : bd->LLI_Addr_H = (next_bd_addr >> 38) | ZXDH_GDMA_LINK_END_NODE;
432 [ # # ]: 0 : if (queue->flag != 0) {
433 : 0 : bd = IDX_TO_ADDR(queue->ring.desc,
434 : : queue->ring.last_avail_idx,
435 : : struct zxdh_gdma_buff_desc*);
436 : 0 : next_bd_addr = IDX_TO_ADDR(queue->ring.ring_mem,
437 : : (queue->ring.last_avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
438 : : uint64_t);
439 : 0 : bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
440 : 0 : bd->LLI_Addr_H = next_bd_addr >> 38;
441 : : rte_wmb();
442 : 0 : bd->LLI_Addr_H &= ~ZXDH_GDMA_LINK_END_NODE;
443 : : }
444 : : /* Record the index of empty bd for dynamic chaining */
445 : 0 : queue->ring.last_avail_idx = avail_idx;
446 : : }
447 : :
448 [ # # ]: 0 : if (++avail_idx >= ZXDH_GDMA_RING_SIZE)
449 : 0 : avail_idx -= ZXDH_GDMA_RING_SIZE;
450 : :
451 : 0 : queue->ring.avail_idx = avail_idx;
452 : 0 : }
453 : :
454 : : static int
455 : 0 : zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
456 : : __rte_unused struct rte_rawdev_buf **buffers,
457 : : uint32_t count,
458 : : rte_rawdev_obj_t context)
459 : : {
460 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
461 : : struct zxdh_gdma_queue *queue = NULL;
462 : : struct zxdh_gdma_enqdeq *e_context = NULL;
463 : : struct zxdh_gdma_job *job = NULL;
464 : : uint16_t queue_id = 0;
465 : : uint32_t val = 0;
466 : : uint16_t i = 0;
467 : : uint16_t free_cnt = 0;
468 : :
469 [ # # ]: 0 : if (dev == NULL)
470 : : return -EINVAL;
471 : :
472 [ # # ]: 0 : if (unlikely((count < 1) || (context == NULL)))
473 : : return -EINVAL;
474 : :
475 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
476 [ # # ]: 0 : if (gdmadev->device_state == ZXDH_GDMA_DEV_STOPPED) {
477 : 0 : ZXDH_PMD_LOG(ERR, "gdma dev is stop");
478 : 0 : return 0;
479 : : }
480 : :
481 : : e_context = (struct zxdh_gdma_enqdeq *)context;
482 : 0 : queue_id = e_context->vq_id;
483 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
484 [ # # # # ]: 0 : if ((queue == NULL) || (queue->enable == 0))
485 : : return -EINVAL;
486 : :
487 : 0 : free_cnt = queue->sw_ring.free_cnt;
488 [ # # ]: 0 : if (free_cnt == 0) {
489 : 0 : ZXDH_PMD_LOG(ERR, "queue %u is full, enq_idx:%u deq_idx:%u used_idx:%u",
490 : : queue_id, queue->sw_ring.enq_idx,
491 : : queue->sw_ring.deq_idx, queue->sw_ring.used_idx);
492 : 0 : return 0;
493 [ # # ]: 0 : } else if (free_cnt < count) {
494 : 0 : ZXDH_PMD_LOG(DEBUG, "job num %u > free_cnt, change to %u", count, free_cnt);
495 : : count = free_cnt;
496 : : }
497 : :
498 : 0 : rte_spinlock_lock(&queue->enqueue_lock);
499 : :
500 : : /* Build bd list, the last bd is empty bd */
501 [ # # ]: 0 : for (i = 0; i < count; i++) {
502 : 0 : job = e_context->job[i];
503 : 0 : zxdh_gdma_fill_bd(queue, job);
504 : : }
505 : 0 : zxdh_gdma_fill_bd(queue, NULL);
506 : :
507 [ # # ]: 0 : if (unlikely(queue->flag == 0)) {
508 : 0 : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET,
509 : 0 : (queue->ring.ring_mem >> 6) & LOW32_MASK);
510 : 0 : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_H_OFFSET,
511 : 0 : queue->ring.ring_mem >> 38);
512 : : /* Start hardware handling */
513 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
514 : : zxdh_gdma_control_cal(&val, 0);
515 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
516 : 0 : queue->flag = 1;
517 : : } else {
518 : : val = ZXDH_GDMA_CHAN_CONTINUE;
519 : 0 : zxdh_gdma_write_reg(dev, queue->vq_id, ZXDH_GDMA_CHAN_CONTINUE_OFFSET, val);
520 : : }
521 : :
522 : : /* job enqueue */
523 [ # # ]: 0 : for (i = 0; i < count; i++) {
524 : 0 : queue->sw_ring.job[queue->sw_ring.enq_idx] = e_context->job[i];
525 [ # # ]: 0 : if (++queue->sw_ring.enq_idx >= queue->queue_size)
526 : 0 : queue->sw_ring.enq_idx -= queue->queue_size;
527 : :
528 : 0 : free_cnt--;
529 : : }
530 : 0 : queue->sw_ring.free_cnt = free_cnt;
531 : 0 : queue->sw_ring.pend_cnt += count;
532 : : rte_spinlock_unlock(&queue->enqueue_lock);
533 : :
534 : 0 : return count;
535 : : }
536 : :
537 : : static inline void
538 : 0 : zxdh_gdma_used_idx_update(struct zxdh_gdma_queue *queue, uint16_t cnt, uint8_t data_bd_err)
539 : : {
540 : : uint16_t idx = 0;
541 : :
542 [ # # ]: 0 : if (queue->sw_ring.used_idx + cnt < queue->queue_size)
543 : 0 : queue->sw_ring.used_idx += cnt;
544 : : else
545 : 0 : queue->sw_ring.used_idx = queue->sw_ring.used_idx + cnt - queue->queue_size;
546 : :
547 [ # # ]: 0 : if (data_bd_err == 1) {
548 : : /* Update job status, the last job status is error */
549 [ # # ]: 0 : if (queue->sw_ring.used_idx == 0)
550 : 0 : idx = queue->queue_size - 1;
551 : : else
552 : 0 : idx = queue->sw_ring.used_idx - 1;
553 : :
554 : 0 : queue->sw_ring.job[idx]->status = 1;
555 : : }
556 : 0 : }
557 : :
558 : : static int
559 : 0 : zxdh_gdma_rawdev_dequeue_bufs(struct rte_rawdev *dev,
560 : : __rte_unused struct rte_rawdev_buf **buffers,
561 : : uint32_t count,
562 : : rte_rawdev_obj_t context)
563 : : {
564 : : struct zxdh_gdma_queue *queue = NULL;
565 : : struct zxdh_gdma_enqdeq *e_context = NULL;
566 : : uint16_t queue_id = 0;
567 : : uint32_t val = 0;
568 : : uint16_t tc_cnt = 0;
569 : : uint16_t diff_cnt = 0;
570 : : uint16_t i = 0;
571 : : uint16_t bd_idx = 0;
572 : : uint64_t next_bd_addr = 0;
573 : : uint8_t data_bd_err = 0;
574 : :
575 [ # # ]: 0 : if ((dev == NULL) || (context == NULL))
576 : : return -EINVAL;
577 : :
578 : : e_context = (struct zxdh_gdma_enqdeq *)context;
579 : 0 : queue_id = e_context->vq_id;
580 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
581 [ # # # # ]: 0 : if ((queue == NULL) || (queue->enable == 0))
582 : : return -EINVAL;
583 : :
584 [ # # ]: 0 : if (queue->sw_ring.pend_cnt == 0)
585 : 0 : goto deq_job;
586 : :
587 : : /* Get data transmit count */
588 : : val = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET);
589 : 0 : tc_cnt = val & LOW16_MASK;
590 [ # # ]: 0 : if (tc_cnt >= queue->tc_cnt)
591 : 0 : diff_cnt = tc_cnt - queue->tc_cnt;
592 : : else
593 : 0 : diff_cnt = tc_cnt + ZXDH_GDMA_TC_CNT_MAX - queue->tc_cnt;
594 : :
595 : 0 : queue->tc_cnt = tc_cnt;
596 : :
597 : : /* Data transmit error, channel stopped */
598 [ # # ]: 0 : if ((val & ZXDH_GDMA_ERR_STATUS) != 0) {
599 : 0 : next_bd_addr = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET);
600 : 0 : next_bd_addr |= ((uint64_t)zxdh_gdma_read_reg(dev, queue_id,
601 : 0 : ZXDH_GDMA_LLI_H_OFFSET) << 32);
602 : 0 : next_bd_addr = next_bd_addr << 6;
603 : 0 : bd_idx = (next_bd_addr - queue->ring.ring_mem) / sizeof(struct zxdh_gdma_buff_desc);
604 [ # # ]: 0 : if ((val & ZXDH_GDMA_SRC_DATA_ERR) || (val & ZXDH_GDMA_DST_ADDR_ERR)) {
605 : 0 : diff_cnt++;
606 : : data_bd_err = 1;
607 : : }
608 : 0 : ZXDH_PMD_LOG(INFO, "queue%d is err(0x%x) next_bd_idx:%u ll_addr:0x%"PRIx64" def user:0x%x",
609 : : queue_id, val, bd_idx, next_bd_addr, queue->user);
610 : :
611 : 0 : ZXDH_PMD_LOG(INFO, "Clean up error status");
612 : : val = ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_ERR_INTR_ENABLE;
613 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET, val);
614 : :
615 : 0 : ZXDH_PMD_LOG(INFO, "Restart channel");
616 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
617 : : zxdh_gdma_control_cal(&val, 0);
618 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
619 : : }
620 : :
621 [ # # ]: 0 : if (diff_cnt != 0) {
622 : 0 : zxdh_gdma_used_idx_update(queue, diff_cnt, data_bd_err);
623 : 0 : queue->sw_ring.deq_cnt += diff_cnt;
624 : 0 : queue->sw_ring.pend_cnt -= diff_cnt;
625 : : }
626 : :
627 : 0 : deq_job:
628 [ # # ]: 0 : if (queue->sw_ring.deq_cnt == 0)
629 : : return 0;
630 : 0 : else if (queue->sw_ring.deq_cnt < count)
631 : : count = queue->sw_ring.deq_cnt;
632 : :
633 : 0 : queue->sw_ring.deq_cnt -= count;
634 : :
635 [ # # ]: 0 : for (i = 0; i < count; i++) {
636 : 0 : e_context->job[i] = queue->sw_ring.job[queue->sw_ring.deq_idx];
637 : 0 : queue->sw_ring.job[queue->sw_ring.deq_idx] = NULL;
638 [ # # ]: 0 : if (++queue->sw_ring.deq_idx >= queue->queue_size)
639 : 0 : queue->sw_ring.deq_idx -= queue->queue_size;
640 : : }
641 : 0 : queue->sw_ring.free_cnt += count;
642 : :
643 : 0 : return count;
644 : : }
645 : :
646 : : static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
647 : : .dev_info_get = zxdh_gdma_rawdev_info_get,
648 : : .dev_configure = zxdh_gdma_rawdev_configure,
649 : : .dev_start = zxdh_gdma_rawdev_start,
650 : : .dev_stop = zxdh_gdma_rawdev_stop,
651 : : .dev_close = zxdh_gdma_rawdev_close,
652 : : .dev_reset = zxdh_gdma_rawdev_reset,
653 : :
654 : : .queue_setup = zxdh_gdma_rawdev_queue_setup,
655 : : .queue_release = zxdh_gdma_rawdev_queue_release,
656 : :
657 : : .attr_get = zxdh_gdma_rawdev_get_attr,
658 : :
659 : : .enqueue_bufs = zxdh_gdma_rawdev_enqueue_bufs,
660 : : .dequeue_bufs = zxdh_gdma_rawdev_dequeue_bufs,
661 : : };
662 : :
663 : : static int
664 : 0 : zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
665 : : {
666 : : char name[RTE_MEMZONE_NAMESIZE];
667 : : struct zxdh_gdma_queue *queue = NULL;
668 : : const struct rte_memzone *mz = NULL;
669 : : uint32_t size = 0;
670 : : int ret = 0;
671 : :
672 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
673 [ # # ]: 0 : if (queue == NULL)
674 : : return -EINVAL;
675 : :
676 : 0 : queue->enable = 1;
677 : 0 : queue->vq_id = queue_id;
678 : 0 : queue->flag = 0;
679 : 0 : queue->tc_cnt = 0;
680 : :
681 : : /* Init sw_ring */
682 : 0 : queue->sw_ring.job = rte_calloc(NULL, queue->queue_size, sizeof(struct zxdh_gdma_job *), 0);
683 [ # # ]: 0 : if (queue->sw_ring.job == NULL) {
684 : 0 : ZXDH_PMD_LOG(ERR, "can not allocate sw_ring");
685 : : ret = -ENOMEM;
686 : 0 : goto free_queue;
687 : : }
688 : :
689 : : /* Cache up to size-1 job in the ring to prevent overwriting hardware prefetching */
690 : 0 : queue->sw_ring.free_cnt = queue->queue_size - 1;
691 : 0 : queue->sw_ring.deq_cnt = 0;
692 : 0 : queue->sw_ring.pend_cnt = 0;
693 : 0 : queue->sw_ring.enq_idx = 0;
694 : 0 : queue->sw_ring.deq_idx = 0;
695 : 0 : queue->sw_ring.used_idx = 0;
696 : :
697 : : /* Init ring */
698 : : snprintf(name, RTE_MEMZONE_NAMESIZE, "gdma_vq%d_ring", queue_id);
699 : : size = ZXDH_GDMA_RING_SIZE * sizeof(struct zxdh_gdma_buff_desc);
700 : 0 : mz = rte_memzone_reserve_aligned(name, size, rte_socket_id(),
701 : : RTE_MEMZONE_IOVA_CONTIG, size);
702 [ # # ]: 0 : if (mz == NULL) {
703 [ # # ]: 0 : if (rte_errno == EEXIST)
704 : 0 : mz = rte_memzone_lookup(name);
705 [ # # ]: 0 : if (mz == NULL) {
706 : 0 : ZXDH_PMD_LOG(ERR, "can not allocate ring %s", name);
707 : : ret = -ENOMEM;
708 : 0 : goto free_queue;
709 : : }
710 : : }
711 : 0 : memset(mz->addr, 0, size);
712 : 0 : queue->ring.ring_mz = mz;
713 : 0 : queue->ring.desc = (struct zxdh_gdma_buff_desc *)(mz->addr);
714 : 0 : queue->ring.ring_mem = mz->iova;
715 : 0 : queue->ring.avail_idx = 0;
716 : 0 : ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
717 : : queue_id, mz->iova, mz->addr);
718 : :
719 : : /* Configure the hardware channel to the initial state */
720 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
721 : : ZXDH_GDMA_CHAN_FORCE_CLOSE);
722 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET,
723 : : ZXDH_GDMA_ERR_INTR_ENABLE | ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_TC_CNT_CLEAN);
724 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_USER_OFFSET,
725 : : ZXDH_GDMA_ZF_USER);
726 : :
727 : 0 : return 0;
728 : :
729 : 0 : free_queue:
730 : 0 : zxdh_gdma_queue_free(dev, queue_id);
731 : 0 : return ret;
732 : : }
733 : :
734 : : static int
735 : 0 : zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id)
736 : : {
737 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
738 : : struct zxdh_gdma_queue *queue = NULL;
739 : : uint32_t val = 0;
740 : :
741 : 0 : queue = zxdh_gdma_get_queue(dev, queue_id);
742 [ # # ]: 0 : if (queue == NULL)
743 : : return -EINVAL;
744 : :
745 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
746 : 0 : gdmadev->used_num--;
747 : :
748 : : /* disable gdma channel */
749 : : val = ZXDH_GDMA_CHAN_FORCE_CLOSE;
750 : : zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
751 : :
752 : 0 : queue->enable = 0;
753 : 0 : queue->is_txq = 0;
754 : 0 : queue->flag = 0;
755 : 0 : queue->user = 0;
756 : 0 : queue->tc_cnt = 0;
757 : 0 : queue->ring.avail_idx = 0;
758 : 0 : queue->sw_ring.free_cnt = 0;
759 : 0 : queue->sw_ring.deq_cnt = 0;
760 : 0 : queue->sw_ring.pend_cnt = 0;
761 : 0 : queue->sw_ring.enq_idx = 0;
762 : 0 : queue->sw_ring.deq_idx = 0;
763 : 0 : queue->sw_ring.used_idx = 0;
764 : 0 : rte_free(queue->sw_ring.job);
765 : 0 : rte_memzone_free(queue->ring.ring_mz);
766 : :
767 : 0 : return 0;
768 : : }
769 : :
770 : : static int
771 : 0 : zxdh_gdma_map_resource(struct rte_pci_device *dev)
772 : : {
773 : : int fd = -1;
774 : : char devname[PATH_MAX];
775 : : void *mapaddr = NULL;
776 : : struct rte_pci_addr *loc;
777 : :
778 : : loc = &dev->addr;
779 : 0 : snprintf(devname, sizeof(devname), "%s/" PCI_PRI_FMT "/resource0",
780 : : rte_pci_get_sysfs_path(),
781 : 0 : loc->domain, loc->bus, loc->devid,
782 : 0 : loc->function);
783 : :
784 : : fd = open(devname, O_RDWR);
785 [ # # ]: 0 : if (fd < 0) {
786 : 0 : ZXDH_PMD_LOG(ERR, "Cannot open %s: %s", devname, strerror(errno));
787 : 0 : return -1;
788 : : }
789 : :
790 : : /* Map the PCI memory resource of device */
791 : 0 : mapaddr = rte_mem_map(NULL, (size_t)dev->mem_resource[0].len,
792 : : RTE_PROT_READ | RTE_PROT_WRITE,
793 : : RTE_MAP_SHARED, fd, 0);
794 [ # # ]: 0 : if (mapaddr == NULL) {
795 : 0 : ZXDH_PMD_LOG(ERR, "cannot map resource(%d, 0x%zx): %s (%p)",
796 : : fd, (size_t)dev->mem_resource[0].len,
797 : : rte_strerror(rte_errno), mapaddr);
798 : 0 : close(fd);
799 : 0 : return -1;
800 : : }
801 : :
802 : 0 : close(fd);
803 : 0 : dev->mem_resource[0].addr = mapaddr;
804 : :
805 : 0 : return 0;
806 : : }
807 : :
808 : : static void
809 : 0 : zxdh_gdma_unmap_resource(void *requested_addr, size_t size)
810 : : {
811 [ # # ]: 0 : if (requested_addr == NULL)
812 : : return;
813 : :
814 : : /* Unmap the PCI memory resource of device */
815 [ # # ]: 0 : if (rte_mem_unmap(requested_addr, size))
816 : 0 : ZXDH_PMD_LOG(ERR, "cannot mem unmap(%p, %#zx): %s",
817 : : requested_addr, size, rte_strerror(rte_errno));
818 : : else
819 : 0 : ZXDH_PMD_LOG(DEBUG, "PCI memory unmapped at %p", requested_addr);
820 : : }
821 : :
822 : : static int
823 : 0 : zxdh_gdma_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
824 : : struct rte_pci_device *pci_dev)
825 : : {
826 : : struct rte_rawdev *dev = NULL;
827 : : struct zxdh_gdma_rawdev *gdmadev = NULL;
828 : : struct zxdh_gdma_queue *queue = NULL;
829 : : uint8_t i = 0;
830 : : int ret;
831 : :
832 [ # # ]: 0 : if (pci_dev->mem_resource[0].phys_addr == 0) {
833 : 0 : ZXDH_PMD_LOG(ERR, "PCI bar0 resource is invalid");
834 : 0 : return -1;
835 : : }
836 : :
837 : 0 : ret = zxdh_gdma_map_resource(pci_dev);
838 [ # # ]: 0 : if (ret != 0) {
839 : 0 : ZXDH_PMD_LOG(ERR, "Failed to mmap pci device(%s)", pci_dev->name);
840 : 0 : return -1;
841 : : }
842 : 0 : ZXDH_PMD_LOG(INFO, "%s bar0 0x%"PRIx64" mapped at %p",
843 : : pci_dev->name, pci_dev->mem_resource[0].phys_addr,
844 : : pci_dev->mem_resource[0].addr);
845 : :
846 : 0 : dev = rte_rawdev_pmd_allocate(dev_name, sizeof(struct zxdh_gdma_rawdev), rte_socket_id());
847 [ # # ]: 0 : if (dev == NULL) {
848 : 0 : ZXDH_PMD_LOG(ERR, "Unable to allocate gdma rawdev");
849 : 0 : goto err_out;
850 : : }
851 : 0 : ZXDH_PMD_LOG(INFO, "Init %s on NUMA node %d, dev_id is %d",
852 : : dev_name, rte_socket_id(), dev->dev_id);
853 : :
854 : 0 : dev->dev_ops = &zxdh_gdma_rawdev_ops;
855 : 0 : dev->device = &pci_dev->device;
856 : 0 : dev->driver_name = zxdh_gdma_driver_name;
857 : : gdmadev = zxdh_gdma_rawdev_get_priv(dev);
858 : 0 : gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
859 : 0 : gdmadev->rawdev = dev;
860 : 0 : gdmadev->queue_num = ZXDH_GDMA_TOTAL_CHAN_NUM;
861 : 0 : gdmadev->used_num = 0;
862 : 0 : gdmadev->base_addr = (uintptr_t)pci_dev->mem_resource[0].addr + ZXDH_GDMA_BASE_OFFSET;
863 : :
864 [ # # ]: 0 : for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
865 : 0 : queue = &(gdmadev->vqs[i]);
866 : 0 : queue->enable = 0;
867 : 0 : queue->queue_size = ZXDH_GDMA_QUEUE_SIZE;
868 : : rte_spinlock_init(&(queue->enqueue_lock));
869 : : }
870 : :
871 : : return 0;
872 : :
873 : : err_out:
874 : 0 : zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
875 : 0 : (size_t)pci_dev->mem_resource[0].len);
876 : 0 : return -1;
877 : : }
878 : :
879 : : static int
880 : 0 : zxdh_gdma_rawdev_remove(struct rte_pci_device *pci_dev)
881 : : {
882 : : struct rte_rawdev *dev = NULL;
883 : : int ret = 0;
884 : :
885 : 0 : dev = rte_rawdev_pmd_get_named_dev(dev_name);
886 [ # # ]: 0 : if (dev == NULL)
887 : : return -EINVAL;
888 : :
889 : : /* rte_rawdev_close is called by pmd_release */
890 : 0 : ret = rte_rawdev_pmd_release(dev);
891 [ # # ]: 0 : if (ret != 0) {
892 : 0 : ZXDH_PMD_LOG(ERR, "Device cleanup failed");
893 : 0 : return -1;
894 : : }
895 : :
896 : 0 : zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
897 : 0 : (size_t)pci_dev->mem_resource[0].len);
898 : :
899 : 0 : ZXDH_PMD_LOG(DEBUG, "rawdev %s remove done!", dev_name);
900 : :
901 : 0 : return ret;
902 : : }
903 : :
904 : : static const struct rte_pci_id zxdh_gdma_rawdev_map[] = {
905 : : { RTE_PCI_DEVICE(ZXDH_GDMA_VENDORID, ZXDH_GDMA_DEVICEID) },
906 : : { .vendor_id = 0, /* sentinel */ },
907 : : };
908 : :
909 : : static struct rte_pci_driver zxdh_gdma_rawdev_pmd = {
910 : : .id_table = zxdh_gdma_rawdev_map,
911 : : .drv_flags = 0,
912 : : .probe = zxdh_gdma_rawdev_probe,
913 : : .remove = zxdh_gdma_rawdev_remove,
914 : : };
915 : :
916 : 252 : RTE_PMD_REGISTER_PCI(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_pmd);
917 : : RTE_PMD_REGISTER_PCI_TABLE(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_map);
918 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(zxdh_gdma_rawdev_logtype, NOTICE);
|