1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright 2017 NXP 4 * 5 */ 6 7 #include <unistd.h> 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <string.h> 11 #include <stdlib.h> 12 #include <fcntl.h> 13 #include <errno.h> 14 15 #include <rte_malloc.h> 16 #include <rte_memcpy.h> 17 #include <rte_string_fns.h> 18 #include <rte_cycles.h> 19 #include <rte_kvargs.h> 20 #include <rte_dev.h> 21 #include <ethdev_driver.h> 22 23 #include <rte_fslmc.h> 24 #include <mc/fsl_dpcon.h> 25 #include <portal/dpaa2_hw_pvt.h> 26 #include "dpaa2_eventdev.h" 27 #include "dpaa2_eventdev_logs.h" 28 29 TAILQ_HEAD(dpcon_dev_list, dpaa2_dpcon_dev); 30 static struct dpcon_dev_list dpcon_dev_list 31 = TAILQ_HEAD_INITIALIZER(dpcon_dev_list); /*!< DPCON device list */ 32 33 static int 34 rte_dpaa2_create_dpcon_device(int dev_fd __rte_unused, 35 struct vfio_device_info *obj_info __rte_unused, 36 int dpcon_id) 37 { 38 struct dpaa2_dpcon_dev *dpcon_node; 39 struct dpcon_attr attr; 40 int ret; 41 42 /* Allocate DPAA2 dpcon handle */ 43 dpcon_node = rte_malloc(NULL, sizeof(struct dpaa2_dpcon_dev), 0); 44 if (!dpcon_node) { 45 DPAA2_EVENTDEV_ERR( 46 "Memory allocation failed for dpcon device"); 47 return -1; 48 } 49 50 /* Open the dpcon object */ 51 dpcon_node->dpcon.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX); 52 ret = dpcon_open(&dpcon_node->dpcon, 53 CMD_PRI_LOW, dpcon_id, &dpcon_node->token); 54 if (ret) { 55 DPAA2_EVENTDEV_ERR("Unable to open dpcon device: err(%d)", 56 ret); 57 rte_free(dpcon_node); 58 return -1; 59 } 60 61 /* Get the device attributes */ 62 ret = dpcon_get_attributes(&dpcon_node->dpcon, 63 CMD_PRI_LOW, dpcon_node->token, &attr); 64 if (ret != 0) { 65 DPAA2_EVENTDEV_ERR("dpcon attribute fetch failed: err(%d)", 66 ret); 67 rte_free(dpcon_node); 68 return -1; 69 } 70 71 /* Updating device specific private information*/ 72 dpcon_node->qbman_ch_id = attr.qbman_ch_id; 73 dpcon_node->num_priorities = attr.num_priorities; 74 dpcon_node->dpcon_id = dpcon_id; 75 rte_atomic16_init(&dpcon_node->in_use); 76 77 TAILQ_INSERT_TAIL(&dpcon_dev_list, dpcon_node, next); 78 79 return 0; 80 } 81 82 struct dpaa2_dpcon_dev *rte_dpaa2_alloc_dpcon_dev(void) 83 { 84 struct dpaa2_dpcon_dev *dpcon_dev = NULL; 85 86 /* Get DPCON dev handle from list using index */ 87 TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 88 if (dpcon_dev && rte_atomic16_test_and_set(&dpcon_dev->in_use)) 89 break; 90 } 91 92 return dpcon_dev; 93 } 94 95 void rte_dpaa2_free_dpcon_dev(struct dpaa2_dpcon_dev *dpcon) 96 { 97 struct dpaa2_dpcon_dev *dpcon_dev = NULL; 98 99 /* Match DPCON handle and mark it free */ 100 TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 101 if (dpcon_dev == dpcon) { 102 rte_atomic16_dec(&dpcon_dev->in_use); 103 return; 104 } 105 } 106 } 107 108 static struct rte_dpaa2_object rte_dpaa2_dpcon_obj = { 109 .dev_type = DPAA2_CON, 110 .create = rte_dpaa2_create_dpcon_device, 111 }; 112 113 RTE_PMD_REGISTER_DPAA2_OBJECT(dpcon, rte_dpaa2_dpcon_obj); 114