]> Git Repo - linux.git/blob - drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / crypto / marvell / octeontx2 / otx2_cptpf_mbox.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2020 Marvell. */
3
4 #include "otx2_cpt_common.h"
5 #include "otx2_cptpf.h"
6 #include "rvu_reg.h"
7
8 /* Fastpath ipsec opcode with inplace processing */
9 #define CPT_INLINE_RX_OPCODE (0x26 | (1 << 6))
10 #define CN10K_CPT_INLINE_RX_OPCODE (0x29 | (1 << 6))
11
12 #define cpt_inline_rx_opcode(pdev)                      \
13 ({                                                      \
14         u8 opcode;                                      \
15         if (is_dev_otx2(pdev))                          \
16                 opcode = CPT_INLINE_RX_OPCODE;          \
17         else                                            \
18                 opcode = CN10K_CPT_INLINE_RX_OPCODE;    \
19         (opcode);                                       \
20 })
21
22 /*
23  * CPT PF driver version, It will be incremented by 1 for every feature
24  * addition in CPT mailbox messages.
25  */
26 #define OTX2_CPT_PF_DRV_VERSION 0x1
27
28 static int forward_to_af(struct otx2_cptpf_dev *cptpf,
29                          struct otx2_cptvf_info *vf,
30                          struct mbox_msghdr *req, int size)
31 {
32         struct mbox_msghdr *msg;
33         int ret;
34
35         mutex_lock(&cptpf->lock);
36         msg = otx2_mbox_alloc_msg(&cptpf->afpf_mbox, 0, size);
37         if (msg == NULL) {
38                 mutex_unlock(&cptpf->lock);
39                 return -ENOMEM;
40         }
41
42         memcpy((uint8_t *)msg + sizeof(struct mbox_msghdr),
43                (uint8_t *)req + sizeof(struct mbox_msghdr), size);
44         msg->id = req->id;
45         msg->pcifunc = req->pcifunc;
46         msg->sig = req->sig;
47         msg->ver = req->ver;
48
49         ret = otx2_cpt_sync_mbox_msg(&cptpf->afpf_mbox);
50         /* Error code -EIO indicate there is a communication failure
51          * to the AF. Rest of the error codes indicate that AF processed
52          * VF messages and set the error codes in response messages
53          * (if any) so simply forward responses to VF.
54          */
55         if (ret == -EIO) {
56                 dev_warn(&cptpf->pdev->dev,
57                          "AF not responding to VF%d messages\n", vf->vf_id);
58                 mutex_unlock(&cptpf->lock);
59                 return ret;
60         }
61         mutex_unlock(&cptpf->lock);
62         return 0;
63 }
64
65 static int handle_msg_get_caps(struct otx2_cptpf_dev *cptpf,
66                                struct otx2_cptvf_info *vf,
67                                struct mbox_msghdr *req)
68 {
69         struct otx2_cpt_caps_rsp *rsp;
70
71         rsp = (struct otx2_cpt_caps_rsp *)
72               otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id,
73                                   sizeof(*rsp));
74         if (!rsp)
75                 return -ENOMEM;
76
77         rsp->hdr.id = MBOX_MSG_GET_CAPS;
78         rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
79         rsp->hdr.pcifunc = req->pcifunc;
80         rsp->cpt_pf_drv_version = OTX2_CPT_PF_DRV_VERSION;
81         rsp->cpt_revision = cptpf->eng_grps.rid;
82         memcpy(&rsp->eng_caps, &cptpf->eng_caps, sizeof(rsp->eng_caps));
83
84         return 0;
85 }
86
87 static int handle_msg_get_eng_grp_num(struct otx2_cptpf_dev *cptpf,
88                                       struct otx2_cptvf_info *vf,
89                                       struct mbox_msghdr *req)
90 {
91         struct otx2_cpt_egrp_num_msg *grp_req;
92         struct otx2_cpt_egrp_num_rsp *rsp;
93
94         grp_req = (struct otx2_cpt_egrp_num_msg *)req;
95         rsp = (struct otx2_cpt_egrp_num_rsp *)
96                otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
97         if (!rsp)
98                 return -ENOMEM;
99
100         rsp->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
101         rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
102         rsp->hdr.pcifunc = req->pcifunc;
103         rsp->eng_type = grp_req->eng_type;
104         rsp->eng_grp_num = otx2_cpt_get_eng_grp(&cptpf->eng_grps,
105                                                 grp_req->eng_type);
106
107         return 0;
108 }
109
110 static int handle_msg_kvf_limits(struct otx2_cptpf_dev *cptpf,
111                                  struct otx2_cptvf_info *vf,
112                                  struct mbox_msghdr *req)
113 {
114         struct otx2_cpt_kvf_limits_rsp *rsp;
115
116         rsp = (struct otx2_cpt_kvf_limits_rsp *)
117               otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
118         if (!rsp)
119                 return -ENOMEM;
120
121         rsp->hdr.id = MBOX_MSG_GET_KVF_LIMITS;
122         rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
123         rsp->hdr.pcifunc = req->pcifunc;
124         rsp->kvf_limits = cptpf->kvf_limits;
125
126         return 0;
127 }
128
129 static int send_inline_ipsec_inbound_msg(struct otx2_cptpf_dev *cptpf,
130                                          int sso_pf_func, u8 slot)
131 {
132         struct cpt_inline_ipsec_cfg_msg *req;
133         struct pci_dev *pdev = cptpf->pdev;
134
135         req = (struct cpt_inline_ipsec_cfg_msg *)
136               otx2_mbox_alloc_msg_rsp(&cptpf->afpf_mbox, 0,
137                                       sizeof(*req), sizeof(struct msg_rsp));
138         if (req == NULL) {
139                 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
140                 return -EFAULT;
141         }
142         memset(req, 0, sizeof(*req));
143         req->hdr.id = MBOX_MSG_CPT_INLINE_IPSEC_CFG;
144         req->hdr.sig = OTX2_MBOX_REQ_SIG;
145         req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
146         req->dir = CPT_INLINE_INBOUND;
147         req->slot = slot;
148         req->sso_pf_func_ovrd = cptpf->sso_pf_func_ovrd;
149         req->sso_pf_func = sso_pf_func;
150         req->enable = 1;
151
152         return otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
153 }
154
155 static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp,
156                                   struct otx2_cpt_rx_inline_lf_cfg *req)
157 {
158         struct nix_inline_ipsec_cfg *nix_req;
159         struct pci_dev *pdev = cptpf->pdev;
160         int ret;
161
162         nix_req = (struct nix_inline_ipsec_cfg *)
163                    otx2_mbox_alloc_msg_rsp(&cptpf->afpf_mbox, 0,
164                                            sizeof(*nix_req),
165                                            sizeof(struct msg_rsp));
166         if (nix_req == NULL) {
167                 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
168                 return -EFAULT;
169         }
170         memset(nix_req, 0, sizeof(*nix_req));
171         nix_req->hdr.id = MBOX_MSG_NIX_INLINE_IPSEC_CFG;
172         nix_req->hdr.sig = OTX2_MBOX_REQ_SIG;
173         nix_req->enable = 1;
174         nix_req->credit_th = req->credit_th;
175         nix_req->bpid = req->bpid;
176         if (!req->credit || req->credit > OTX2_CPT_INST_QLEN_MSGS)
177                 nix_req->cpt_credit = OTX2_CPT_INST_QLEN_MSGS - 1;
178         else
179                 nix_req->cpt_credit = req->credit - 1;
180         nix_req->gen_cfg.egrp = egrp;
181         if (req->opcode)
182                 nix_req->gen_cfg.opcode = req->opcode;
183         else
184                 nix_req->gen_cfg.opcode = cpt_inline_rx_opcode(pdev);
185         nix_req->gen_cfg.param1 = req->param1;
186         nix_req->gen_cfg.param2 = req->param2;
187         nix_req->inst_qsel.cpt_pf_func = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
188         nix_req->inst_qsel.cpt_slot = 0;
189         ret = otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
190         if (ret)
191                 return ret;
192
193         if (cptpf->has_cpt1) {
194                 ret = send_inline_ipsec_inbound_msg(cptpf, req->sso_pf_func, 1);
195                 if (ret)
196                         return ret;
197         }
198
199         return send_inline_ipsec_inbound_msg(cptpf, req->sso_pf_func, 0);
200 }
201
202 int
203 otx2_inline_cptlf_setup(struct otx2_cptpf_dev *cptpf,
204                         struct otx2_cptlfs_info *lfs, u8 egrp, int num_lfs)
205 {
206         int ret;
207
208         ret = otx2_cptlf_init(lfs, 1 << egrp, OTX2_CPT_QUEUE_HI_PRIO, 1);
209         if (ret) {
210                 dev_err(&cptpf->pdev->dev,
211                         "LF configuration failed for RX inline ipsec.\n");
212                 return ret;
213         }
214
215         /* Get msix offsets for attached LFs */
216         ret = otx2_cpt_msix_offset_msg(lfs);
217         if (ret)
218                 goto cleanup_lf;
219
220         /* Register for CPT LF Misc interrupts */
221         ret = otx2_cptlf_register_misc_interrupts(lfs);
222         if (ret)
223                 goto free_irq;
224
225         return 0;
226 free_irq:
227         otx2_cptlf_unregister_misc_interrupts(lfs);
228 cleanup_lf:
229         otx2_cptlf_shutdown(lfs);
230         return ret;
231 }
232
233 void
234 otx2_inline_cptlf_cleanup(struct otx2_cptlfs_info *lfs)
235 {
236         /* Unregister misc interrupt */
237         otx2_cptlf_unregister_misc_interrupts(lfs);
238
239         /* Cleanup LFs */
240         otx2_cptlf_shutdown(lfs);
241 }
242
243 static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
244                                              struct mbox_msghdr *req)
245 {
246         struct otx2_cpt_rx_inline_lf_cfg *cfg_req;
247         int num_lfs = 1, ret;
248         u8 egrp;
249
250         cfg_req = (struct otx2_cpt_rx_inline_lf_cfg *)req;
251         if (cptpf->lfs.lfs_num) {
252                 dev_err(&cptpf->pdev->dev,
253                         "LF is already configured for RX inline ipsec.\n");
254                 return -EEXIST;
255         }
256         /*
257          * Allow LFs to execute requests destined to only grp IE_TYPES and
258          * set queue priority of each LF to high
259          */
260         egrp = otx2_cpt_get_eng_grp(&cptpf->eng_grps, OTX2_CPT_IE_TYPES);
261         if (egrp == OTX2_CPT_INVALID_CRYPTO_ENG_GRP) {
262                 dev_err(&cptpf->pdev->dev,
263                         "Engine group for inline ipsec is not available\n");
264                 return -ENOENT;
265         }
266
267         otx2_cptlf_set_dev_info(&cptpf->lfs, cptpf->pdev, cptpf->reg_base,
268                                 &cptpf->afpf_mbox, BLKADDR_CPT0);
269         cptpf->lfs.global_slot = 0;
270         cptpf->lfs.ctx_ilen_ovrd = cfg_req->ctx_ilen_valid;
271         cptpf->lfs.ctx_ilen = cfg_req->ctx_ilen;
272
273         ret = otx2_inline_cptlf_setup(cptpf, &cptpf->lfs, egrp, num_lfs);
274         if (ret) {
275                 dev_err(&cptpf->pdev->dev, "Inline-Ipsec CPT0 LF setup failed.\n");
276                 return ret;
277         }
278
279         if (cptpf->has_cpt1) {
280                 cptpf->rsrc_req_blkaddr = BLKADDR_CPT1;
281                 otx2_cptlf_set_dev_info(&cptpf->cpt1_lfs, cptpf->pdev,
282                                         cptpf->reg_base, &cptpf->afpf_mbox,
283                                         BLKADDR_CPT1);
284                 cptpf->cpt1_lfs.global_slot = num_lfs;
285                 cptpf->cpt1_lfs.ctx_ilen_ovrd = cfg_req->ctx_ilen_valid;
286                 cptpf->cpt1_lfs.ctx_ilen = cfg_req->ctx_ilen;
287                 ret = otx2_inline_cptlf_setup(cptpf, &cptpf->cpt1_lfs, egrp,
288                                               num_lfs);
289                 if (ret) {
290                         dev_err(&cptpf->pdev->dev, "Inline CPT1 LF setup failed.\n");
291                         goto lf_cleanup;
292                 }
293                 cptpf->rsrc_req_blkaddr = 0;
294         }
295
296         ret = rx_inline_ipsec_lf_cfg(cptpf, egrp, cfg_req);
297         if (ret)
298                 goto lf1_cleanup;
299
300         return 0;
301
302 lf1_cleanup:
303         otx2_inline_cptlf_cleanup(&cptpf->cpt1_lfs);
304 lf_cleanup:
305         otx2_inline_cptlf_cleanup(&cptpf->lfs);
306         return ret;
307 }
308
309 static int cptpf_handle_vf_req(struct otx2_cptpf_dev *cptpf,
310                                struct otx2_cptvf_info *vf,
311                                struct mbox_msghdr *req, int size)
312 {
313         int err = 0;
314
315         /* Check if msg is valid, if not reply with an invalid msg */
316         if (req->sig != OTX2_MBOX_REQ_SIG)
317                 goto inval_msg;
318
319         switch (req->id) {
320         case MBOX_MSG_GET_ENG_GRP_NUM:
321                 err = handle_msg_get_eng_grp_num(cptpf, vf, req);
322                 break;
323         case MBOX_MSG_GET_CAPS:
324                 err = handle_msg_get_caps(cptpf, vf, req);
325                 break;
326         case MBOX_MSG_GET_KVF_LIMITS:
327                 err = handle_msg_kvf_limits(cptpf, vf, req);
328                 break;
329         case MBOX_MSG_RX_INLINE_IPSEC_LF_CFG:
330                 err = handle_msg_rx_inline_ipsec_lf_cfg(cptpf, req);
331                 break;
332
333         default:
334                 err = forward_to_af(cptpf, vf, req, size);
335                 break;
336         }
337         return err;
338
339 inval_msg:
340         otx2_reply_invalid_msg(&cptpf->vfpf_mbox, vf->vf_id, 0, req->id);
341         otx2_mbox_msg_send(&cptpf->vfpf_mbox, vf->vf_id);
342         return err;
343 }
344
345 irqreturn_t otx2_cptpf_vfpf_mbox_intr(int __always_unused irq, void *arg)
346 {
347         struct otx2_cptpf_dev *cptpf = arg;
348         struct otx2_cptvf_info *vf;
349         int i, vf_idx;
350         u64 intr;
351
352         /*
353          * Check which VF has raised an interrupt and schedule
354          * corresponding work queue to process the messages
355          */
356         for (i = 0; i < 2; i++) {
357                 /* Read the interrupt bits */
358                 intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
359                                        RVU_PF_VFPF_MBOX_INTX(i));
360
361                 for (vf_idx = i * 64; vf_idx < cptpf->enabled_vfs; vf_idx++) {
362                         vf = &cptpf->vf[vf_idx];
363                         if (intr & (1ULL << vf->intr_idx)) {
364                                 queue_work(cptpf->vfpf_mbox_wq,
365                                            &vf->vfpf_mbox_work);
366                                 /* Clear the interrupt */
367                                 otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM,
368                                                  0, RVU_PF_VFPF_MBOX_INTX(i),
369                                                  BIT_ULL(vf->intr_idx));
370                         }
371                 }
372         }
373         return IRQ_HANDLED;
374 }
375
376 void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
377 {
378         struct otx2_cptpf_dev *cptpf;
379         struct otx2_cptvf_info *vf;
380         struct otx2_mbox_dev *mdev;
381         struct mbox_hdr *req_hdr;
382         struct mbox_msghdr *msg;
383         struct otx2_mbox *mbox;
384         int offset, i, err;
385
386         vf = container_of(work, struct otx2_cptvf_info, vfpf_mbox_work);
387         cptpf = vf->cptpf;
388         mbox = &cptpf->vfpf_mbox;
389         /* sync with mbox memory region */
390         smp_rmb();
391         mdev = &mbox->dev[vf->vf_id];
392         /* Process received mbox messages */
393         req_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
394         offset = mbox->rx_start + ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
395
396         for (i = 0; i < req_hdr->num_msgs; i++) {
397                 msg = (struct mbox_msghdr *)(mdev->mbase + offset);
398
399                 /* Set which VF sent this message based on mbox IRQ */
400                 msg->pcifunc = ((u16)cptpf->pf_id << RVU_PFVF_PF_SHIFT) |
401                                 ((vf->vf_id + 1) & RVU_PFVF_FUNC_MASK);
402
403                 err = cptpf_handle_vf_req(cptpf, vf, msg,
404                                           msg->next_msgoff - offset);
405                 /*
406                  * Behave as the AF, drop the msg if there is
407                  * no memory, timeout handling also goes here
408                  */
409                 if (err == -ENOMEM || err == -EIO)
410                         break;
411                 offset = msg->next_msgoff;
412                 /* Write barrier required for VF responses which are handled by
413                  * PF driver and not forwarded to AF.
414                  */
415                 smp_wmb();
416         }
417         /* Send mbox responses to VF */
418         if (mdev->num_msgs)
419                 otx2_mbox_msg_send(mbox, vf->vf_id);
420 }
421
422 irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
423 {
424         struct otx2_cptpf_dev *cptpf = arg;
425         struct otx2_mbox_dev *mdev;
426         struct otx2_mbox *mbox;
427         struct mbox_hdr *hdr;
428         u64 intr;
429
430         /* Read the interrupt bits */
431         intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);
432
433         if (intr & 0x1ULL) {
434                 mbox = &cptpf->afpf_mbox;
435                 mdev = &mbox->dev[0];
436                 hdr = mdev->mbase + mbox->rx_start;
437                 if (hdr->num_msgs)
438                         /* Schedule work queue function to process the MBOX request */
439                         queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
440
441                 mbox = &cptpf->afpf_mbox_up;
442                 mdev = &mbox->dev[0];
443                 hdr = mdev->mbase + mbox->rx_start;
444                 if (hdr->num_msgs)
445                         /* Schedule work queue function to process the MBOX request */
446                         queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_up_work);
447                 /* Clear and ack the interrupt */
448                 otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
449                                  0x1ULL);
450         }
451         return IRQ_HANDLED;
452 }
453
454 static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
455                                   struct mbox_msghdr *msg)
456 {
457         struct otx2_cptlfs_info *lfs = &cptpf->lfs;
458         struct device *dev = &cptpf->pdev->dev;
459         struct cpt_rd_wr_reg_msg *rsp_rd_wr;
460         struct msix_offset_rsp *rsp_msix;
461         int i;
462
463         if (msg->id >= MBOX_MSG_MAX) {
464                 dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
465                 return;
466         }
467         if (msg->sig != OTX2_MBOX_RSP_SIG) {
468                 dev_err(dev, "MBOX msg with wrong signature %x, ID %d\n",
469                         msg->sig, msg->id);
470                 return;
471         }
472         if (cptpf->rsrc_req_blkaddr == BLKADDR_CPT1)
473                 lfs = &cptpf->cpt1_lfs;
474
475         switch (msg->id) {
476         case MBOX_MSG_READY:
477                 cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
478                                 RVU_PFVF_PF_MASK;
479                 break;
480         case MBOX_MSG_MSIX_OFFSET:
481                 rsp_msix = (struct msix_offset_rsp *) msg;
482                 for (i = 0; i < rsp_msix->cptlfs; i++)
483                         lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];
484
485                 for (i = 0; i < rsp_msix->cpt1_lfs; i++)
486                         lfs->lf[i].msix_offset = rsp_msix->cpt1_lf_msixoff[i];
487                 break;
488         case MBOX_MSG_CPT_RD_WR_REGISTER:
489                 rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg;
490                 if (msg->rc) {
491                         dev_err(dev, "Reg %llx rd/wr(%d) failed %d\n",
492                                 rsp_rd_wr->reg_offset, rsp_rd_wr->is_write,
493                                 msg->rc);
494                         return;
495                 }
496                 if (!rsp_rd_wr->is_write)
497                         *rsp_rd_wr->ret_val = rsp_rd_wr->val;
498                 break;
499         case MBOX_MSG_ATTACH_RESOURCES:
500                 if (!msg->rc)
501                         lfs->are_lfs_attached = 1;
502                 break;
503         case MBOX_MSG_DETACH_RESOURCES:
504                 if (!msg->rc)
505                         lfs->are_lfs_attached = 0;
506                 break;
507         case MBOX_MSG_CPT_INLINE_IPSEC_CFG:
508         case MBOX_MSG_NIX_INLINE_IPSEC_CFG:
509         case MBOX_MSG_CPT_LF_RESET:
510                 break;
511
512         default:
513                 dev_err(dev,
514                         "Unsupported msg %d received.\n", msg->id);
515                 break;
516         }
517 }
518
519 static void forward_to_vf(struct otx2_cptpf_dev *cptpf, struct mbox_msghdr *msg,
520                           int vf_id, int size)
521 {
522         struct otx2_mbox *vfpf_mbox;
523         struct mbox_msghdr *fwd;
524
525         if (msg->id >= MBOX_MSG_MAX) {
526                 dev_err(&cptpf->pdev->dev,
527                         "MBOX msg with unknown ID %d\n", msg->id);
528                 return;
529         }
530         if (msg->sig != OTX2_MBOX_RSP_SIG) {
531                 dev_err(&cptpf->pdev->dev,
532                         "MBOX msg with wrong signature %x, ID %d\n",
533                         msg->sig, msg->id);
534                 return;
535         }
536         vfpf_mbox = &cptpf->vfpf_mbox;
537         vf_id--;
538         if (vf_id >= cptpf->enabled_vfs) {
539                 dev_err(&cptpf->pdev->dev,
540                         "MBOX msg to unknown VF: %d >= %d\n",
541                         vf_id, cptpf->enabled_vfs);
542                 return;
543         }
544         if (msg->id == MBOX_MSG_VF_FLR)
545                 return;
546
547         fwd = otx2_mbox_alloc_msg(vfpf_mbox, vf_id, size);
548         if (!fwd) {
549                 dev_err(&cptpf->pdev->dev,
550                         "Forwarding to VF%d failed.\n", vf_id);
551                 return;
552         }
553         memcpy((uint8_t *)fwd + sizeof(struct mbox_msghdr),
554                 (uint8_t *)msg + sizeof(struct mbox_msghdr), size);
555         fwd->id = msg->id;
556         fwd->pcifunc = msg->pcifunc;
557         fwd->sig = msg->sig;
558         fwd->ver = msg->ver;
559         fwd->rc = msg->rc;
560 }
561
562 /* Handle mailbox messages received from AF */
563 void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
564 {
565         struct otx2_cptpf_dev *cptpf;
566         struct otx2_mbox *afpf_mbox;
567         struct otx2_mbox_dev *mdev;
568         struct mbox_hdr *rsp_hdr;
569         struct mbox_msghdr *msg;
570         int offset, vf_id, i;
571
572         cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_work);
573         afpf_mbox = &cptpf->afpf_mbox;
574         mdev = &afpf_mbox->dev[0];
575         /* Sync mbox data into memory */
576         smp_wmb();
577
578         rsp_hdr = (struct mbox_hdr *)(mdev->mbase + afpf_mbox->rx_start);
579         offset = ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
580
581         for (i = 0; i < rsp_hdr->num_msgs; i++) {
582                 msg = (struct mbox_msghdr *)(mdev->mbase + afpf_mbox->rx_start +
583                                              offset);
584                 vf_id = (msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) &
585                          RVU_PFVF_FUNC_MASK;
586                 if (vf_id > 0)
587                         forward_to_vf(cptpf, msg, vf_id,
588                                       msg->next_msgoff - offset);
589                 else
590                         process_afpf_mbox_msg(cptpf, msg);
591
592                 offset = msg->next_msgoff;
593                 /* Sync VF response ready to be sent */
594                 smp_wmb();
595                 mdev->msgs_acked++;
596         }
597         otx2_mbox_reset(afpf_mbox, 0);
598 }
599
600 static void handle_msg_cpt_inst_lmtst(struct otx2_cptpf_dev *cptpf,
601                                       struct mbox_msghdr *msg)
602 {
603         struct cpt_inst_lmtst_req *req = (struct cpt_inst_lmtst_req *)msg;
604         struct otx2_cptlfs_info *lfs = &cptpf->lfs;
605         struct msg_rsp *rsp;
606
607         if (cptpf->lfs.lfs_num)
608                 lfs->ops->send_cmd((union otx2_cpt_inst_s *)req->inst, 1,
609                                    &lfs->lf[0]);
610
611         rsp = (struct msg_rsp *)otx2_mbox_alloc_msg(&cptpf->afpf_mbox_up, 0,
612                                                     sizeof(*rsp));
613         if (!rsp)
614                 return;
615
616         rsp->hdr.id = msg->id;
617         rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
618         rsp->hdr.pcifunc = 0;
619         rsp->hdr.rc = 0;
620 }
621
622 static void process_afpf_mbox_up_msg(struct otx2_cptpf_dev *cptpf,
623                                      struct mbox_msghdr *msg)
624 {
625         if (msg->id >= MBOX_MSG_MAX) {
626                 dev_err(&cptpf->pdev->dev,
627                         "MBOX msg with unknown ID %d\n", msg->id);
628                 return;
629         }
630
631         switch (msg->id) {
632         case MBOX_MSG_CPT_INST_LMTST:
633                 handle_msg_cpt_inst_lmtst(cptpf, msg);
634                 break;
635         default:
636                 otx2_reply_invalid_msg(&cptpf->afpf_mbox_up, 0, 0, msg->id);
637         }
638 }
639
640 void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work)
641 {
642         struct otx2_cptpf_dev *cptpf;
643         struct otx2_mbox_dev *mdev;
644         struct mbox_hdr *rsp_hdr;
645         struct mbox_msghdr *msg;
646         struct otx2_mbox *mbox;
647         int offset, i;
648
649         cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_up_work);
650         mbox = &cptpf->afpf_mbox_up;
651         mdev = &mbox->dev[0];
652         /* Sync mbox data into memory */
653         smp_wmb();
654
655         rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
656         offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
657
658         for (i = 0; i < rsp_hdr->num_msgs; i++) {
659                 msg = (struct mbox_msghdr *)(mdev->mbase + offset);
660
661                 process_afpf_mbox_up_msg(cptpf, msg);
662
663                 offset = mbox->rx_start + msg->next_msgoff;
664         }
665         otx2_mbox_msg_send(mbox, 0);
666 }
This page took 0.07438 seconds and 4 git commands to generate.