1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2019 Marvell International Ltd. 3 */ 4 5 #include <rte_malloc.h> 6 7 #include "nitrox_device.h" 8 #include "nitrox_hal.h" 9 #include "nitrox_sym.h" 10 #include "nitrox_comp.h" 11 12 #define PCI_VENDOR_ID_CAVIUM 0x177d 13 #define NITROX_V_PCI_VF_DEV_ID 0x13 14 15 TAILQ_HEAD(ndev_list, nitrox_device); 16 static struct ndev_list ndev_list = TAILQ_HEAD_INITIALIZER(ndev_list); 17 18 static struct nitrox_device * 19 ndev_allocate(struct rte_pci_device *pdev) 20 { 21 struct nitrox_device *ndev; 22 23 ndev = rte_zmalloc_socket("nitrox device", sizeof(*ndev), 24 RTE_CACHE_LINE_SIZE, 25 pdev->device.numa_node); 26 if (!ndev) 27 return NULL; 28 29 TAILQ_INSERT_TAIL(&ndev_list, ndev, next); 30 return ndev; 31 } 32 33 static void 34 ndev_init(struct nitrox_device *ndev, struct rte_pci_device *pdev) 35 { 36 enum nitrox_vf_mode vf_mode; 37 38 ndev->pdev = pdev; 39 ndev->bar_addr = pdev->mem_resource[0].addr; 40 vf_mode = vf_get_vf_config_mode(ndev->bar_addr); 41 ndev->nr_queues = vf_config_mode_to_nr_queues(vf_mode); 42 } 43 44 static struct nitrox_device * 45 find_ndev(struct rte_pci_device *pdev) 46 { 47 struct nitrox_device *ndev; 48 49 TAILQ_FOREACH(ndev, &ndev_list, next) 50 if (ndev->pdev == pdev) 51 return ndev; 52 53 return NULL; 54 } 55 56 static void 57 ndev_release(struct nitrox_device *ndev) 58 { 59 if (!ndev) 60 return; 61 62 TAILQ_REMOVE(&ndev_list, ndev, next); 63 rte_free(ndev); 64 } 65 66 static int 67 nitrox_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 68 struct rte_pci_device *pdev) 69 { 70 struct nitrox_device *ndev; 71 int err = -1; 72 73 /* Nitrox CSR space */ 74 if (!pdev->mem_resource[0].addr) 75 return -EINVAL; 76 77 ndev = ndev_allocate(pdev); 78 if (!ndev) 79 return -ENOMEM; 80 81 ndev_init(ndev, pdev); 82 err = nitrox_sym_pmd_create(ndev); 83 if (err) 84 goto sym_pmd_err; 85 86 err = nitrox_comp_pmd_create(ndev); 87 if (err) 88 goto comp_pmd_err; 89 90 return 0; 91 92 comp_pmd_err: 93 nitrox_sym_pmd_destroy(ndev); 94 sym_pmd_err: 95 ndev_release(ndev); 96 return err; 97 } 98 99 static int 100 nitrox_pci_remove(struct rte_pci_device *pdev) 101 { 102 struct nitrox_device *ndev; 103 int err; 104 105 ndev = find_ndev(pdev); 106 if (!ndev) 107 return -ENODEV; 108 109 err = nitrox_sym_pmd_destroy(ndev); 110 if (err) 111 return err; 112 113 err = nitrox_comp_pmd_destroy(ndev); 114 if (err) 115 return err; 116 117 ndev_release(ndev); 118 return 0; 119 } 120 121 static struct rte_pci_id pci_id_nitrox_map[] = { 122 { 123 /* Nitrox 5 VF */ 124 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, NITROX_V_PCI_VF_DEV_ID) 125 }, 126 {.device_id = 0}, 127 }; 128 129 static struct rte_pci_driver nitrox_pmd = { 130 .id_table = pci_id_nitrox_map, 131 .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 132 .probe = nitrox_pci_probe, 133 .remove = nitrox_pci_remove, 134 }; 135 136 __rte_weak int 137 nitrox_sym_pmd_create(struct nitrox_device *ndev) 138 { 139 RTE_SET_USED(ndev); 140 return 0; 141 } 142 143 __rte_weak int 144 nitrox_sym_pmd_destroy(struct nitrox_device *ndev) 145 { 146 RTE_SET_USED(ndev); 147 return 0; 148 } 149 150 __rte_weak int 151 nitrox_comp_pmd_create(struct nitrox_device *ndev) 152 { 153 RTE_SET_USED(ndev); 154 return 0; 155 } 156 157 __rte_weak int 158 nitrox_comp_pmd_destroy(struct nitrox_device *ndev) 159 { 160 RTE_SET_USED(ndev); 161 return 0; 162 } 163 164 RTE_PMD_REGISTER_PCI(nitrox, nitrox_pmd); 165 RTE_PMD_REGISTER_PCI_TABLE(nitrox, pci_id_nitrox_map); 166