net/hns3: support flow control autoneg for copper port
[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         if (rsp->cpt_pf_drv_version != OTX2_CPT_PMD_VERSION) {
33                 otx2_err("Incompatible CPT PMD version"
34                          "(Kernel: 0x%04x DPDK: 0x%04x)",
35                           rsp->cpt_pf_drv_version, OTX2_CPT_PMD_VERSION);
36                 return -EPIPE;
37         }
38
39         vf->cpt_revision = rsp->cpt_revision;
40         memcpy(hw_caps, rsp->eng_caps,
41                 sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES);
42
43         return 0;
44 }
45
46 int
47 otx2_cpt_available_queues_get(const struct rte_cryptodev *dev,
48                               uint16_t *nb_queues)
49 {
50         struct otx2_cpt_vf *vf = dev->data->dev_private;
51         struct otx2_dev *otx2_dev = &vf->otx2_dev;
52         struct free_rsrcs_rsp *rsp;
53         int ret;
54
55         otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
56
57         ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
58         if (ret)
59                 return -EIO;
60
61         *nb_queues = rsp->cpt + rsp->cpt1;
62         return 0;
63 }
64
65 int
66 otx2_cpt_queues_attach(const struct rte_cryptodev *dev, uint8_t nb_queues)
67 {
68         struct otx2_cpt_vf *vf = dev->data->dev_private;
69         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
70         int blkaddr[OTX2_CPT_MAX_BLKS];
71         struct rsrc_attach_req *req;
72         int blknum = 0;
73         int i, ret;
74
75         blkaddr[0] = RVU_BLOCK_ADDR_CPT0;
76         blkaddr[1] = RVU_BLOCK_ADDR_CPT1;
77
78         /* Ask AF to attach required LFs */
79
80         req = otx2_mbox_alloc_msg_attach_resources(mbox);
81
82         if ((vf->cpt_revision == OTX2_CPT_REVISION_ID_3) &&
83             (vf->otx2_dev.pf_func & 0x1))
84                 blknum = (blknum + 1) % OTX2_CPT_MAX_BLKS;
85
86         /* 1 LF = 1 queue */
87         req->cptlfs = nb_queues;
88         req->cpt_blkaddr = blkaddr[blknum];
89
90         ret = otx2_mbox_process(mbox);
91         if (ret == -ENOSPC) {
92                 if (vf->cpt_revision == OTX2_CPT_REVISION_ID_3) {
93                         blknum = (blknum + 1) % OTX2_CPT_MAX_BLKS;
94                         req->cpt_blkaddr = blkaddr[blknum];
95                         if (otx2_mbox_process(mbox) < 0)
96                                 return -EIO;
97                 } else {
98                         return -EIO;
99                 }
100         } else if (ret < 0) {
101                 return -EIO;
102         }
103
104         /* Update number of attached queues */
105         vf->nb_queues = nb_queues;
106         for (i = 0; i < nb_queues; i++)
107                 vf->lf_blkaddr[i] = req->cpt_blkaddr;
108
109         return 0;
110 }
111
112 int
113 otx2_cpt_queues_detach(const struct rte_cryptodev *dev)
114 {
115         struct otx2_cpt_vf *vf = dev->data->dev_private;
116         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
117         struct rsrc_detach_req *req;
118
119         req = otx2_mbox_alloc_msg_detach_resources(mbox);
120         req->cptlfs = true;
121         req->partial = true;
122         if (otx2_mbox_process(mbox) < 0)
123                 return -EIO;
124
125         /* Queues have been detached */
126         vf->nb_queues = 0;
127
128         return 0;
129 }
130
131 int
132 otx2_cpt_msix_offsets_get(const struct rte_cryptodev *dev)
133 {
134         struct otx2_cpt_vf *vf = dev->data->dev_private;
135         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
136         struct msix_offset_rsp *rsp;
137         uint32_t i, ret;
138
139         /* Get CPT MSI-X vector offsets */
140
141         otx2_mbox_alloc_msg_msix_offset(mbox);
142
143         ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
144         if (ret)
145                 return ret;
146
147         for (i = 0; i < vf->nb_queues; i++)
148                 vf->lf_msixoff[i] = (vf->lf_blkaddr[i] == RVU_BLOCK_ADDR_CPT1) ?
149                         rsp->cpt1_lf_msixoff[i] : rsp->cptlf_msixoff[i];
150
151         return 0;
152 }
153
154 static int
155 otx2_cpt_send_mbox_msg(struct otx2_cpt_vf *vf)
156 {
157         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
158         int ret;
159
160         otx2_mbox_msg_send(mbox, 0);
161
162         ret = otx2_mbox_wait_for_rsp(mbox, 0);
163         if (ret < 0) {
164                 CPT_LOG_ERR("Could not get mailbox response");
165                 return ret;
166         }
167
168         return 0;
169 }
170
171 int
172 otx2_cpt_af_reg_read(const struct rte_cryptodev *dev, uint64_t reg,
173                      uint8_t blkaddr, uint64_t *val)
174 {
175         struct otx2_cpt_vf *vf = dev->data->dev_private;
176         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
177         struct otx2_mbox_dev *mdev = &mbox->dev[0];
178         struct cpt_rd_wr_reg_msg *msg;
179         int ret, off;
180
181         msg = (struct cpt_rd_wr_reg_msg *)
182                         otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*msg),
183                                                 sizeof(*msg));
184         if (msg == NULL) {
185                 CPT_LOG_ERR("Could not allocate mailbox message");
186                 return -EFAULT;
187         }
188
189         msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
190         msg->hdr.sig = OTX2_MBOX_REQ_SIG;
191         msg->hdr.pcifunc = vf->otx2_dev.pf_func;
192         msg->is_write = 0;
193         msg->reg_offset = reg;
194         msg->ret_val = val;
195         msg->blkaddr = blkaddr;
196
197         ret = otx2_cpt_send_mbox_msg(vf);
198         if (ret < 0)
199                 return ret;
200
201         off = mbox->rx_start +
202                         RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
203         msg = (struct cpt_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
204
205         *val = msg->val;
206
207         return 0;
208 }
209
210 int
211 otx2_cpt_af_reg_write(const struct rte_cryptodev *dev, uint64_t reg,
212                       uint8_t blkaddr, uint64_t val)
213 {
214         struct otx2_cpt_vf *vf = dev->data->dev_private;
215         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
216         struct cpt_rd_wr_reg_msg *msg;
217
218         msg = (struct cpt_rd_wr_reg_msg *)
219                         otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*msg),
220                                                 sizeof(*msg));
221         if (msg == NULL) {
222                 CPT_LOG_ERR("Could not allocate mailbox message");
223                 return -EFAULT;
224         }
225
226         msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
227         msg->hdr.sig = OTX2_MBOX_REQ_SIG;
228         msg->hdr.pcifunc = vf->otx2_dev.pf_func;
229         msg->is_write = 1;
230         msg->reg_offset = reg;
231         msg->val = val;
232         msg->blkaddr = blkaddr;
233
234         return otx2_cpt_send_mbox_msg(vf);
235 }
236
237 int
238 otx2_cpt_inline_init(const struct rte_cryptodev *dev)
239 {
240         struct otx2_cpt_vf *vf = dev->data->dev_private;
241         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
242         struct cpt_rx_inline_lf_cfg_msg *msg;
243         int ret;
244
245         msg = otx2_mbox_alloc_msg_cpt_rx_inline_lf_cfg(mbox);
246         msg->sso_pf_func = otx2_sso_pf_func_get();
247
248         otx2_mbox_msg_send(mbox, 0);
249         ret = otx2_mbox_process(mbox);
250         if (ret < 0)
251                 return -EIO;
252
253         return 0;
254 }
255
256 int
257 otx2_cpt_qp_ethdev_bind(const struct rte_cryptodev *dev, struct otx2_cpt_qp *qp,
258                         uint16_t port_id)
259 {
260         struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
261         struct otx2_cpt_vf *vf = dev->data->dev_private;
262         struct otx2_mbox *mbox = vf->otx2_dev.mbox;
263         struct cpt_inline_ipsec_cfg_msg *msg;
264         struct otx2_eth_dev *otx2_eth_dev;
265         int ret;
266
267         if (!otx2_eth_dev_is_sec_capable(&rte_eth_devices[port_id]))
268                 return -EINVAL;
269
270         otx2_eth_dev = otx2_eth_pmd_priv(eth_dev);
271
272         msg = otx2_mbox_alloc_msg_cpt_inline_ipsec_cfg(mbox);
273         msg->dir = CPT_INLINE_OUTBOUND;
274         msg->enable = 1;
275         msg->slot = qp->id;
276
277         msg->nix_pf_func = otx2_eth_dev->pf_func;
278
279         otx2_mbox_msg_send(mbox, 0);
280         ret = otx2_mbox_process(mbox);
281         if (ret < 0)
282                 return -EIO;
283
284         return 0;
285 }