crypto/octeontx2: support control ops
[dpdk.git] / drivers / crypto / octeontx2 / otx2_cryptodev_hw_access.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_common.h"
6 #include "otx2_cryptodev.h"
7 #include "otx2_cryptodev_hw_access.h"
8
9 #include "cpt_pmd_logs.h"
10
11 static void
12 otx2_cpt_lf_err_intr_handler(void *param)
13 {
14         uintptr_t base = (uintptr_t)param;
15         uint8_t lf_id;
16         uint64_t intr;
17
18         lf_id = (base >> 12) & 0xFF;
19
20         intr = otx2_read64(base + OTX2_CPT_LF_MISC_INT);
21         if (intr == 0)
22                 return;
23
24         CPT_LOG_ERR("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
25
26         /* Clear interrupt */
27         otx2_write64(intr, base + OTX2_CPT_LF_MISC_INT);
28 }
29
30 static void
31 otx2_cpt_lf_err_intr_unregister(const struct rte_cryptodev *dev,
32                                 uint16_t msix_off, uintptr_t base)
33 {
34         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
35         struct rte_intr_handle *handle = &pci_dev->intr_handle;
36
37         /* Disable error interrupts */
38         otx2_write64(~0ull, base + OTX2_CPT_LF_MISC_INT_ENA_W1C);
39
40         otx2_unregister_irq(handle, otx2_cpt_lf_err_intr_handler, (void *)base,
41                             msix_off);
42 }
43
44 void
45 otx2_cpt_err_intr_unregister(const struct rte_cryptodev *dev)
46 {
47         struct otx2_cpt_vf *vf = dev->data->dev_private;
48         uintptr_t base;
49         uint32_t i;
50
51         for (i = 0; i < vf->nb_queues; i++) {
52                 base = OTX2_CPT_LF_BAR2(vf, i);
53                 otx2_cpt_lf_err_intr_unregister(dev, vf->lf_msixoff[i], base);
54         }
55
56         vf->err_intr_registered = 0;
57 }
58
59 static int
60 otx2_cpt_lf_err_intr_register(const struct rte_cryptodev *dev,
61                              uint16_t msix_off, uintptr_t base)
62 {
63         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
64         struct rte_intr_handle *handle = &pci_dev->intr_handle;
65         int ret;
66
67         /* Disable error interrupts */
68         otx2_write64(~0ull, base + OTX2_CPT_LF_MISC_INT_ENA_W1C);
69
70         /* Register error interrupt handler */
71         ret = otx2_register_irq(handle, otx2_cpt_lf_err_intr_handler,
72                                 (void *)base, msix_off);
73         if (ret)
74                 return ret;
75
76         /* Enable error interrupts */
77         otx2_write64(~0ull, base + OTX2_CPT_LF_MISC_INT_ENA_W1S);
78
79         return 0;
80 }
81
82 int
83 otx2_cpt_err_intr_register(const struct rte_cryptodev *dev)
84 {
85         struct otx2_cpt_vf *vf = dev->data->dev_private;
86         uint32_t i, j, ret;
87         uintptr_t base;
88
89         for (i = 0; i < vf->nb_queues; i++) {
90                 if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
91                         CPT_LOG_ERR("Invalid CPT LF MSI-X offset: 0x%x",
92                                     vf->lf_msixoff[i]);
93                         return -EINVAL;
94                 }
95         }
96
97         for (i = 0; i < vf->nb_queues; i++) {
98                 base = OTX2_CPT_LF_BAR2(vf, i);
99                 ret = otx2_cpt_lf_err_intr_register(dev, vf->lf_msixoff[i],
100                                                    base);
101                 if (ret)
102                         goto intr_unregister;
103         }
104
105         vf->err_intr_registered = 1;
106         return 0;
107
108 intr_unregister:
109         /* Unregister the ones already registered */
110         for (j = 0; j < i; j++) {
111                 base = OTX2_CPT_LF_BAR2(vf, j);
112                 otx2_cpt_lf_err_intr_unregister(dev, vf->lf_msixoff[j], base);
113         }
114
115         /*
116          * Failed to register error interrupt. Not returning error as this would
117          * prevent application from enabling larger number of devs.
118          *
119          * This failure is a known issue because otx2_dev_init() initializes
120          * interrupts based on static values from ATF, and the actual number
121          * of interrupts needed (which is based on LFs) can be determined only
122          * after otx2_dev_init() sets up interrupts which includes mbox
123          * interrupts.
124          */
125         return 0;
126 }