1 /* SPDX-License-Identifier: BSD-3-Clause
9 #include <rte_atomic.h>
10 #include <rte_lcore.h>
11 #include <rte_rawdev.h>
12 #include <rte_rawdev_pmd.h>
13 #include <rte_malloc.h>
15 #include <rte_mempool.h>
17 #include <mc/fsl_dpdmai.h>
18 #include <portal/dpaa2_hw_pvt.h>
19 #include <portal/dpaa2_hw_dpio.h>
21 #include "dpaa2_qdma.h"
22 #include "dpaa2_qdma_logs.h"
24 /* Dynamic log type identifier */
25 int dpaa2_qdma_logtype;
28 static struct qdma_device qdma_dev;
30 /* QDMA H/W queues list */
31 TAILQ_HEAD(qdma_hw_queue_list, qdma_hw_queue);
32 static struct qdma_hw_queue_list qdma_queue_list
33 = TAILQ_HEAD_INITIALIZER(qdma_queue_list);
35 static const struct rte_rawdev_ops dpaa2_qdma_ops;
38 add_hw_queues_to_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
40 struct qdma_hw_queue *queue;
43 DPAA2_QDMA_FUNC_TRACE();
45 for (i = 0; i < dpdmai_dev->num_queues; i++) {
46 queue = rte_zmalloc(NULL, sizeof(struct qdma_hw_queue), 0);
49 "Memory allocation failed for QDMA queue");
53 queue->dpdmai_dev = dpdmai_dev;
56 TAILQ_INSERT_TAIL(&qdma_queue_list, queue, next);
57 qdma_dev.num_hw_queues++;
64 remove_hw_queues_from_list(struct dpaa2_dpdmai_dev *dpdmai_dev)
66 struct qdma_hw_queue *queue = NULL;
67 struct qdma_hw_queue *tqueue = NULL;
69 DPAA2_QDMA_FUNC_TRACE();
71 TAILQ_FOREACH_SAFE(queue, &qdma_queue_list, next, tqueue) {
72 if (queue->dpdmai_dev == dpdmai_dev) {
73 TAILQ_REMOVE(&qdma_queue_list, queue, next);
81 dpaa2_dpdmai_dev_uninit(struct rte_rawdev *rawdev)
83 struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
86 DPAA2_QDMA_FUNC_TRACE();
88 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
91 /* Remove HW queues from global list */
92 remove_hw_queues_from_list(dpdmai_dev);
94 ret = dpdmai_disable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
97 DPAA2_QDMA_ERR("dmdmai disable failed");
99 /* Set up the DQRR storage for Rx */
100 for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
101 struct dpaa2_queue *rxq = &(dpdmai_dev->rx_queue[i]);
103 if (rxq->q_storage) {
104 dpaa2_free_dq_storage(rxq->q_storage);
105 rte_free(rxq->q_storage);
109 /* Close the device at underlying layer*/
110 ret = dpdmai_close(&dpdmai_dev->dpdmai, CMD_PRI_LOW, dpdmai_dev->token);
112 DPAA2_QDMA_ERR("Failure closing dpdmai device");
118 dpaa2_dpdmai_dev_init(struct rte_rawdev *rawdev, int dpdmai_id)
120 struct dpaa2_dpdmai_dev *dpdmai_dev = rawdev->dev_private;
121 struct dpdmai_rx_queue_cfg rx_queue_cfg;
122 struct dpdmai_attr attr;
123 struct dpdmai_rx_queue_attr rx_attr;
124 struct dpdmai_tx_queue_attr tx_attr;
127 DPAA2_QDMA_FUNC_TRACE();
129 /* For secondary processes, the primary has done all the work */
130 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
133 /* Open DPDMAI device */
134 dpdmai_dev->dpdmai_id = dpdmai_id;
135 dpdmai_dev->dpdmai.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
136 ret = dpdmai_open(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
137 dpdmai_dev->dpdmai_id, &dpdmai_dev->token);
139 DPAA2_QDMA_ERR("dpdmai_open() failed with err: %d", ret);
143 /* Get DPDMAI attributes */
144 ret = dpdmai_get_attributes(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
145 dpdmai_dev->token, &attr);
147 DPAA2_QDMA_ERR("dpdmai get attributes failed with err: %d",
151 dpdmai_dev->num_queues = attr.num_of_priorities;
153 /* Set up Rx Queues */
154 for (i = 0; i < attr.num_of_priorities; i++) {
155 struct dpaa2_queue *rxq;
157 memset(&rx_queue_cfg, 0, sizeof(struct dpdmai_rx_queue_cfg));
158 ret = dpdmai_set_rx_queue(&dpdmai_dev->dpdmai,
163 DPAA2_QDMA_ERR("Setting Rx queue failed with err: %d",
168 /* Allocate DQ storage for the DPDMAI Rx queues */
169 rxq = &(dpdmai_dev->rx_queue[i]);
170 rxq->q_storage = rte_malloc("dq_storage",
171 sizeof(struct queue_storage_info_t),
172 RTE_CACHE_LINE_SIZE);
173 if (!rxq->q_storage) {
174 DPAA2_QDMA_ERR("q_storage allocation failed");
179 memset(rxq->q_storage, 0, sizeof(struct queue_storage_info_t));
180 ret = dpaa2_alloc_dq_storage(rxq->q_storage);
182 DPAA2_QDMA_ERR("dpaa2_alloc_dq_storage failed");
187 /* Get Rx and Tx queues FQID's */
188 for (i = 0; i < DPDMAI_PRIO_NUM; i++) {
189 ret = dpdmai_get_rx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
190 dpdmai_dev->token, i, &rx_attr);
192 DPAA2_QDMA_ERR("Reading device failed with err: %d",
196 dpdmai_dev->rx_queue[i].fqid = rx_attr.fqid;
198 ret = dpdmai_get_tx_queue(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
199 dpdmai_dev->token, i, &tx_attr);
201 DPAA2_QDMA_ERR("Reading device failed with err: %d",
205 dpdmai_dev->tx_queue[i].fqid = tx_attr.fqid;
208 /* Enable the device */
209 ret = dpdmai_enable(&dpdmai_dev->dpdmai, CMD_PRI_LOW,
212 DPAA2_QDMA_ERR("Enabling device failed with err: %d", ret);
216 /* Add the HW queue to the global list */
217 ret = add_hw_queues_to_list(dpdmai_dev);
219 DPAA2_QDMA_ERR("Adding H/W queue to list failed");
222 DPAA2_QDMA_DEBUG("Initialized dpdmai object successfully");
226 dpaa2_dpdmai_dev_uninit(rawdev);
231 rte_dpaa2_qdma_probe(struct rte_dpaa2_driver *dpaa2_drv,
232 struct rte_dpaa2_device *dpaa2_dev)
234 struct rte_rawdev *rawdev;
237 DPAA2_QDMA_FUNC_TRACE();
239 rawdev = rte_rawdev_pmd_allocate(dpaa2_dev->device.name,
240 sizeof(struct dpaa2_dpdmai_dev),
243 DPAA2_QDMA_ERR("Unable to allocate rawdevice");
247 dpaa2_dev->rawdev = rawdev;
248 rawdev->dev_ops = &dpaa2_qdma_ops;
249 rawdev->device = &dpaa2_dev->device;
250 rawdev->driver_name = dpaa2_drv->driver.name;
252 /* Invoke PMD device initialization function */
253 ret = dpaa2_dpdmai_dev_init(rawdev, dpaa2_dev->object_id);
255 rte_rawdev_pmd_release(rawdev);
263 rte_dpaa2_qdma_remove(struct rte_dpaa2_device *dpaa2_dev)
265 struct rte_rawdev *rawdev = dpaa2_dev->rawdev;
268 DPAA2_QDMA_FUNC_TRACE();
270 dpaa2_dpdmai_dev_uninit(rawdev);
272 ret = rte_rawdev_pmd_release(rawdev);
274 DPAA2_QDMA_ERR("Device cleanup failed");
279 static struct rte_dpaa2_driver rte_dpaa2_qdma_pmd = {
280 .drv_type = DPAA2_QDMA,
281 .probe = rte_dpaa2_qdma_probe,
282 .remove = rte_dpaa2_qdma_remove,
285 RTE_PMD_REGISTER_DPAA2(dpaa2_qdma, rte_dpaa2_qdma_pmd);
287 RTE_INIT(dpaa2_qdma_init_log);
289 dpaa2_qdma_init_log(void)
291 dpaa2_qdma_logtype = rte_log_register("pmd.raw.dpaa2.qdma");
292 if (dpaa2_qdma_logtype >= 0)
293 rte_log_set_level(dpaa2_qdma_logtype, RTE_LOG_INFO);