crypto/octeontx2: discover capabilities
[dpdk.git] / drivers / crypto / octeontx2 / otx2_cryptodev_mbox.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2019 Marvell International Ltd.
3  */
4 #include <rte_cryptodev.h>
5 #include <rte_ethdev.h>
6
7 #include "otx2_cryptodev.h"
8 #include "otx2_cryptodev_hw_access.h"
9 #include "otx2_cryptodev_mbox.h"
10 #include "otx2_dev.h"
11 #include "otx2_ethdev.h"
12 #include "otx2_sec_idev.h"
13 #include "otx2_mbox.h"
14
15 #include "cpt_pmd_logs.h"
16
17 int
18 otx2_cpt_hardware_caps_get(const struct rte_cryptodev *dev,
19                               union cpt_eng_caps *hw_caps)
20 {
21         struct otx2_cpt_vf *vf = dev->data->dev_private;
22         struct otx2_dev *otx2_dev = &vf->otx2_dev;
23         struct cpt_caps_rsp_msg *rsp;
24         int ret;
25
26         otx2_mbox_alloc_msg_cpt_caps_get(otx2_dev->mbox);
27
28         ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
29         if (ret)
30                 return -EIO;
31
32         memcpy(hw_caps, rsp->eng_caps,
33                 sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES);
34
35         return 0;
36 }
37
38 int
39 otx2_cpt_available_queues_get(const struct rte_cryptodev *dev,
40                               uint16_t *nb_queues)
41 {
42         struct otx2_cpt_vf *vf = dev->data->dev_private;
43         struct otx2_dev *otx2_dev = &vf->otx2_dev;
44         struct free_rsrcs_rsp *rsp;
45         int ret;
46
47         otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
48
49         ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
50         if (ret)
51                 return -EIO;
52
53         *nb_queues = rsp->cpt;
54         return 0;
55 }
56
57 int
58 otx2_cpt_queues_attach(const struct rte_cryptodev *dev, uint8_t nb_queues)
59 {
60         struct otx2_cpt_vf *vf = dev->data->dev_private;
61         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
62         struct rsrc_attach_req *req;
63
64         /* Ask AF to attach required LFs */
65
66         req = otx2_mbox_alloc_msg_attach_resources(mbox);
67
68         /* 1 LF = 1 queue */
69         req->cptlfs = nb_queues;
70
71         if (otx2_mbox_process(mbox) < 0)
72                 return -EIO;
73
74         /* Update number of attached queues */
75         vf->nb_queues = nb_queues;
76
77         return 0;
78 }
79
80 int
81 otx2_cpt_queues_detach(const struct rte_cryptodev *dev)
82 {
83         struct otx2_cpt_vf *vf = dev->data->dev_private;
84         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
85         struct rsrc_detach_req *req;
86
87         req = otx2_mbox_alloc_msg_detach_resources(mbox);
88         req->cptlfs = true;
89         req->partial = true;
90         if (otx2_mbox_process(mbox) < 0)
91                 return -EIO;
92
93         /* Queues have been detached */
94         vf->nb_queues = 0;
95
96         return 0;
97 }
98
99 int
100 otx2_cpt_msix_offsets_get(const struct rte_cryptodev *dev)
101 {
102         struct otx2_cpt_vf *vf = dev->data->dev_private;
103         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
104         struct msix_offset_rsp *rsp;
105         uint32_t i, ret;
106
107         /* Get CPT MSI-X vector offsets */
108
109         otx2_mbox_alloc_msg_msix_offset(mbox);
110
111         ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
112         if (ret)
113                 return ret;
114
115         for (i = 0; i < vf->nb_queues; i++)
116                 vf->lf_msixoff[i] = rsp->cptlf_msixoff[i];
117
118         return 0;
119 }
120
121 static int
122 otx2_cpt_send_mbox_msg(struct otx2_cpt_vf *vf)
123 {
124         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
125         int ret;
126
127         otx2_mbox_msg_send(mbox, 0);
128
129         ret = otx2_mbox_wait_for_rsp(mbox, 0);
130         if (ret < 0) {
131                 CPT_LOG_ERR("Could not get mailbox response");
132                 return ret;
133         }
134
135         return 0;
136 }
137
138 int
139 otx2_cpt_af_reg_read(const struct rte_cryptodev *dev, uint64_t reg,
140                      uint64_t *val)
141 {
142         struct otx2_cpt_vf *vf = dev->data->dev_private;
143         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
144         struct otx2_mbox_dev *mdev = &mbox->dev[0];
145         struct cpt_rd_wr_reg_msg *msg;
146         int ret, off;
147
148         msg = (struct cpt_rd_wr_reg_msg *)
149                         otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*msg),
150                                                 sizeof(*msg));
151         if (msg == NULL) {
152                 CPT_LOG_ERR("Could not allocate mailbox message");
153                 return -EFAULT;
154         }
155
156         msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
157         msg->hdr.sig = OTX2_MBOX_REQ_SIG;
158         msg->hdr.pcifunc = vf->otx2_dev.pf_func;
159         msg->is_write = 0;
160         msg->reg_offset = reg;
161         msg->ret_val = val;
162
163         ret = otx2_cpt_send_mbox_msg(vf);
164         if (ret < 0)
165                 return ret;
166
167         off = mbox->rx_start +
168                         RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
169         msg = (struct cpt_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
170
171         *val = msg->val;
172
173         return 0;
174 }
175
176 int
177 otx2_cpt_af_reg_write(const struct rte_cryptodev *dev, uint64_t reg,
178                       uint64_t val)
179 {
180         struct otx2_cpt_vf *vf = dev->data->dev_private;
181         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
182         struct cpt_rd_wr_reg_msg *msg;
183
184         msg = (struct cpt_rd_wr_reg_msg *)
185                         otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*msg),
186                                                 sizeof(*msg));
187         if (msg == NULL) {
188                 CPT_LOG_ERR("Could not allocate mailbox message");
189                 return -EFAULT;
190         }
191
192         msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
193         msg->hdr.sig = OTX2_MBOX_REQ_SIG;
194         msg->hdr.pcifunc = vf->otx2_dev.pf_func;
195         msg->is_write = 1;
196         msg->reg_offset = reg;
197         msg->val = val;
198
199         return otx2_cpt_send_mbox_msg(vf);
200 }
201
202 int
203 otx2_cpt_inline_init(const struct rte_cryptodev *dev)
204 {
205         struct otx2_cpt_vf *vf = dev->data->dev_private;
206         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
207         struct cpt_rx_inline_lf_cfg_msg *msg;
208         int ret;
209
210         msg = otx2_mbox_alloc_msg_cpt_rx_inline_lf_cfg(mbox);
211         msg->sso_pf_func = otx2_sso_pf_func_get();
212
213         otx2_mbox_msg_send(mbox, 0);
214         ret = otx2_mbox_process(mbox);
215         if (ret < 0)
216                 return -EIO;
217
218         return 0;
219 }
220
221 int
222 otx2_cpt_qp_ethdev_bind(const struct rte_cryptodev *dev, struct otx2_cpt_qp *qp,
223                         uint16_t port_id)
224 {
225         struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
226         struct otx2_cpt_vf *vf = dev->data->dev_private;
227         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
228         struct cpt_inline_ipsec_cfg_msg *msg;
229         struct otx2_eth_dev *otx2_eth_dev;
230         int ret;
231
232         if (!otx2_eth_dev_is_sec_capable(&rte_eth_devices[port_id]))
233                 return -EINVAL;
234
235         otx2_eth_dev = otx2_eth_pmd_priv(eth_dev);
236
237         msg = otx2_mbox_alloc_msg_cpt_inline_ipsec_cfg(mbox);
238         msg->dir = CPT_INLINE_OUTBOUND;
239         msg->enable = 1;
240         msg->slot = qp->id;
241
242         msg->nix_pf_func = otx2_eth_dev->pf_func;
243
244         otx2_mbox_msg_send(mbox, 0);
245         ret = otx2_mbox_process(mbox);
246         if (ret < 0)
247                 return -EIO;
248
249         return 0;
250 }