Merge tag 'for-5.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[sfrench/cifs-2.6.git] / drivers / crypto / marvell / octeontx2 / otx2_cptvf_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_cptvf.h"
6 #include <rvu_reg.h>
7
8 irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg)
9 {
10         struct otx2_cptvf_dev *cptvf = arg;
11         u64 intr;
12
13         /* Read the interrupt bits */
14         intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0,
15                                OTX2_RVU_VF_INT);
16
17         if (intr & 0x1ULL) {
18                 /* Schedule work queue function to process the MBOX request */
19                 queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work);
20                 /* Clear and ack the interrupt */
21                 otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,
22                                  OTX2_RVU_VF_INT, 0x1ULL);
23         }
24         return IRQ_HANDLED;
25 }
26
27 static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf,
28                                        struct mbox_msghdr *msg)
29 {
30         struct otx2_cptlfs_info *lfs = &cptvf->lfs;
31         struct otx2_cpt_kvf_limits_rsp *rsp_limits;
32         struct otx2_cpt_egrp_num_rsp *rsp_grp;
33         struct cpt_rd_wr_reg_msg *rsp_reg;
34         struct msix_offset_rsp *rsp_msix;
35         int i;
36
37         if (msg->id >= MBOX_MSG_MAX) {
38                 dev_err(&cptvf->pdev->dev,
39                         "MBOX msg with unknown ID %d\n", msg->id);
40                 return;
41         }
42         if (msg->sig != OTX2_MBOX_RSP_SIG) {
43                 dev_err(&cptvf->pdev->dev,
44                         "MBOX msg with wrong signature %x, ID %d\n",
45                         msg->sig, msg->id);
46                 return;
47         }
48         switch (msg->id) {
49         case MBOX_MSG_READY:
50                 cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT)
51                                 & RVU_PFVF_FUNC_MASK) - 1;
52                 break;
53         case MBOX_MSG_ATTACH_RESOURCES:
54                 /* Check if resources were successfully attached */
55                 if (!msg->rc)
56                         lfs->are_lfs_attached = 1;
57                 break;
58         case MBOX_MSG_DETACH_RESOURCES:
59                 /* Check if resources were successfully detached */
60                 if (!msg->rc)
61                         lfs->are_lfs_attached = 0;
62                 break;
63         case MBOX_MSG_MSIX_OFFSET:
64                 rsp_msix = (struct msix_offset_rsp *) msg;
65                 for (i = 0; i < rsp_msix->cptlfs; i++)
66                         lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];
67                 break;
68         case MBOX_MSG_CPT_RD_WR_REGISTER:
69                 rsp_reg = (struct cpt_rd_wr_reg_msg *) msg;
70                 if (msg->rc) {
71                         dev_err(&cptvf->pdev->dev,
72                                 "Reg %llx rd/wr(%d) failed %d\n",
73                                 rsp_reg->reg_offset, rsp_reg->is_write,
74                                 msg->rc);
75                         return;
76                 }
77                 if (!rsp_reg->is_write)
78                         *rsp_reg->ret_val = rsp_reg->val;
79                 break;
80         case MBOX_MSG_GET_ENG_GRP_NUM:
81                 rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg;
82                 cptvf->lfs.kcrypto_eng_grp_num = rsp_grp->eng_grp_num;
83                 break;
84         case MBOX_MSG_GET_KVF_LIMITS:
85                 rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg;
86                 cptvf->lfs.kvf_limits = rsp_limits->kvf_limits;
87                 break;
88         default:
89                 dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n",
90                         msg->id);
91                 break;
92         }
93 }
94
95 void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work)
96 {
97         struct otx2_cptvf_dev *cptvf;
98         struct otx2_mbox *pfvf_mbox;
99         struct otx2_mbox_dev *mdev;
100         struct mbox_hdr *rsp_hdr;
101         struct mbox_msghdr *msg;
102         int offset, i;
103
104         /* sync with mbox memory region */
105         smp_rmb();
106
107         cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work);
108         pfvf_mbox = &cptvf->pfvf_mbox;
109         mdev = &pfvf_mbox->dev[0];
110         rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start);
111         if (rsp_hdr->num_msgs == 0)
112                 return;
113         offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
114
115         for (i = 0; i < rsp_hdr->num_msgs; i++) {
116                 msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start +
117                                              offset);
118                 process_pfvf_mbox_mbox_msg(cptvf, msg);
119                 offset = msg->next_msgoff;
120                 mdev->msgs_acked++;
121         }
122         otx2_mbox_reset(pfvf_mbox, 0);
123 }
124
125 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)
126 {
127         struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
128         struct pci_dev *pdev = cptvf->pdev;
129         struct otx2_cpt_egrp_num_msg *req;
130
131         req = (struct otx2_cpt_egrp_num_msg *)
132               otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
133                                       sizeof(struct otx2_cpt_egrp_num_rsp));
134         if (req == NULL) {
135                 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
136                 return -EFAULT;
137         }
138         req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
139         req->hdr.sig = OTX2_MBOX_REQ_SIG;
140         req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
141         req->eng_type = eng_type;
142
143         return otx2_cpt_send_mbox_msg(mbox, pdev);
144 }
145
146 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)
147 {
148         struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
149         struct pci_dev *pdev = cptvf->pdev;
150         struct mbox_msghdr *req;
151         int ret;
152
153         req = (struct mbox_msghdr *)
154               otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
155                                       sizeof(struct otx2_cpt_kvf_limits_rsp));
156         if (req == NULL) {
157                 dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
158                 return -EFAULT;
159         }
160         req->id = MBOX_MSG_GET_KVF_LIMITS;
161         req->sig = OTX2_MBOX_REQ_SIG;
162         req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
163
164         ret = otx2_cpt_send_mbox_msg(mbox, pdev);
165
166         return ret;
167 }