Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * 3 : : * Copyright 2017, 2020, 2023 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 <dev_driver.h> 21 : : #include <ethdev_driver.h> 22 : : 23 : : #include <bus_fslmc_driver.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 struct dpaa2_dpcon_dev *get_dpcon_from_id(uint32_t dpcon_id) 34 : : { 35 : : struct dpaa2_dpcon_dev *dpcon_dev = NULL; 36 : : 37 : : /* Get DPCONC dev handle from list using index */ 38 [ # # ]: 0 : TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 39 [ # # ]: 0 : if (dpcon_dev->dpcon_id == dpcon_id) 40 : : break; 41 : : } 42 : : 43 : : return dpcon_dev; 44 : : } 45 : : 46 : : static int 47 : 0 : rte_dpaa2_create_dpcon_device(int dev_fd __rte_unused, 48 : : struct vfio_device_info *obj_info __rte_unused, 49 : : struct rte_dpaa2_device *obj) 50 : : { 51 : : struct dpaa2_dpcon_dev *dpcon_node; 52 : : struct dpcon_attr attr; 53 : 0 : int ret, dpcon_id = obj->object_id; 54 : : 55 : : /* Allocate DPAA2 dpcon handle */ 56 : 0 : dpcon_node = rte_malloc(NULL, sizeof(struct dpaa2_dpcon_dev), 0); 57 [ # # ]: 0 : if (!dpcon_node) { 58 : 0 : DPAA2_EVENTDEV_ERR( 59 : : "Memory allocation failed for dpcon device"); 60 : 0 : return -1; 61 : : } 62 : : 63 : : /* Open the dpcon object */ 64 : 0 : dpcon_node->dpcon.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX); 65 : 0 : ret = dpcon_open(&dpcon_node->dpcon, 66 : : CMD_PRI_LOW, dpcon_id, &dpcon_node->token); 67 [ # # ]: 0 : if (ret) { 68 : 0 : DPAA2_EVENTDEV_ERR("Unable to open dpcon device: err(%d)", 69 : : ret); 70 : 0 : rte_free(dpcon_node); 71 : 0 : return -1; 72 : : } 73 : : 74 : : /* Get the device attributes */ 75 : 0 : ret = dpcon_get_attributes(&dpcon_node->dpcon, 76 : 0 : CMD_PRI_LOW, dpcon_node->token, &attr); 77 [ # # ]: 0 : if (ret != 0) { 78 : 0 : DPAA2_EVENTDEV_ERR("dpcon attribute fetch failed: err(%d)", 79 : : ret); 80 : 0 : rte_free(dpcon_node); 81 : 0 : return -1; 82 : : } 83 : : 84 : : /* Updating device specific private information*/ 85 : 0 : dpcon_node->qbman_ch_id = attr.qbman_ch_id; 86 : 0 : dpcon_node->num_priorities = attr.num_priorities; 87 : 0 : dpcon_node->dpcon_id = dpcon_id; 88 : : rte_atomic16_init(&dpcon_node->in_use); 89 : : 90 : 0 : TAILQ_INSERT_TAIL(&dpcon_dev_list, dpcon_node, next); 91 : : 92 : 0 : return 0; 93 : : } 94 : : 95 : 0 : struct dpaa2_dpcon_dev *rte_dpaa2_alloc_dpcon_dev(void) 96 : : { 97 : : struct dpaa2_dpcon_dev *dpcon_dev = NULL; 98 : : 99 : : /* Get DPCON dev handle from list using index */ 100 [ # # ]: 0 : TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 101 [ # # ]: 0 : if (dpcon_dev && rte_atomic16_test_and_set(&dpcon_dev->in_use)) 102 : : break; 103 : : } 104 : : 105 : 0 : return dpcon_dev; 106 : : } 107 : : 108 : 0 : void rte_dpaa2_free_dpcon_dev(struct dpaa2_dpcon_dev *dpcon) 109 : : { 110 : : struct dpaa2_dpcon_dev *dpcon_dev = NULL; 111 : : 112 : : /* Match DPCON handle and mark it free */ 113 [ # # ]: 0 : TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 114 [ # # ]: 0 : if (dpcon_dev == dpcon) { 115 : 0 : rte_atomic16_dec(&dpcon_dev->in_use); 116 : 0 : return; 117 : : } 118 : : } 119 : : } 120 : : 121 : : 122 : : static void 123 : 0 : rte_dpaa2_close_dpcon_device(int object_id) 124 : : { 125 : : struct dpaa2_dpcon_dev *dpcon_dev = NULL; 126 : : 127 : 0 : dpcon_dev = get_dpcon_from_id((uint32_t)object_id); 128 : : 129 [ # # ]: 0 : if (dpcon_dev) { 130 : 0 : rte_dpaa2_free_dpcon_dev(dpcon_dev); 131 : 0 : dpcon_close(&dpcon_dev->dpcon, CMD_PRI_LOW, dpcon_dev->token); 132 [ # # ]: 0 : TAILQ_REMOVE(&dpcon_dev_list, dpcon_dev, next); 133 : 0 : rte_free(dpcon_dev); 134 : : } 135 : 0 : } 136 : : 137 : : static struct rte_dpaa2_object rte_dpaa2_dpcon_obj = { 138 : : .dev_type = DPAA2_CON, 139 : : .create = rte_dpaa2_create_dpcon_device, 140 : : .close = rte_dpaa2_close_dpcon_device, 141 : : }; 142 : : 143 : 251 : RTE_PMD_REGISTER_DPAA2_OBJECT(dpcon, rte_dpaa2_dpcon_obj);