raw/cnxk_bphy: add BPHY CGX/RPM skeleton driver
[dpdk.git] / drivers / raw / cnxk_bphy / cnxk_bphy_cgx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #include <rte_bus_pci.h>
5 #include <rte_rawdev.h>
6 #include <rte_rawdev_pmd.h>
7
8 #include <roc_api.h>
9
10 struct cnxk_bphy_cgx_queue {
11         unsigned int lmac;
12         /* queue holds up to one response */
13         void *rsp;
14 };
15
16 struct cnxk_bphy_cgx {
17         struct roc_bphy_cgx *rcgx;
18         struct cnxk_bphy_cgx_queue queues[MAX_LMACS_PER_CGX];
19         unsigned int num_queues;
20 };
21
22 static void
23 cnxk_bphy_cgx_format_name(char *name, unsigned int len,
24                           struct rte_pci_device *pci_dev)
25 {
26         snprintf(name, len, "BPHY_CGX:%x:%02x.%x", pci_dev->addr.bus,
27                  pci_dev->addr.devid, pci_dev->addr.function);
28 }
29
30 static const struct rte_rawdev_ops cnxk_bphy_cgx_rawdev_ops = {
31 };
32
33 static void
34 cnxk_bphy_cgx_init_queues(struct cnxk_bphy_cgx *cgx)
35 {
36         struct roc_bphy_cgx *rcgx = cgx->rcgx;
37         unsigned int i;
38
39         for (i = 0; i < RTE_DIM(cgx->queues); i++) {
40                 if (!(rcgx->lmac_bmap & BIT_ULL(i)))
41                         continue;
42
43                 cgx->queues[cgx->num_queues++].lmac = i;
44         }
45 }
46
47 static void
48 cnxk_bphy_cgx_fini_queues(struct cnxk_bphy_cgx *cgx)
49 {
50         unsigned int i;
51
52         for (i = 0; i < cgx->num_queues; i++) {
53                 if (cgx->queues[i].rsp)
54                         rte_free(cgx->queues[i].rsp);
55         }
56
57         cgx->num_queues = 0;
58 }
59
60 static int
61 cnxk_bphy_cgx_rawdev_probe(struct rte_pci_driver *pci_drv,
62                            struct rte_pci_device *pci_dev)
63 {
64         char name[RTE_RAWDEV_NAME_MAX_LEN];
65         struct rte_rawdev *rawdev;
66         struct cnxk_bphy_cgx *cgx;
67         struct roc_bphy_cgx *rcgx;
68         int ret;
69
70         RTE_SET_USED(pci_drv);
71
72         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
73                 return 0;
74
75         if (!pci_dev->mem_resource[0].addr)
76                 return -ENODEV;
77
78         ret = roc_plt_init();
79         if (ret)
80                 return ret;
81
82         cnxk_bphy_cgx_format_name(name, sizeof(name), pci_dev);
83         rawdev = rte_rawdev_pmd_allocate(name, sizeof(*cgx), rte_socket_id());
84         if (!rawdev)
85                 return -ENOMEM;
86
87         rawdev->dev_ops = &cnxk_bphy_cgx_rawdev_ops;
88         rawdev->device = &pci_dev->device;
89         rawdev->driver_name = pci_dev->driver->driver.name;
90
91         cgx = rawdev->dev_private;
92         cgx->rcgx = rte_zmalloc(NULL, sizeof(*rcgx), 0);
93         if (!cgx->rcgx) {
94                 ret = -ENOMEM;
95                 goto out_pmd_release;
96         }
97
98         rcgx = cgx->rcgx;
99         rcgx->bar0_pa = pci_dev->mem_resource[0].phys_addr;
100         rcgx->bar0_va = pci_dev->mem_resource[0].addr;
101         ret = roc_bphy_cgx_dev_init(rcgx);
102         if (ret)
103                 goto out_free;
104
105         cnxk_bphy_cgx_init_queues(cgx);
106
107         return 0;
108 out_free:
109         rte_free(rcgx);
110 out_pmd_release:
111         rte_rawdev_pmd_release(rawdev);
112
113         return ret;
114 }
115
116 static int
117 cnxk_bphy_cgx_rawdev_remove(struct rte_pci_device *pci_dev)
118 {
119         char name[RTE_RAWDEV_NAME_MAX_LEN];
120         struct rte_rawdev *rawdev;
121         struct cnxk_bphy_cgx *cgx;
122
123         cnxk_bphy_cgx_format_name(name, sizeof(name), pci_dev);
124         rawdev = rte_rawdev_pmd_get_named_dev(name);
125         if (!rawdev)
126                 return -ENODEV;
127
128         cgx = rawdev->dev_private;
129         cnxk_bphy_cgx_fini_queues(cgx);
130         roc_bphy_cgx_dev_fini(cgx->rcgx);
131         rte_free(cgx->rcgx);
132
133         return rte_rawdev_pmd_release(rawdev);
134 }
135
136 static const struct rte_pci_id cnxk_bphy_cgx_map[] = {
137         {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN9K_CGX)},
138         {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RPM)},
139         {} /* sentinel */
140 };
141
142 static struct rte_pci_driver bphy_cgx_rawdev_pmd = {
143         .id_table = cnxk_bphy_cgx_map,
144         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
145         .probe = cnxk_bphy_cgx_rawdev_probe,
146         .remove = cnxk_bphy_cgx_rawdev_remove,
147 };
148
149 RTE_PMD_REGISTER_PCI(cnxk_bphy_cgx_rawdev_pci_driver, bphy_cgx_rawdev_pmd);
150 RTE_PMD_REGISTER_PCI_TABLE(cnxk_bphy_cgx_rawdev_pci_driver, cnxk_bphy_cgx_map);
151 RTE_PMD_REGISTER_KMOD_DEP(cnxk_bphy_cgx_rawdev_pci_driver, "vfio-pci");