Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2017 Cavium, Inc 3 : : */ 4 : : 5 : : #include <rte_eal.h> 6 : : #include <rte_io.h> 7 : : #include <rte_pci.h> 8 : : #include <bus_pci_driver.h> 9 : : 10 : : #include <octeontx_mbox.h> 11 : : 12 : : #include "ssovf_evdev.h" 13 : : #include "timvf_evdev.h" 14 : : 15 : : #ifndef PCI_VENDOR_ID_CAVIUM 16 : : #define PCI_VENDOR_ID_CAVIUM (0x177D) 17 : : #endif 18 : : 19 : : #define PCI_DEVICE_ID_OCTEONTX_TIM_VF (0xA051) 20 : : #define TIM_MAX_RINGS (64) 21 : : 22 : : struct timvf_res { 23 : : uint8_t in_use; 24 : : uint16_t domain; 25 : : uint16_t vfid; 26 : : void *bar0; 27 : : void *bar2; 28 : : void *bar4; 29 : : }; 30 : : 31 : : struct timdev { 32 : : uint8_t total_timvfs; 33 : : struct timvf_res rings[TIM_MAX_RINGS]; 34 : : }; 35 : : 36 : : static struct timdev tdev; 37 : : 38 : : uint8_t 39 : 0 : timvf_get_ring(void) 40 : : { 41 : 0 : uint16_t global_domain = octeontx_get_global_domain(); 42 : : int i; 43 : : 44 [ # # ]: 0 : for (i = 0; i < tdev.total_timvfs; i++) { 45 [ # # ]: 0 : if (tdev.rings[i].domain != global_domain) 46 : 0 : continue; 47 [ # # ]: 0 : if (tdev.rings[i].in_use) 48 : 0 : continue; 49 : : 50 : 0 : tdev.rings[i].in_use = true; 51 : 0 : return tdev.rings[i].vfid; 52 : : } 53 : : 54 : : return UINT8_MAX; 55 : : } 56 : : 57 : : void 58 : 0 : timvf_release_ring(uint8_t tim_ring_id) 59 : : { 60 : 0 : uint16_t global_domain = octeontx_get_global_domain(); 61 : : int i; 62 : : 63 [ # # ]: 0 : for (i = 0; i < tdev.total_timvfs; i++) { 64 [ # # ]: 0 : if (tdev.rings[i].domain != global_domain) 65 : 0 : continue; 66 [ # # ]: 0 : if (tdev.rings[i].vfid == tim_ring_id) 67 : 0 : tdev.rings[i].in_use = false; 68 : : } 69 : 0 : } 70 : : 71 : : void* 72 : 0 : timvf_bar(uint8_t vfid, uint8_t bar) 73 : : { 74 : 0 : uint16_t global_domain = octeontx_get_global_domain(); 75 : : struct timvf_res *res = NULL; 76 : : int i; 77 : : 78 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) 79 : : return NULL; 80 : : 81 [ # # ]: 0 : for (i = 0; i < tdev.total_timvfs; i++) { 82 [ # # ]: 0 : if (tdev.rings[i].domain != global_domain) 83 : 0 : continue; 84 [ # # ]: 0 : if (tdev.rings[i].vfid == vfid) 85 : 0 : res = &tdev.rings[i]; 86 : : 87 : : } 88 : : 89 [ # # ]: 0 : if (res == NULL) 90 : : return NULL; 91 : : 92 [ # # # ]: 0 : switch (bar) { 93 : 0 : case 0: 94 : 0 : return res->bar0; 95 : 0 : case 4: 96 : 0 : return res->bar4; 97 : : default: 98 : : return NULL; 99 : : } 100 : : } 101 : : 102 : : static int 103 : 0 : timvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) 104 : : { 105 : : uint64_t val; 106 : : uint16_t vfid; 107 : : struct timvf_res *res; 108 : : 109 : : RTE_SET_USED(pci_drv); 110 : : 111 : : /* For secondary processes, the primary has done all the work */ 112 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) 113 : : return 0; 114 : : 115 [ # # ]: 0 : if (pci_dev->mem_resource[0].addr == NULL || 116 [ # # ]: 0 : pci_dev->mem_resource[4].addr == NULL) { 117 : 0 : timvf_log_err("Empty bars %p %p", 118 : : pci_dev->mem_resource[0].addr, 119 : : pci_dev->mem_resource[4].addr); 120 : 0 : return -ENODEV; 121 : : } 122 : : 123 : : val = rte_read64((uint8_t *)pci_dev->mem_resource[0].addr + 124 : : 0x100 /* TIM_VRINGX_BASE */); 125 : 0 : vfid = (val >> 23) & 0xff; 126 [ # # ]: 0 : if (vfid >= TIM_MAX_RINGS) { 127 : 0 : timvf_log_err("Invalid vfid(%d/%d)", vfid, TIM_MAX_RINGS); 128 : 0 : return -EINVAL; 129 : : } 130 : : 131 : 0 : res = &tdev.rings[tdev.total_timvfs]; 132 : 0 : res->vfid = vfid; 133 : 0 : res->bar0 = pci_dev->mem_resource[0].addr; 134 : 0 : res->bar2 = pci_dev->mem_resource[2].addr; 135 : 0 : res->bar4 = pci_dev->mem_resource[4].addr; 136 : 0 : res->domain = (val >> 7) & 0xffff; 137 : 0 : res->in_use = false; 138 : 0 : tdev.total_timvfs++; 139 : : rte_wmb(); 140 : : 141 : 0 : timvf_log_dbg("Domain=%d VFid=%d bar0 %p total_timvfs=%d", res->domain, 142 : : res->vfid, pci_dev->mem_resource[0].addr, 143 : : tdev.total_timvfs); 144 : 0 : return 0; 145 : : } 146 : : 147 : : 148 : : static const struct rte_pci_id pci_timvf_map[] = { 149 : : { 150 : : RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 151 : : PCI_DEVICE_ID_OCTEONTX_TIM_VF) 152 : : }, 153 : : { 154 : : .vendor_id = 0, 155 : : }, 156 : : }; 157 : : 158 : : static struct rte_pci_driver pci_timvf = { 159 : : .id_table = pci_timvf_map, 160 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA, 161 : : .probe = timvf_probe, 162 : : .remove = NULL, 163 : : }; 164 : : 165 : 252 : RTE_PMD_REGISTER_PCI(octeontx_timvf, pci_timvf);