Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
26285 views
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
int otx2_cpt_mbox_bbuf_init(struct otx2_cptvf_dev *cptvf, struct pci_dev *pdev)
9
{
10
struct otx2_mbox_dev *mdev;
11
struct otx2_mbox *otx2_mbox;
12
13
cptvf->bbuf_base = devm_kmalloc(&pdev->dev, MBOX_SIZE, GFP_KERNEL);
14
if (!cptvf->bbuf_base)
15
return -ENOMEM;
16
/*
17
* Overwrite mbox mbase to point to bounce buffer, so that PF/VF
18
* prepare all mbox messages in bounce buffer instead of directly
19
* in hw mbox memory.
20
*/
21
otx2_mbox = &cptvf->pfvf_mbox;
22
mdev = &otx2_mbox->dev[0];
23
mdev->mbase = cptvf->bbuf_base;
24
25
return 0;
26
}
27
28
static void otx2_cpt_sync_mbox_bbuf(struct otx2_mbox *mbox, int devid)
29
{
30
u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
31
void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);
32
struct otx2_mbox_dev *mdev = &mbox->dev[devid];
33
struct mbox_hdr *hdr;
34
u64 msg_size;
35
36
if (mdev->mbase == hw_mbase)
37
return;
38
39
hdr = hw_mbase + mbox->rx_start;
40
msg_size = hdr->msg_size;
41
42
if (msg_size > mbox->rx_size - msgs_offset)
43
msg_size = mbox->rx_size - msgs_offset;
44
45
/* Copy mbox messages from mbox memory to bounce buffer */
46
memcpy(mdev->mbase + mbox->rx_start,
47
hw_mbase + mbox->rx_start, msg_size + msgs_offset);
48
}
49
50
irqreturn_t otx2_cptvf_pfvf_mbox_intr(int __always_unused irq, void *arg)
51
{
52
struct otx2_cptvf_dev *cptvf = arg;
53
u64 intr;
54
55
/* Read the interrupt bits */
56
intr = otx2_cpt_read64(cptvf->reg_base, BLKADDR_RVUM, 0,
57
OTX2_RVU_VF_INT);
58
59
if (intr & 0x1ULL) {
60
/* Schedule work queue function to process the MBOX request */
61
queue_work(cptvf->pfvf_mbox_wq, &cptvf->pfvf_mbox_work);
62
/* Clear and ack the interrupt */
63
otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,
64
OTX2_RVU_VF_INT, 0x1ULL);
65
}
66
return IRQ_HANDLED;
67
}
68
69
static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev *cptvf,
70
struct mbox_msghdr *msg)
71
{
72
struct otx2_cptlfs_info *lfs = &cptvf->lfs;
73
struct otx2_cpt_kvf_limits_rsp *rsp_limits;
74
struct otx2_cpt_egrp_num_rsp *rsp_grp;
75
struct otx2_cpt_caps_rsp *eng_caps;
76
struct cpt_rd_wr_reg_msg *rsp_reg;
77
struct msix_offset_rsp *rsp_msix;
78
u8 grp_num;
79
int i;
80
81
if (msg->id >= MBOX_MSG_MAX) {
82
dev_err(&cptvf->pdev->dev,
83
"MBOX msg with unknown ID %d\n", msg->id);
84
return;
85
}
86
if (msg->sig != OTX2_MBOX_RSP_SIG) {
87
dev_err(&cptvf->pdev->dev,
88
"MBOX msg with wrong signature %x, ID %d\n",
89
msg->sig, msg->id);
90
return;
91
}
92
switch (msg->id) {
93
case MBOX_MSG_READY:
94
cptvf->vf_id = ((msg->pcifunc >> RVU_PFVF_FUNC_SHIFT)
95
& RVU_PFVF_FUNC_MASK) - 1;
96
break;
97
case MBOX_MSG_ATTACH_RESOURCES:
98
/* Check if resources were successfully attached */
99
if (!msg->rc)
100
lfs->are_lfs_attached = 1;
101
break;
102
case MBOX_MSG_DETACH_RESOURCES:
103
/* Check if resources were successfully detached */
104
if (!msg->rc)
105
lfs->are_lfs_attached = 0;
106
break;
107
case MBOX_MSG_MSIX_OFFSET:
108
rsp_msix = (struct msix_offset_rsp *) msg;
109
for (i = 0; i < rsp_msix->cptlfs; i++)
110
lfs->lf[i].msix_offset = rsp_msix->cptlf_msixoff[i];
111
break;
112
case MBOX_MSG_CPT_RD_WR_REGISTER:
113
rsp_reg = (struct cpt_rd_wr_reg_msg *) msg;
114
if (msg->rc) {
115
dev_err(&cptvf->pdev->dev,
116
"Reg %llx rd/wr(%d) failed %d\n",
117
rsp_reg->reg_offset, rsp_reg->is_write,
118
msg->rc);
119
return;
120
}
121
if (!rsp_reg->is_write)
122
*rsp_reg->ret_val = rsp_reg->val;
123
break;
124
case MBOX_MSG_GET_ENG_GRP_NUM:
125
rsp_grp = (struct otx2_cpt_egrp_num_rsp *) msg;
126
grp_num = rsp_grp->eng_grp_num;
127
if (rsp_grp->eng_type == OTX2_CPT_SE_TYPES)
128
cptvf->lfs.kcrypto_se_eng_grp_num = grp_num;
129
else if (rsp_grp->eng_type == OTX2_CPT_AE_TYPES)
130
cptvf->lfs.kcrypto_ae_eng_grp_num = grp_num;
131
break;
132
case MBOX_MSG_GET_KVF_LIMITS:
133
rsp_limits = (struct otx2_cpt_kvf_limits_rsp *) msg;
134
cptvf->lfs.kvf_limits = rsp_limits->kvf_limits;
135
break;
136
case MBOX_MSG_GET_CAPS:
137
eng_caps = (struct otx2_cpt_caps_rsp *)msg;
138
memcpy(cptvf->eng_caps, eng_caps->eng_caps,
139
sizeof(cptvf->eng_caps));
140
break;
141
case MBOX_MSG_CPT_LF_RESET:
142
case MBOX_MSG_LMTST_TBL_SETUP:
143
break;
144
default:
145
dev_err(&cptvf->pdev->dev, "Unsupported msg %d received.\n",
146
msg->id);
147
break;
148
}
149
}
150
151
void otx2_cptvf_pfvf_mbox_handler(struct work_struct *work)
152
{
153
struct otx2_cptvf_dev *cptvf;
154
struct otx2_mbox *pfvf_mbox;
155
struct otx2_mbox_dev *mdev;
156
struct mbox_hdr *rsp_hdr;
157
struct mbox_msghdr *msg;
158
int offset, i;
159
160
/* sync with mbox memory region */
161
smp_rmb();
162
163
cptvf = container_of(work, struct otx2_cptvf_dev, pfvf_mbox_work);
164
pfvf_mbox = &cptvf->pfvf_mbox;
165
otx2_cpt_sync_mbox_bbuf(pfvf_mbox, 0);
166
mdev = &pfvf_mbox->dev[0];
167
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + pfvf_mbox->rx_start);
168
if (rsp_hdr->num_msgs == 0)
169
return;
170
offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
171
172
for (i = 0; i < rsp_hdr->num_msgs; i++) {
173
msg = (struct mbox_msghdr *)(mdev->mbase + pfvf_mbox->rx_start +
174
offset);
175
process_pfvf_mbox_mbox_msg(cptvf, msg);
176
offset = msg->next_msgoff;
177
mdev->msgs_acked++;
178
}
179
otx2_mbox_reset(pfvf_mbox, 0);
180
}
181
182
int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)
183
{
184
struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
185
struct pci_dev *pdev = cptvf->pdev;
186
struct otx2_cpt_egrp_num_msg *req;
187
188
req = (struct otx2_cpt_egrp_num_msg *)
189
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
190
sizeof(struct otx2_cpt_egrp_num_rsp));
191
if (req == NULL) {
192
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
193
return -EFAULT;
194
}
195
req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
196
req->hdr.sig = OTX2_MBOX_REQ_SIG;
197
req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
198
req->eng_type = eng_type;
199
200
return otx2_cpt_send_mbox_msg(mbox, pdev);
201
}
202
203
int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)
204
{
205
struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
206
struct pci_dev *pdev = cptvf->pdev;
207
struct mbox_msghdr *req;
208
209
req = (struct mbox_msghdr *)
210
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
211
sizeof(struct otx2_cpt_kvf_limits_rsp));
212
if (req == NULL) {
213
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
214
return -EFAULT;
215
}
216
req->id = MBOX_MSG_GET_KVF_LIMITS;
217
req->sig = OTX2_MBOX_REQ_SIG;
218
req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
219
220
return otx2_cpt_send_mbox_msg(mbox, pdev);
221
}
222
223
int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf)
224
{
225
struct otx2_mbox *mbox = &cptvf->pfvf_mbox;
226
struct pci_dev *pdev = cptvf->pdev;
227
struct mbox_msghdr *req;
228
229
req = (struct mbox_msghdr *)
230
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
231
sizeof(struct otx2_cpt_caps_rsp));
232
if (!req) {
233
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
234
return -EFAULT;
235
}
236
req->id = MBOX_MSG_GET_CAPS;
237
req->sig = OTX2_MBOX_REQ_SIG;
238
req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
239
240
return otx2_cpt_send_mbox_msg(mbox, pdev);
241
}
242
243