1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2020 Marvell. */
4 #include "otx2_cpt_common.h"
5 #include "otx2_cptvf.h"
8 int otx2_cpt_mbox_bbuf_init(struct otx2_cptvf_dev
*cptvf
, struct pci_dev
*pdev
)
10 struct otx2_mbox_dev
*mdev
;
11 struct otx2_mbox
*otx2_mbox
;
13 cptvf
->bbuf_base
= devm_kmalloc(&pdev
->dev
, MBOX_SIZE
, GFP_KERNEL
);
14 if (!cptvf
->bbuf_base
)
17 * Overwrite mbox mbase to point to bounce buffer, so that PF/VF
18 * prepare all mbox messages in bounce buffer instead of directly
21 otx2_mbox
= &cptvf
->pfvf_mbox
;
22 mdev
= &otx2_mbox
->dev
[0];
23 mdev
->mbase
= cptvf
->bbuf_base
;
28 static void otx2_cpt_sync_mbox_bbuf(struct otx2_mbox
*mbox
, int devid
)
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
];
36 if (mdev
->mbase
== hw_mbase
)
39 hdr
= hw_mbase
+ mbox
->rx_start
;
40 msg_size
= hdr
->msg_size
;
42 if (msg_size
> mbox
->rx_size
- msgs_offset
)
43 msg_size
= mbox
->rx_size
- msgs_offset
;
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
);
50 irqreturn_t
otx2_cptvf_pfvf_mbox_intr(int __always_unused irq
, void *arg
)
52 struct otx2_cptvf_dev
*cptvf
= arg
;
55 /* Read the interrupt bits */
56 intr
= otx2_cpt_read64(cptvf
->reg_base
, BLKADDR_RVUM
, 0,
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
);
69 static void process_pfvf_mbox_mbox_msg(struct otx2_cptvf_dev
*cptvf
,
70 struct mbox_msghdr
*msg
)
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
;
80 if (msg
->id
>= MBOX_MSG_MAX
) {
81 dev_err(&cptvf
->pdev
->dev
,
82 "MBOX msg with unknown ID %d\n", msg
->id
);
85 if (msg
->sig
!= OTX2_MBOX_RSP_SIG
) {
86 dev_err(&cptvf
->pdev
->dev
,
87 "MBOX msg with wrong signature %x, ID %d\n",
93 cptvf
->vf_id
= ((msg
->pcifunc
>> RVU_PFVF_FUNC_SHIFT
)
94 & RVU_PFVF_FUNC_MASK
) - 1;
96 case MBOX_MSG_ATTACH_RESOURCES
:
97 /* Check if resources were successfully attached */
99 lfs
->are_lfs_attached
= 1;
101 case MBOX_MSG_DETACH_RESOURCES
:
102 /* Check if resources were successfully detached */
104 lfs
->are_lfs_attached
= 0;
106 case MBOX_MSG_MSIX_OFFSET
:
107 rsp_msix
= (struct msix_offset_rsp
*) msg
;
108 for (i
= 0; i
< rsp_msix
->cptlfs
; i
++)
109 lfs
->lf
[i
].msix_offset
= rsp_msix
->cptlf_msixoff
[i
];
111 case MBOX_MSG_CPT_RD_WR_REGISTER
:
112 rsp_reg
= (struct cpt_rd_wr_reg_msg
*) msg
;
114 dev_err(&cptvf
->pdev
->dev
,
115 "Reg %llx rd/wr(%d) failed %d\n",
116 rsp_reg
->reg_offset
, rsp_reg
->is_write
,
120 if (!rsp_reg
->is_write
)
121 *rsp_reg
->ret_val
= rsp_reg
->val
;
123 case MBOX_MSG_GET_ENG_GRP_NUM
:
124 rsp_grp
= (struct otx2_cpt_egrp_num_rsp
*) msg
;
125 cptvf
->lfs
.kcrypto_eng_grp_num
= rsp_grp
->eng_grp_num
;
127 case MBOX_MSG_GET_KVF_LIMITS
:
128 rsp_limits
= (struct otx2_cpt_kvf_limits_rsp
*) msg
;
129 cptvf
->lfs
.kvf_limits
= rsp_limits
->kvf_limits
;
131 case MBOX_MSG_GET_CAPS
:
132 eng_caps
= (struct otx2_cpt_caps_rsp
*)msg
;
133 memcpy(cptvf
->eng_caps
, eng_caps
->eng_caps
,
134 sizeof(cptvf
->eng_caps
));
136 case MBOX_MSG_CPT_LF_RESET
:
139 dev_err(&cptvf
->pdev
->dev
, "Unsupported msg %d received.\n",
145 void otx2_cptvf_pfvf_mbox_handler(struct work_struct
*work
)
147 struct otx2_cptvf_dev
*cptvf
;
148 struct otx2_mbox
*pfvf_mbox
;
149 struct otx2_mbox_dev
*mdev
;
150 struct mbox_hdr
*rsp_hdr
;
151 struct mbox_msghdr
*msg
;
154 /* sync with mbox memory region */
157 cptvf
= container_of(work
, struct otx2_cptvf_dev
, pfvf_mbox_work
);
158 pfvf_mbox
= &cptvf
->pfvf_mbox
;
159 otx2_cpt_sync_mbox_bbuf(pfvf_mbox
, 0);
160 mdev
= &pfvf_mbox
->dev
[0];
161 rsp_hdr
= (struct mbox_hdr
*)(mdev
->mbase
+ pfvf_mbox
->rx_start
);
162 if (rsp_hdr
->num_msgs
== 0)
164 offset
= ALIGN(sizeof(struct mbox_hdr
), MBOX_MSG_ALIGN
);
166 for (i
= 0; i
< rsp_hdr
->num_msgs
; i
++) {
167 msg
= (struct mbox_msghdr
*)(mdev
->mbase
+ pfvf_mbox
->rx_start
+
169 process_pfvf_mbox_mbox_msg(cptvf
, msg
);
170 offset
= msg
->next_msgoff
;
173 otx2_mbox_reset(pfvf_mbox
, 0);
176 int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev
*cptvf
, int eng_type
)
178 struct otx2_mbox
*mbox
= &cptvf
->pfvf_mbox
;
179 struct pci_dev
*pdev
= cptvf
->pdev
;
180 struct otx2_cpt_egrp_num_msg
*req
;
182 req
= (struct otx2_cpt_egrp_num_msg
*)
183 otx2_mbox_alloc_msg_rsp(mbox
, 0, sizeof(*req
),
184 sizeof(struct otx2_cpt_egrp_num_rsp
));
186 dev_err(&pdev
->dev
, "RVU MBOX failed to get message.\n");
189 req
->hdr
.id
= MBOX_MSG_GET_ENG_GRP_NUM
;
190 req
->hdr
.sig
= OTX2_MBOX_REQ_SIG
;
191 req
->hdr
.pcifunc
= OTX2_CPT_RVU_PFFUNC(cptvf
->vf_id
, 0);
192 req
->eng_type
= eng_type
;
194 return otx2_cpt_send_mbox_msg(mbox
, pdev
);
197 int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev
*cptvf
)
199 struct otx2_mbox
*mbox
= &cptvf
->pfvf_mbox
;
200 struct pci_dev
*pdev
= cptvf
->pdev
;
201 struct mbox_msghdr
*req
;
203 req
= (struct mbox_msghdr
*)
204 otx2_mbox_alloc_msg_rsp(mbox
, 0, sizeof(*req
),
205 sizeof(struct otx2_cpt_kvf_limits_rsp
));
207 dev_err(&pdev
->dev
, "RVU MBOX failed to get message.\n");
210 req
->id
= MBOX_MSG_GET_KVF_LIMITS
;
211 req
->sig
= OTX2_MBOX_REQ_SIG
;
212 req
->pcifunc
= OTX2_CPT_RVU_PFFUNC(cptvf
->vf_id
, 0);
214 return otx2_cpt_send_mbox_msg(mbox
, pdev
);
217 int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev
*cptvf
)
219 struct otx2_mbox
*mbox
= &cptvf
->pfvf_mbox
;
220 struct pci_dev
*pdev
= cptvf
->pdev
;
221 struct mbox_msghdr
*req
;
223 req
= (struct mbox_msghdr
*)
224 otx2_mbox_alloc_msg_rsp(mbox
, 0, sizeof(*req
),
225 sizeof(struct otx2_cpt_caps_rsp
));
227 dev_err(&pdev
->dev
, "RVU MBOX failed to get message.\n");
230 req
->id
= MBOX_MSG_GET_CAPS
;
231 req
->sig
= OTX2_MBOX_REQ_SIG
;
232 req
->pcifunc
= OTX2_CPT_RVU_PFFUNC(cptvf
->vf_id
, 0);
234 return otx2_cpt_send_mbox_msg(mbox
, pdev
);