33fed93c413e1b9560ed497d05c46629ea1b7700
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev_irq.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <inttypes.h>
6
7 #include <rte_bus_pci.h>
8
9 #include "otx2_ethdev.h"
10
11 static void
12 nix_lf_err_irq(void *param)
13 {
14         struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
15         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
16         uint64_t intr;
17
18         intr = otx2_read64(dev->base + NIX_LF_ERR_INT);
19         if (intr == 0)
20                 return;
21
22         otx2_err("Err_intr=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf);
23
24         /* Clear interrupt */
25         otx2_write64(intr, dev->base + NIX_LF_ERR_INT);
26 }
27
28 static int
29 nix_lf_register_err_irq(struct rte_eth_dev *eth_dev)
30 {
31         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
32         struct rte_intr_handle *handle = &pci_dev->intr_handle;
33         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
34         int rc, vec;
35
36         vec = dev->nix_msixoff + NIX_LF_INT_VEC_ERR_INT;
37
38         /* Clear err interrupt */
39         otx2_write64(~0ull, dev->base + NIX_LF_ERR_INT_ENA_W1C);
40         /* Set used interrupt vectors */
41         rc = otx2_register_irq(handle, nix_lf_err_irq, eth_dev, vec);
42         /* Enable all dev interrupt except for RQ_DISABLED */
43         otx2_write64(~BIT_ULL(11), dev->base + NIX_LF_ERR_INT_ENA_W1S);
44
45         return rc;
46 }
47
48 static void
49 nix_lf_unregister_err_irq(struct rte_eth_dev *eth_dev)
50 {
51         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
52         struct rte_intr_handle *handle = &pci_dev->intr_handle;
53         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
54         int vec;
55
56         vec = dev->nix_msixoff + NIX_LF_INT_VEC_ERR_INT;
57
58         /* Clear err interrupt */
59         otx2_write64(~0ull, dev->base + NIX_LF_ERR_INT_ENA_W1C);
60         otx2_unregister_irq(handle, nix_lf_err_irq, eth_dev, vec);
61 }
62
63 static void
64 nix_lf_ras_irq(void *param)
65 {
66         struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
67         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
68         uint64_t intr;
69
70         intr = otx2_read64(dev->base + NIX_LF_RAS);
71         if (intr == 0)
72                 return;
73
74         otx2_err("Ras_intr=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf);
75
76         /* Clear interrupt */
77         otx2_write64(intr, dev->base + NIX_LF_RAS);
78 }
79
80 static int
81 nix_lf_register_ras_irq(struct rte_eth_dev *eth_dev)
82 {
83         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
84         struct rte_intr_handle *handle = &pci_dev->intr_handle;
85         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
86         int rc, vec;
87
88         vec = dev->nix_msixoff + NIX_LF_INT_VEC_POISON;
89
90         /* Clear err interrupt */
91         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1C);
92         /* Set used interrupt vectors */
93         rc = otx2_register_irq(handle, nix_lf_ras_irq, eth_dev, vec);
94         /* Enable dev interrupt */
95         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1S);
96
97         return rc;
98 }
99
100 static void
101 nix_lf_unregister_ras_irq(struct rte_eth_dev *eth_dev)
102 {
103         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
104         struct rte_intr_handle *handle = &pci_dev->intr_handle;
105         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
106         int vec;
107
108         vec = dev->nix_msixoff + NIX_LF_INT_VEC_POISON;
109
110         /* Clear err interrupt */
111         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1C);
112         otx2_unregister_irq(handle, nix_lf_ras_irq, eth_dev, vec);
113 }
114
115 int
116 otx2_nix_register_irqs(struct rte_eth_dev *eth_dev)
117 {
118         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
119         int rc;
120
121         if (dev->nix_msixoff == MSIX_VECTOR_INVALID) {
122                 otx2_err("Invalid NIXLF MSIX vector offset vector: 0x%x",
123                          dev->nix_msixoff);
124                 return -EINVAL;
125         }
126
127         /* Register lf err interrupt */
128         rc = nix_lf_register_err_irq(eth_dev);
129         /* Register RAS interrupt */
130         rc |= nix_lf_register_ras_irq(eth_dev);
131
132         return rc;
133 }
134
135 void
136 otx2_nix_unregister_irqs(struct rte_eth_dev *eth_dev)
137 {
138         nix_lf_unregister_err_irq(eth_dev);
139         nix_lf_unregister_ras_irq(eth_dev);
140 }