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