common/octeontx2: introduce common device class
[dpdk.git] / drivers / common / octeontx2 / otx2_dev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <fcntl.h>
6 #include <inttypes.h>
7 #include <sys/mman.h>
8 #include <unistd.h>
9
10 #include <rte_common.h>
11 #include <rte_eal.h>
12 #include <rte_memcpy.h>
13
14 #include "otx2_dev.h"
15 #include "otx2_mbox.h"
16
17 /* PF/VF message handling timer */
18 #define VF_PF_MBOX_TIMER_MS     (20 * 1000)
19
20 static void *
21 mbox_mem_map(off_t off, size_t size)
22 {
23         void *va = MAP_FAILED;
24         int mem_fd;
25
26         if (size <= 0)
27                 goto error;
28
29         mem_fd = open("/dev/mem", O_RDWR);
30         if (mem_fd < 0)
31                 goto error;
32
33         va = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, off);
34         close(mem_fd);
35
36         if (va == MAP_FAILED)
37                 otx2_err("Failed to mmap sz=0x%zx, fd=%d, off=%jd",
38                          size, mem_fd, (intmax_t)off);
39 error:
40         return va;
41 }
42
43 static void
44 mbox_mem_unmap(void *va, size_t size)
45 {
46         if (va)
47                 munmap(va, size);
48 }
49
50 static void
51 otx2_update_pass_hwcap(struct rte_pci_device *pci_dev, struct otx2_dev *dev)
52 {
53         RTE_SET_USED(pci_dev);
54
55         /* Update this logic when we have A1 */
56         dev->hwcap |= OTX2_HWCAP_F_A0;
57 }
58
59 static void
60 otx2_update_vf_hwcap(struct rte_pci_device *pci_dev, struct otx2_dev *dev)
61 {
62         dev->hwcap = 0;
63
64         switch (pci_dev->id.device_id) {
65         case PCI_DEVID_OCTEONTX2_RVU_PF:
66                 break;
67         case PCI_DEVID_OCTEONTX2_RVU_SSO_TIM_VF:
68         case PCI_DEVID_OCTEONTX2_RVU_NPA_VF:
69         case PCI_DEVID_OCTEONTX2_RVU_CPT_VF:
70         case PCI_DEVID_OCTEONTX2_RVU_AF_VF:
71         case PCI_DEVID_OCTEONTX2_RVU_VF:
72                 dev->hwcap |= OTX2_HWCAP_F_VF;
73                 break;
74         }
75 }
76
77 /**
78  * @internal
79  * Initialize the otx2 device
80  */
81 int
82 otx2_dev_init(struct rte_pci_device *pci_dev, void *otx2_dev)
83 {
84         int up_direction = MBOX_DIR_PFAF_UP;
85         int rc, direction = MBOX_DIR_PFAF;
86         struct otx2_dev *dev = otx2_dev;
87         uintptr_t bar2, bar4;
88         uint64_t bar4_addr;
89         void *hwbase;
90
91         bar2 = (uintptr_t)pci_dev->mem_resource[2].addr;
92         bar4 = (uintptr_t)pci_dev->mem_resource[4].addr;
93
94         if (bar2 == 0 || bar4 == 0) {
95                 otx2_err("Failed to get pci bars");
96                 rc = -ENODEV;
97                 goto error;
98         }
99
100         dev->node = pci_dev->device.numa_node;
101         dev->maxvf = pci_dev->max_vfs;
102         dev->bar2 = bar2;
103         dev->bar4 = bar4;
104
105         otx2_update_vf_hwcap(pci_dev, dev);
106         otx2_update_pass_hwcap(pci_dev, dev);
107
108         if (otx2_dev_is_vf(dev)) {
109                 direction = MBOX_DIR_VFPF;
110                 up_direction = MBOX_DIR_VFPF_UP;
111         }
112
113         /* Initialize the local mbox */
114         rc = otx2_mbox_init(&dev->mbox_local, bar4, bar2, direction, 1);
115         if (rc)
116                 goto error;
117         dev->mbox = &dev->mbox_local;
118
119         rc = otx2_mbox_init(&dev->mbox_up, bar4, bar2, up_direction, 1);
120         if (rc)
121                 goto error;
122
123         /* Check the readiness of PF/VF */
124         rc = otx2_send_ready_msg(dev->mbox, &dev->pf_func);
125         if (rc)
126                 goto mbox_fini;
127
128         dev->pf = otx2_get_pf(dev->pf_func);
129         dev->vf = otx2_get_vf(dev->pf_func);
130         memset(&dev->active_vfs, 0, sizeof(dev->active_vfs));
131
132         /* Found VF devices in a PF device */
133         if (pci_dev->max_vfs > 0) {
134
135                 /* Remap mbox area for all vf's */
136                 bar4_addr = otx2_read64(bar2 + RVU_PF_VF_BAR4_ADDR);
137                 if (bar4_addr == 0) {
138                         rc = -ENODEV;
139                         goto mbox_fini;
140                 }
141
142                 hwbase = mbox_mem_map(bar4_addr, MBOX_SIZE * pci_dev->max_vfs);
143                 if (hwbase == MAP_FAILED) {
144                         rc = -ENOMEM;
145                         goto mbox_fini;
146                 }
147                 /* Init mbox object */
148                 rc = otx2_mbox_init(&dev->mbox_vfpf, (uintptr_t)hwbase,
149                                     bar2, MBOX_DIR_PFVF, pci_dev->max_vfs);
150                 if (rc)
151                         goto iounmap;
152
153                 /* PF -> VF UP messages */
154                 rc = otx2_mbox_init(&dev->mbox_vfpf_up, (uintptr_t)hwbase,
155                                     bar2, MBOX_DIR_PFVF_UP, pci_dev->max_vfs);
156                 if (rc)
157                         goto mbox_fini;
158         }
159
160         dev->mbox_active = 1;
161         return rc;
162
163 iounmap:
164         mbox_mem_unmap(hwbase, MBOX_SIZE * pci_dev->max_vfs);
165 mbox_fini:
166         otx2_mbox_fini(dev->mbox);
167         otx2_mbox_fini(&dev->mbox_up);
168 error:
169         return rc;
170 }
171
172 /**
173  * @internal
174  * Finalize the otx2 device
175  */
176 void
177 otx2_dev_fini(struct rte_pci_device *pci_dev, void *otx2_dev)
178 {
179         struct otx2_dev *dev = otx2_dev;
180         struct otx2_mbox *mbox;
181
182         /* Release PF - VF */
183         mbox = &dev->mbox_vfpf;
184         if (mbox->hwbase && mbox->dev)
185                 mbox_mem_unmap((void *)mbox->hwbase,
186                                MBOX_SIZE * pci_dev->max_vfs);
187         otx2_mbox_fini(mbox);
188         mbox = &dev->mbox_vfpf_up;
189         otx2_mbox_fini(mbox);
190
191         /* Release PF - AF */
192         mbox = dev->mbox;
193         otx2_mbox_fini(mbox);
194         mbox = &dev->mbox_up;
195         otx2_mbox_fini(mbox);
196         dev->mbox_active = 0;
197 }