net/octeontx2: handle device error interrupts
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_ethdev_pci.h>
6 #include <rte_io.h>
7 #include <rte_malloc.h>
8
9 #include "otx2_ethdev.h"
10
11 static inline void
12 otx2_eth_set_rx_function(struct rte_eth_dev *eth_dev)
13 {
14         RTE_SET_USED(eth_dev);
15 }
16
17 static inline void
18 otx2_eth_set_tx_function(struct rte_eth_dev *eth_dev)
19 {
20         RTE_SET_USED(eth_dev);
21 }
22
23 static inline uint64_t
24 nix_get_rx_offload_capa(struct otx2_eth_dev *dev)
25 {
26         uint64_t capa = NIX_RX_OFFLOAD_CAPA;
27
28         if (otx2_dev_is_vf(dev))
29                 capa &= ~DEV_RX_OFFLOAD_TIMESTAMP;
30
31         return capa;
32 }
33
34 static inline uint64_t
35 nix_get_tx_offload_capa(struct otx2_eth_dev *dev)
36 {
37         RTE_SET_USED(dev);
38
39         return NIX_TX_OFFLOAD_CAPA;
40 }
41
42 static int
43 nix_lf_free(struct otx2_eth_dev *dev)
44 {
45         struct otx2_mbox *mbox = dev->mbox;
46         struct nix_lf_free_req *req;
47         struct ndc_sync_op *ndc_req;
48         int rc;
49
50         /* Sync NDC-NIX for LF */
51         ndc_req = otx2_mbox_alloc_msg_ndc_sync_op(mbox);
52         ndc_req->nix_lf_tx_sync = 1;
53         ndc_req->nix_lf_rx_sync = 1;
54         rc = otx2_mbox_process(mbox);
55         if (rc)
56                 otx2_err("Error on NDC-NIX-[TX, RX] LF sync, rc %d", rc);
57
58         req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
59         /* Let AF driver free all this nix lf's
60          * NPC entries allocated using NPC MBOX.
61          */
62         req->flags = 0;
63
64         return otx2_mbox_process(mbox);
65 }
66
67 static inline int
68 nix_lf_attach(struct otx2_eth_dev *dev)
69 {
70         struct otx2_mbox *mbox = dev->mbox;
71         struct rsrc_attach_req *req;
72
73         /* Attach NIX(lf) */
74         req = otx2_mbox_alloc_msg_attach_resources(mbox);
75         req->modify = true;
76         req->nixlf = true;
77
78         return otx2_mbox_process(mbox);
79 }
80
81 static inline int
82 nix_lf_get_msix_offset(struct otx2_eth_dev *dev)
83 {
84         struct otx2_mbox *mbox = dev->mbox;
85         struct msix_offset_rsp *msix_rsp;
86         int rc;
87
88         /* Get NPA and NIX MSIX vector offsets */
89         otx2_mbox_alloc_msg_msix_offset(mbox);
90
91         rc = otx2_mbox_process_msg(mbox, (void *)&msix_rsp);
92
93         dev->nix_msixoff = msix_rsp->nix_msixoff;
94
95         return rc;
96 }
97
98 static inline int
99 otx2_eth_dev_lf_detach(struct otx2_mbox *mbox)
100 {
101         struct rsrc_detach_req *req;
102
103         req = otx2_mbox_alloc_msg_detach_resources(mbox);
104
105         /* Detach all except npa lf */
106         req->partial = true;
107         req->nixlf = true;
108         req->sso = true;
109         req->ssow = true;
110         req->timlfs = true;
111         req->cptlfs = true;
112
113         return otx2_mbox_process(mbox);
114 }
115
116 static int
117 otx2_eth_dev_init(struct rte_eth_dev *eth_dev)
118 {
119         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
120         struct rte_pci_device *pci_dev;
121         int rc, max_entries;
122
123         /* For secondary processes, the primary has done all the work */
124         if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
125                 /* Setup callbacks for secondary process */
126                 otx2_eth_set_tx_function(eth_dev);
127                 otx2_eth_set_rx_function(eth_dev);
128                 return 0;
129         }
130
131         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
132
133         rte_eth_copy_pci_info(eth_dev, pci_dev);
134         eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
135
136         /* Zero out everything after OTX2_DEV to allow proper dev_reset() */
137         memset(&dev->otx2_eth_dev_data_start, 0, sizeof(*dev) -
138                 offsetof(struct otx2_eth_dev, otx2_eth_dev_data_start));
139
140         /* Parse devargs string */
141         rc = otx2_ethdev_parse_devargs(eth_dev->device->devargs, dev);
142         if (rc) {
143                 otx2_err("Failed to parse devargs rc=%d", rc);
144                 goto error;
145         }
146
147         if (!dev->mbox_active) {
148                 /* Initialize the base otx2_dev object
149                  * only if already present
150                  */
151                 rc = otx2_dev_init(pci_dev, dev);
152                 if (rc) {
153                         otx2_err("Failed to initialize otx2_dev rc=%d", rc);
154                         goto error;
155                 }
156         }
157
158         /* Grab the NPA LF if required */
159         rc = otx2_npa_lf_init(pci_dev, dev);
160         if (rc)
161                 goto otx2_dev_uninit;
162
163         dev->configured = 0;
164         dev->drv_inited = true;
165         dev->base = dev->bar2 + (RVU_BLOCK_ADDR_NIX0 << 20);
166         dev->lmt_addr = dev->bar2 + (RVU_BLOCK_ADDR_LMT << 20);
167
168         /* Attach NIX LF */
169         rc = nix_lf_attach(dev);
170         if (rc)
171                 goto otx2_npa_uninit;
172
173         /* Get NIX MSIX offset */
174         rc = nix_lf_get_msix_offset(dev);
175         if (rc)
176                 goto otx2_npa_uninit;
177
178         /* Register LF irq handlers */
179         rc = otx2_nix_register_irqs(eth_dev);
180         if (rc)
181                 goto mbox_detach;
182
183         /* Get maximum number of supported MAC entries */
184         max_entries = otx2_cgx_mac_max_entries_get(dev);
185         if (max_entries < 0) {
186                 otx2_err("Failed to get max entries for mac addr");
187                 rc = -ENOTSUP;
188                 goto unregister_irq;
189         }
190
191         /* For VFs, returned max_entries will be 0. But to keep default MAC
192          * address, one entry must be allocated. So setting up to 1.
193          */
194         if (max_entries == 0)
195                 max_entries = 1;
196
197         eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", max_entries *
198                                                RTE_ETHER_ADDR_LEN, 0);
199         if (eth_dev->data->mac_addrs == NULL) {
200                 otx2_err("Failed to allocate memory for mac addr");
201                 rc = -ENOMEM;
202                 goto unregister_irq;
203         }
204
205         dev->max_mac_entries = max_entries;
206
207         rc = otx2_nix_mac_addr_get(eth_dev, dev->mac_addr);
208         if (rc)
209                 goto free_mac_addrs;
210
211         /* Update the mac address */
212         memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
213
214         /* Also sync same MAC address to CGX table */
215         otx2_cgx_mac_addr_set(eth_dev, &eth_dev->data->mac_addrs[0]);
216
217         dev->tx_offload_capa = nix_get_tx_offload_capa(dev);
218         dev->rx_offload_capa = nix_get_rx_offload_capa(dev);
219
220         if (otx2_dev_is_A0(dev)) {
221                 dev->hwcap |= OTX2_FIXUP_F_MIN_4K_Q;
222                 dev->hwcap |= OTX2_FIXUP_F_LIMIT_CQ_FULL;
223         }
224
225         otx2_nix_dbg("Port=%d pf=%d vf=%d ver=%s msix_off=%d hwcap=0x%" PRIx64
226                      " rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64,
227                      eth_dev->data->port_id, dev->pf, dev->vf,
228                      OTX2_ETH_DEV_PMD_VERSION, dev->nix_msixoff, dev->hwcap,
229                      dev->rx_offload_capa, dev->tx_offload_capa);
230         return 0;
231
232 free_mac_addrs:
233         rte_free(eth_dev->data->mac_addrs);
234 unregister_irq:
235         otx2_nix_unregister_irqs(eth_dev);
236 mbox_detach:
237         otx2_eth_dev_lf_detach(dev->mbox);
238 otx2_npa_uninit:
239         otx2_npa_lf_fini();
240 otx2_dev_uninit:
241         otx2_dev_fini(pci_dev, dev);
242 error:
243         otx2_err("Failed to init nix eth_dev rc=%d", rc);
244         return rc;
245 }
246
247 static int
248 otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close)
249 {
250         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
251         struct rte_pci_device *pci_dev;
252         int rc;
253
254         /* Nothing to be done for secondary processes */
255         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
256                 return 0;
257
258         rc = nix_lf_free(dev);
259         if (rc)
260                 otx2_err("Failed to free nix lf, rc=%d", rc);
261
262         rc = otx2_npa_lf_fini();
263         if (rc)
264                 otx2_err("Failed to cleanup npa lf, rc=%d", rc);
265
266         rte_free(eth_dev->data->mac_addrs);
267         eth_dev->data->mac_addrs = NULL;
268         dev->drv_inited = false;
269
270         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
271         otx2_nix_unregister_irqs(eth_dev);
272
273         rc = otx2_eth_dev_lf_detach(dev->mbox);
274         if (rc)
275                 otx2_err("Failed to detach resources, rc=%d", rc);
276
277         /* Check if mbox close is needed */
278         if (!mbox_close)
279                 return 0;
280
281         if (otx2_npa_lf_active(dev) || otx2_dev_active_vfs(dev)) {
282                 /* Will be freed later by PMD */
283                 eth_dev->data->dev_private = NULL;
284                 return 0;
285         }
286
287         otx2_dev_fini(pci_dev, dev);
288         return 0;
289 }
290
291 static int
292 nix_remove(struct rte_pci_device *pci_dev)
293 {
294         struct rte_eth_dev *eth_dev;
295         struct otx2_idev_cfg *idev;
296         struct otx2_dev *otx2_dev;
297         int rc;
298
299         eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
300         if (eth_dev) {
301                 /* Cleanup eth dev */
302                 rc = otx2_eth_dev_uninit(eth_dev, true);
303                 if (rc)
304                         return rc;
305
306                 rte_eth_dev_pci_release(eth_dev);
307         }
308
309         /* Nothing to be done for secondary processes */
310         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
311                 return 0;
312
313         /* Check for common resources */
314         idev = otx2_intra_dev_get_cfg();
315         if (!idev || !idev->npa_lf || idev->npa_lf->pci_dev != pci_dev)
316                 return 0;
317
318         otx2_dev = container_of(idev->npa_lf, struct otx2_dev, npalf);
319
320         if (otx2_npa_lf_active(otx2_dev) || otx2_dev_active_vfs(otx2_dev))
321                 goto exit;
322
323         /* Safe to cleanup mbox as no more users */
324         otx2_dev_fini(pci_dev, otx2_dev);
325         rte_free(otx2_dev);
326         return 0;
327
328 exit:
329         otx2_info("%s: common resource in use by other devices", pci_dev->name);
330         return -EAGAIN;
331 }
332
333 static int
334 nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
335 {
336         int rc;
337
338         RTE_SET_USED(pci_drv);
339
340         rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct otx2_eth_dev),
341                                            otx2_eth_dev_init);
342
343         /* On error on secondary, recheck if port exists in primary or
344          * in mid of detach state.
345          */
346         if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
347                 if (!rte_eth_dev_allocated(pci_dev->device.name))
348                         return 0;
349         return rc;
350 }
351
352 static const struct rte_pci_id pci_nix_map[] = {
353         {
354                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_PF)
355         },
356         {
357                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_VF)
358         },
359         {
360                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
361                                PCI_DEVID_OCTEONTX2_RVU_AF_VF)
362         },
363         {
364                 .vendor_id = 0,
365         },
366 };
367
368 static struct rte_pci_driver pci_nix = {
369         .id_table = pci_nix_map,
370         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA |
371                         RTE_PCI_DRV_INTR_LSC,
372         .probe = nix_probe,
373         .remove = nix_remove,
374 };
375
376 RTE_PMD_REGISTER_PCI(net_octeontx2, pci_nix);
377 RTE_PMD_REGISTER_PCI_TABLE(net_octeontx2, pci_nix_map);
378 RTE_PMD_REGISTER_KMOD_DEP(net_octeontx2, "vfio-pci");