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 *
ndev_allocate(struct rte_pci_device * pdev)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
ndev_init(struct nitrox_device * ndev,struct rte_pci_device * pdev)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 *
find_ndev(struct rte_pci_device * pdev)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
ndev_release(struct nitrox_device * ndev)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
nitrox_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pdev)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
nitrox_pci_remove(struct rte_pci_device * pdev)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
nitrox_sym_pmd_create(struct nitrox_device * ndev)137 nitrox_sym_pmd_create(struct nitrox_device *ndev)
138 {
139 RTE_SET_USED(ndev);
140 return 0;
141 }
142
143 __rte_weak int
nitrox_sym_pmd_destroy(struct nitrox_device * ndev)144 nitrox_sym_pmd_destroy(struct nitrox_device *ndev)
145 {
146 RTE_SET_USED(ndev);
147 return 0;
148 }
149
150 __rte_weak int
nitrox_comp_pmd_create(struct nitrox_device * ndev)151 nitrox_comp_pmd_create(struct nitrox_device *ndev)
152 {
153 RTE_SET_USED(ndev);
154 return 0;
155 }
156
157 __rte_weak int
nitrox_comp_pmd_destroy(struct nitrox_device * ndev)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