1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2017 NXP. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of NXP nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <unistd.h> 34 #include <stdio.h> 35 #include <sys/types.h> 36 #include <string.h> 37 #include <stdlib.h> 38 #include <fcntl.h> 39 #include <errno.h> 40 41 #include <rte_malloc.h> 42 #include <rte_memcpy.h> 43 #include <rte_string_fns.h> 44 #include <rte_cycles.h> 45 #include <rte_kvargs.h> 46 #include <rte_dev.h> 47 #include <rte_ethdev.h> 48 49 #include <rte_fslmc.h> 50 #include <mc/fsl_dpcon.h> 51 #include <portal/dpaa2_hw_pvt.h> 52 #include "dpaa2_eventdev.h" 53 54 TAILQ_HEAD(dpcon_dev_list, dpaa2_dpcon_dev); 55 static struct dpcon_dev_list dpcon_dev_list 56 = TAILQ_HEAD_INITIALIZER(dpcon_dev_list); /*!< DPCON device list */ 57 58 static int 59 rte_dpaa2_create_dpcon_device(int dev_fd __rte_unused, 60 struct vfio_device_info *obj_info __rte_unused, 61 int dpcon_id) 62 { 63 struct dpaa2_dpcon_dev *dpcon_node; 64 struct dpcon_attr attr; 65 int ret; 66 67 /* Allocate DPAA2 dpcon handle */ 68 dpcon_node = rte_malloc(NULL, sizeof(struct dpaa2_dpcon_dev), 0); 69 if (!dpcon_node) { 70 PMD_DRV_LOG(ERR, "Memory allocation failed for DPCON Device"); 71 return -1; 72 } 73 74 /* Open the dpcon object */ 75 dpcon_node->dpcon.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX]; 76 ret = dpcon_open(&dpcon_node->dpcon, 77 CMD_PRI_LOW, dpcon_id, &dpcon_node->token); 78 if (ret) { 79 PMD_DRV_LOG(ERR, "Resource alloc failure with err code: %d", 80 ret); 81 rte_free(dpcon_node); 82 return -1; 83 } 84 85 /* Get the device attributes */ 86 ret = dpcon_get_attributes(&dpcon_node->dpcon, 87 CMD_PRI_LOW, dpcon_node->token, &attr); 88 if (ret != 0) { 89 PMD_DRV_LOG(ERR, "Reading device failed with err code: %d", 90 ret); 91 rte_free(dpcon_node); 92 return -1; 93 } 94 95 /* Updating device specific private information*/ 96 dpcon_node->qbman_ch_id = attr.qbman_ch_id; 97 dpcon_node->num_priorities = attr.num_priorities; 98 dpcon_node->dpcon_id = dpcon_id; 99 rte_atomic16_init(&dpcon_node->in_use); 100 101 TAILQ_INSERT_TAIL(&dpcon_dev_list, dpcon_node, next); 102 103 RTE_LOG(DEBUG, PMD, "DPAA2: Added [dpcon.%d]\n", dpcon_id); 104 105 return 0; 106 } 107 108 struct dpaa2_dpcon_dev *rte_dpaa2_alloc_dpcon_dev(void) 109 { 110 struct dpaa2_dpcon_dev *dpcon_dev = NULL; 111 112 /* Get DPCON dev handle from list using index */ 113 TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 114 if (dpcon_dev && rte_atomic16_test_and_set(&dpcon_dev->in_use)) 115 break; 116 } 117 118 return dpcon_dev; 119 } 120 121 void rte_dpaa2_free_dpcon_dev(struct dpaa2_dpcon_dev *dpcon) 122 { 123 struct dpaa2_dpcon_dev *dpcon_dev = NULL; 124 125 /* Match DPCON handle and mark it free */ 126 TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) { 127 if (dpcon_dev == dpcon) { 128 rte_atomic16_dec(&dpcon_dev->in_use); 129 return; 130 } 131 } 132 } 133 134 static struct rte_dpaa2_object rte_dpaa2_dpcon_obj = { 135 .dev_type = DPAA2_CON, 136 .create = rte_dpaa2_create_dpcon_device, 137 }; 138 139 RTE_PMD_REGISTER_DPAA2_OBJECT(dpcon, rte_dpaa2_dpcon_obj); 140