183ffcf78SSrujana Challa // SPDX-License-Identifier: GPL-2.0-only
283ffcf78SSrujana Challa /* Copyright (C) 2020 Marvell. */
383ffcf78SSrujana Challa
483ffcf78SSrujana Challa #include "otx2_cpt_common.h"
583ffcf78SSrujana Challa #include "otx2_cptpf.h"
683ffcf78SSrujana Challa #include "rvu_reg.h"
783ffcf78SSrujana Challa
8*a4855a8cSSrujana Challa /* Fastpath ipsec opcode with inplace processing */
9*a4855a8cSSrujana Challa #define CPT_INLINE_RX_OPCODE (0x26 | (1 << 6))
10*a4855a8cSSrujana Challa #define CN10K_CPT_INLINE_RX_OPCODE (0x29 | (1 << 6))
11*a4855a8cSSrujana Challa
12*a4855a8cSSrujana Challa #define cpt_inline_rx_opcode(pdev) \
13*a4855a8cSSrujana Challa ({ \
14*a4855a8cSSrujana Challa u8 opcode; \
15*a4855a8cSSrujana Challa if (is_dev_otx2(pdev)) \
16*a4855a8cSSrujana Challa opcode = CPT_INLINE_RX_OPCODE; \
17*a4855a8cSSrujana Challa else \
18*a4855a8cSSrujana Challa opcode = CN10K_CPT_INLINE_RX_OPCODE; \
19*a4855a8cSSrujana Challa (opcode); \
20*a4855a8cSSrujana Challa })
21*a4855a8cSSrujana Challa
2278506c2aSSrujana Challa /*
2378506c2aSSrujana Challa * CPT PF driver version, It will be incremented by 1 for every feature
2478506c2aSSrujana Challa * addition in CPT mailbox messages.
2578506c2aSSrujana Challa */
2678506c2aSSrujana Challa #define OTX2_CPT_PF_DRV_VERSION 0x1
2778506c2aSSrujana Challa
forward_to_af(struct otx2_cptpf_dev * cptpf,struct otx2_cptvf_info * vf,struct mbox_msghdr * req,int size)28fe16eceaSSrujana Challa static int forward_to_af(struct otx2_cptpf_dev *cptpf,
29fe16eceaSSrujana Challa struct otx2_cptvf_info *vf,
30fe16eceaSSrujana Challa struct mbox_msghdr *req, int size)
31fe16eceaSSrujana Challa {
32fe16eceaSSrujana Challa struct mbox_msghdr *msg;
33fe16eceaSSrujana Challa int ret;
34fe16eceaSSrujana Challa
354363f3d3SHarman Kalra mutex_lock(&cptpf->lock);
36fe16eceaSSrujana Challa msg = otx2_mbox_alloc_msg(&cptpf->afpf_mbox, 0, size);
37280ee3c3SYang Yingliang if (msg == NULL) {
38280ee3c3SYang Yingliang mutex_unlock(&cptpf->lock);
39fe16eceaSSrujana Challa return -ENOMEM;
40280ee3c3SYang Yingliang }
41fe16eceaSSrujana Challa
42fe16eceaSSrujana Challa memcpy((uint8_t *)msg + sizeof(struct mbox_msghdr),
43fe16eceaSSrujana Challa (uint8_t *)req + sizeof(struct mbox_msghdr), size);
44fe16eceaSSrujana Challa msg->id = req->id;
45fe16eceaSSrujana Challa msg->pcifunc = req->pcifunc;
46fe16eceaSSrujana Challa msg->sig = req->sig;
47fe16eceaSSrujana Challa msg->ver = req->ver;
48fe16eceaSSrujana Challa
494363f3d3SHarman Kalra ret = otx2_cpt_sync_mbox_msg(&cptpf->afpf_mbox);
504363f3d3SHarman Kalra /* Error code -EIO indicate there is a communication failure
514363f3d3SHarman Kalra * to the AF. Rest of the error codes indicate that AF processed
524363f3d3SHarman Kalra * VF messages and set the error codes in response messages
534363f3d3SHarman Kalra * (if any) so simply forward responses to VF.
544363f3d3SHarman Kalra */
55fe16eceaSSrujana Challa if (ret == -EIO) {
564363f3d3SHarman Kalra dev_warn(&cptpf->pdev->dev,
574363f3d3SHarman Kalra "AF not responding to VF%d messages\n", vf->vf_id);
584363f3d3SHarman Kalra mutex_unlock(&cptpf->lock);
59fe16eceaSSrujana Challa return ret;
60fe16eceaSSrujana Challa }
614363f3d3SHarman Kalra mutex_unlock(&cptpf->lock);
62fe16eceaSSrujana Challa return 0;
63fe16eceaSSrujana Challa }
64fe16eceaSSrujana Challa
handle_msg_get_caps(struct otx2_cptpf_dev * cptpf,struct otx2_cptvf_info * vf,struct mbox_msghdr * req)6578506c2aSSrujana Challa static int handle_msg_get_caps(struct otx2_cptpf_dev *cptpf,
6678506c2aSSrujana Challa struct otx2_cptvf_info *vf,
6778506c2aSSrujana Challa struct mbox_msghdr *req)
6878506c2aSSrujana Challa {
6978506c2aSSrujana Challa struct otx2_cpt_caps_rsp *rsp;
7078506c2aSSrujana Challa
7178506c2aSSrujana Challa rsp = (struct otx2_cpt_caps_rsp *)
7278506c2aSSrujana Challa otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id,
7378506c2aSSrujana Challa sizeof(*rsp));
7478506c2aSSrujana Challa if (!rsp)
7578506c2aSSrujana Challa return -ENOMEM;
7678506c2aSSrujana Challa
7778506c2aSSrujana Challa rsp->hdr.id = MBOX_MSG_GET_CAPS;
7878506c2aSSrujana Challa rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
7978506c2aSSrujana Challa rsp->hdr.pcifunc = req->pcifunc;
8078506c2aSSrujana Challa rsp->cpt_pf_drv_version = OTX2_CPT_PF_DRV_VERSION;
8178506c2aSSrujana Challa rsp->cpt_revision = cptpf->pdev->revision;
8278506c2aSSrujana Challa memcpy(&rsp->eng_caps, &cptpf->eng_caps, sizeof(rsp->eng_caps));
8378506c2aSSrujana Challa
8478506c2aSSrujana Challa return 0;
8578506c2aSSrujana Challa }
8678506c2aSSrujana Challa
handle_msg_get_eng_grp_num(struct otx2_cptpf_dev * cptpf,struct otx2_cptvf_info * vf,struct mbox_msghdr * req)8743ac0b82SSrujana Challa static int handle_msg_get_eng_grp_num(struct otx2_cptpf_dev *cptpf,
8843ac0b82SSrujana Challa struct otx2_cptvf_info *vf,
8943ac0b82SSrujana Challa struct mbox_msghdr *req)
9043ac0b82SSrujana Challa {
9143ac0b82SSrujana Challa struct otx2_cpt_egrp_num_msg *grp_req;
9243ac0b82SSrujana Challa struct otx2_cpt_egrp_num_rsp *rsp;
9343ac0b82SSrujana Challa
9443ac0b82SSrujana Challa grp_req = (struct otx2_cpt_egrp_num_msg *)req;
9543ac0b82SSrujana Challa rsp = (struct otx2_cpt_egrp_num_rsp *)
9643ac0b82SSrujana Challa otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
9743ac0b82SSrujana Challa if (!rsp)
9843ac0b82SSrujana Challa return -ENOMEM;
9943ac0b82SSrujana Challa
10043ac0b82SSrujana Challa rsp->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
10143ac0b82SSrujana Challa rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
10243ac0b82SSrujana Challa rsp->hdr.pcifunc = req->pcifunc;
10343ac0b82SSrujana Challa rsp->eng_type = grp_req->eng_type;
10443ac0b82SSrujana Challa rsp->eng_grp_num = otx2_cpt_get_eng_grp(&cptpf->eng_grps,
10543ac0b82SSrujana Challa grp_req->eng_type);
10643ac0b82SSrujana Challa
10743ac0b82SSrujana Challa return 0;
10843ac0b82SSrujana Challa }
10943ac0b82SSrujana Challa
handle_msg_kvf_limits(struct otx2_cptpf_dev * cptpf,struct otx2_cptvf_info * vf,struct mbox_msghdr * req)1108ec8015aSSrujana Challa static int handle_msg_kvf_limits(struct otx2_cptpf_dev *cptpf,
1118ec8015aSSrujana Challa struct otx2_cptvf_info *vf,
1128ec8015aSSrujana Challa struct mbox_msghdr *req)
1138ec8015aSSrujana Challa {
1148ec8015aSSrujana Challa struct otx2_cpt_kvf_limits_rsp *rsp;
1158ec8015aSSrujana Challa
1168ec8015aSSrujana Challa rsp = (struct otx2_cpt_kvf_limits_rsp *)
1178ec8015aSSrujana Challa otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
1188ec8015aSSrujana Challa if (!rsp)
1198ec8015aSSrujana Challa return -ENOMEM;
1208ec8015aSSrujana Challa
1218ec8015aSSrujana Challa rsp->hdr.id = MBOX_MSG_GET_KVF_LIMITS;
1228ec8015aSSrujana Challa rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
1238ec8015aSSrujana Challa rsp->hdr.pcifunc = req->pcifunc;
1248ec8015aSSrujana Challa rsp->kvf_limits = cptpf->kvf_limits;
1258ec8015aSSrujana Challa
1268ec8015aSSrujana Challa return 0;
1278ec8015aSSrujana Challa }
1288ec8015aSSrujana Challa
send_inline_ipsec_inbound_msg(struct otx2_cptpf_dev * cptpf,int sso_pf_func,u8 slot)129*a4855a8cSSrujana Challa static int send_inline_ipsec_inbound_msg(struct otx2_cptpf_dev *cptpf,
130*a4855a8cSSrujana Challa int sso_pf_func, u8 slot)
131*a4855a8cSSrujana Challa {
132*a4855a8cSSrujana Challa struct cpt_inline_ipsec_cfg_msg *req;
133*a4855a8cSSrujana Challa struct pci_dev *pdev = cptpf->pdev;
134*a4855a8cSSrujana Challa
135*a4855a8cSSrujana Challa req = (struct cpt_inline_ipsec_cfg_msg *)
136*a4855a8cSSrujana Challa otx2_mbox_alloc_msg_rsp(&cptpf->afpf_mbox, 0,
137*a4855a8cSSrujana Challa sizeof(*req), sizeof(struct msg_rsp));
138*a4855a8cSSrujana Challa if (req == NULL) {
139*a4855a8cSSrujana Challa dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
140*a4855a8cSSrujana Challa return -EFAULT;
141*a4855a8cSSrujana Challa }
142*a4855a8cSSrujana Challa memset(req, 0, sizeof(*req));
143*a4855a8cSSrujana Challa req->hdr.id = MBOX_MSG_CPT_INLINE_IPSEC_CFG;
144*a4855a8cSSrujana Challa req->hdr.sig = OTX2_MBOX_REQ_SIG;
145*a4855a8cSSrujana Challa req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
146*a4855a8cSSrujana Challa req->dir = CPT_INLINE_INBOUND;
147*a4855a8cSSrujana Challa req->slot = slot;
148*a4855a8cSSrujana Challa req->sso_pf_func_ovrd = cptpf->sso_pf_func_ovrd;
149*a4855a8cSSrujana Challa req->sso_pf_func = sso_pf_func;
150*a4855a8cSSrujana Challa req->enable = 1;
151*a4855a8cSSrujana Challa
152*a4855a8cSSrujana Challa return otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
153*a4855a8cSSrujana Challa }
154*a4855a8cSSrujana Challa
rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev * cptpf,u8 egrp,struct otx2_cpt_rx_inline_lf_cfg * req)155*a4855a8cSSrujana Challa static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp,
156*a4855a8cSSrujana Challa struct otx2_cpt_rx_inline_lf_cfg *req)
157*a4855a8cSSrujana Challa {
158*a4855a8cSSrujana Challa struct nix_inline_ipsec_cfg *nix_req;
159*a4855a8cSSrujana Challa struct pci_dev *pdev = cptpf->pdev;
160*a4855a8cSSrujana Challa int ret;
161*a4855a8cSSrujana Challa
162*a4855a8cSSrujana Challa nix_req = (struct nix_inline_ipsec_cfg *)
163*a4855a8cSSrujana Challa otx2_mbox_alloc_msg_rsp(&cptpf->afpf_mbox, 0,
164*a4855a8cSSrujana Challa sizeof(*nix_req),
165*a4855a8cSSrujana Challa sizeof(struct msg_rsp));
166*a4855a8cSSrujana Challa if (nix_req == NULL) {
167*a4855a8cSSrujana Challa dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
168*a4855a8cSSrujana Challa return -EFAULT;
169*a4855a8cSSrujana Challa }
170*a4855a8cSSrujana Challa memset(nix_req, 0, sizeof(*nix_req));
171*a4855a8cSSrujana Challa nix_req->hdr.id = MBOX_MSG_NIX_INLINE_IPSEC_CFG;
172*a4855a8cSSrujana Challa nix_req->hdr.sig = OTX2_MBOX_REQ_SIG;
173*a4855a8cSSrujana Challa nix_req->enable = 1;
174*a4855a8cSSrujana Challa if (!req->credit || req->credit > OTX2_CPT_INST_QLEN_MSGS)
175*a4855a8cSSrujana Challa nix_req->cpt_credit = OTX2_CPT_INST_QLEN_MSGS - 1;
176*a4855a8cSSrujana Challa else
177*a4855a8cSSrujana Challa nix_req->cpt_credit = req->credit - 1;
178*a4855a8cSSrujana Challa nix_req->gen_cfg.egrp = egrp;
179*a4855a8cSSrujana Challa if (req->opcode)
180*a4855a8cSSrujana Challa nix_req->gen_cfg.opcode = req->opcode;
181*a4855a8cSSrujana Challa else
182*a4855a8cSSrujana Challa nix_req->gen_cfg.opcode = cpt_inline_rx_opcode(pdev);
183*a4855a8cSSrujana Challa nix_req->gen_cfg.param1 = req->param1;
184*a4855a8cSSrujana Challa nix_req->gen_cfg.param2 = req->param2;
185*a4855a8cSSrujana Challa nix_req->inst_qsel.cpt_pf_func = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
186*a4855a8cSSrujana Challa nix_req->inst_qsel.cpt_slot = 0;
187*a4855a8cSSrujana Challa ret = otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
188*a4855a8cSSrujana Challa if (ret)
189*a4855a8cSSrujana Challa return ret;
190*a4855a8cSSrujana Challa
191*a4855a8cSSrujana Challa if (cptpf->has_cpt1) {
192*a4855a8cSSrujana Challa ret = send_inline_ipsec_inbound_msg(cptpf, req->sso_pf_func, 1);
193*a4855a8cSSrujana Challa if (ret)
194*a4855a8cSSrujana Challa return ret;
195*a4855a8cSSrujana Challa }
196*a4855a8cSSrujana Challa
197*a4855a8cSSrujana Challa return send_inline_ipsec_inbound_msg(cptpf, req->sso_pf_func, 0);
198*a4855a8cSSrujana Challa }
199*a4855a8cSSrujana Challa
handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev * cptpf,struct mbox_msghdr * req)200*a4855a8cSSrujana Challa static int handle_msg_rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf,
201*a4855a8cSSrujana Challa struct mbox_msghdr *req)
202*a4855a8cSSrujana Challa {
203*a4855a8cSSrujana Challa struct otx2_cpt_rx_inline_lf_cfg *cfg_req;
204*a4855a8cSSrujana Challa u8 egrp;
205*a4855a8cSSrujana Challa int ret;
206*a4855a8cSSrujana Challa
207*a4855a8cSSrujana Challa cfg_req = (struct otx2_cpt_rx_inline_lf_cfg *)req;
208*a4855a8cSSrujana Challa if (cptpf->lfs.lfs_num) {
209*a4855a8cSSrujana Challa dev_err(&cptpf->pdev->dev,
210*a4855a8cSSrujana Challa "LF is already configured for RX inline ipsec.\n");
211*a4855a8cSSrujana Challa return -EEXIST;
212*a4855a8cSSrujana Challa }
213*a4855a8cSSrujana Challa /*
214*a4855a8cSSrujana Challa * Allow LFs to execute requests destined to only grp IE_TYPES and
215*a4855a8cSSrujana Challa * set queue priority of each LF to high
216*a4855a8cSSrujana Challa */
217*a4855a8cSSrujana Challa egrp = otx2_cpt_get_eng_grp(&cptpf->eng_grps, OTX2_CPT_IE_TYPES);
218*a4855a8cSSrujana Challa if (egrp == OTX2_CPT_INVALID_CRYPTO_ENG_GRP) {
219*a4855a8cSSrujana Challa dev_err(&cptpf->pdev->dev,
220*a4855a8cSSrujana Challa "Engine group for inline ipsec is not available\n");
221*a4855a8cSSrujana Challa return -ENOENT;
222*a4855a8cSSrujana Challa }
223*a4855a8cSSrujana Challa
224*a4855a8cSSrujana Challa otx2_cptlf_set_dev_info(&cptpf->lfs, cptpf->pdev, cptpf->reg_base,
225*a4855a8cSSrujana Challa &cptpf->afpf_mbox, BLKADDR_CPT0);
226*a4855a8cSSrujana Challa ret = otx2_cptlf_init(&cptpf->lfs, 1 << egrp, OTX2_CPT_QUEUE_HI_PRIO,
227*a4855a8cSSrujana Challa 1);
228*a4855a8cSSrujana Challa if (ret) {
229*a4855a8cSSrujana Challa dev_err(&cptpf->pdev->dev,
230*a4855a8cSSrujana Challa "LF configuration failed for RX inline ipsec.\n");
231*a4855a8cSSrujana Challa return ret;
232*a4855a8cSSrujana Challa }
233*a4855a8cSSrujana Challa
234*a4855a8cSSrujana Challa if (cptpf->has_cpt1) {
235*a4855a8cSSrujana Challa cptpf->rsrc_req_blkaddr = BLKADDR_CPT1;
236*a4855a8cSSrujana Challa otx2_cptlf_set_dev_info(&cptpf->cpt1_lfs, cptpf->pdev,
237*a4855a8cSSrujana Challa cptpf->reg_base, &cptpf->afpf_mbox,
238*a4855a8cSSrujana Challa BLKADDR_CPT1);
239*a4855a8cSSrujana Challa ret = otx2_cptlf_init(&cptpf->cpt1_lfs, 1 << egrp,
240*a4855a8cSSrujana Challa OTX2_CPT_QUEUE_HI_PRIO, 1);
241*a4855a8cSSrujana Challa if (ret) {
242*a4855a8cSSrujana Challa dev_err(&cptpf->pdev->dev,
243*a4855a8cSSrujana Challa "LF configuration failed for RX inline ipsec.\n");
244*a4855a8cSSrujana Challa goto lf_cleanup;
245*a4855a8cSSrujana Challa }
246*a4855a8cSSrujana Challa cptpf->rsrc_req_blkaddr = 0;
247*a4855a8cSSrujana Challa }
248*a4855a8cSSrujana Challa
249*a4855a8cSSrujana Challa ret = rx_inline_ipsec_lf_cfg(cptpf, egrp, cfg_req);
250*a4855a8cSSrujana Challa if (ret)
251*a4855a8cSSrujana Challa goto lf1_cleanup;
252*a4855a8cSSrujana Challa
253*a4855a8cSSrujana Challa return 0;
254*a4855a8cSSrujana Challa
255*a4855a8cSSrujana Challa lf1_cleanup:
256*a4855a8cSSrujana Challa otx2_cptlf_shutdown(&cptpf->cpt1_lfs);
257*a4855a8cSSrujana Challa lf_cleanup:
258*a4855a8cSSrujana Challa otx2_cptlf_shutdown(&cptpf->lfs);
259*a4855a8cSSrujana Challa return ret;
260*a4855a8cSSrujana Challa }
261*a4855a8cSSrujana Challa
cptpf_handle_vf_req(struct otx2_cptpf_dev * cptpf,struct otx2_cptvf_info * vf,struct mbox_msghdr * req,int size)262fe16eceaSSrujana Challa static int cptpf_handle_vf_req(struct otx2_cptpf_dev *cptpf,
263fe16eceaSSrujana Challa struct otx2_cptvf_info *vf,
264fe16eceaSSrujana Challa struct mbox_msghdr *req, int size)
265fe16eceaSSrujana Challa {
266fe16eceaSSrujana Challa int err = 0;
267fe16eceaSSrujana Challa
268fe16eceaSSrujana Challa /* Check if msg is valid, if not reply with an invalid msg */
269fe16eceaSSrujana Challa if (req->sig != OTX2_MBOX_REQ_SIG)
270fe16eceaSSrujana Challa goto inval_msg;
271fe16eceaSSrujana Challa
27243ac0b82SSrujana Challa switch (req->id) {
27343ac0b82SSrujana Challa case MBOX_MSG_GET_ENG_GRP_NUM:
27443ac0b82SSrujana Challa err = handle_msg_get_eng_grp_num(cptpf, vf, req);
27543ac0b82SSrujana Challa break;
27678506c2aSSrujana Challa case MBOX_MSG_GET_CAPS:
27778506c2aSSrujana Challa err = handle_msg_get_caps(cptpf, vf, req);
27878506c2aSSrujana Challa break;
2798ec8015aSSrujana Challa case MBOX_MSG_GET_KVF_LIMITS:
2808ec8015aSSrujana Challa err = handle_msg_kvf_limits(cptpf, vf, req);
2818ec8015aSSrujana Challa break;
282*a4855a8cSSrujana Challa case MBOX_MSG_RX_INLINE_IPSEC_LF_CFG:
283*a4855a8cSSrujana Challa err = handle_msg_rx_inline_ipsec_lf_cfg(cptpf, req);
284*a4855a8cSSrujana Challa break;
285*a4855a8cSSrujana Challa
28643ac0b82SSrujana Challa default:
28743ac0b82SSrujana Challa err = forward_to_af(cptpf, vf, req, size);
28843ac0b82SSrujana Challa break;
28943ac0b82SSrujana Challa }
29043ac0b82SSrujana Challa return err;
291fe16eceaSSrujana Challa
292fe16eceaSSrujana Challa inval_msg:
293fe16eceaSSrujana Challa otx2_reply_invalid_msg(&cptpf->vfpf_mbox, vf->vf_id, 0, req->id);
294fe16eceaSSrujana Challa otx2_mbox_msg_send(&cptpf->vfpf_mbox, vf->vf_id);
295fe16eceaSSrujana Challa return err;
296fe16eceaSSrujana Challa }
297fe16eceaSSrujana Challa
otx2_cptpf_vfpf_mbox_intr(int __always_unused irq,void * arg)298fe16eceaSSrujana Challa irqreturn_t otx2_cptpf_vfpf_mbox_intr(int __always_unused irq, void *arg)
299fe16eceaSSrujana Challa {
300fe16eceaSSrujana Challa struct otx2_cptpf_dev *cptpf = arg;
301fe16eceaSSrujana Challa struct otx2_cptvf_info *vf;
302fe16eceaSSrujana Challa int i, vf_idx;
303fe16eceaSSrujana Challa u64 intr;
304fe16eceaSSrujana Challa
305fe16eceaSSrujana Challa /*
306fe16eceaSSrujana Challa * Check which VF has raised an interrupt and schedule
307fe16eceaSSrujana Challa * corresponding work queue to process the messages
308fe16eceaSSrujana Challa */
309fe16eceaSSrujana Challa for (i = 0; i < 2; i++) {
310fe16eceaSSrujana Challa /* Read the interrupt bits */
311fe16eceaSSrujana Challa intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
312fe16eceaSSrujana Challa RVU_PF_VFPF_MBOX_INTX(i));
313fe16eceaSSrujana Challa
314fe16eceaSSrujana Challa for (vf_idx = i * 64; vf_idx < cptpf->enabled_vfs; vf_idx++) {
315fe16eceaSSrujana Challa vf = &cptpf->vf[vf_idx];
316fe16eceaSSrujana Challa if (intr & (1ULL << vf->intr_idx)) {
317fe16eceaSSrujana Challa queue_work(cptpf->vfpf_mbox_wq,
318fe16eceaSSrujana Challa &vf->vfpf_mbox_work);
319fe16eceaSSrujana Challa /* Clear the interrupt */
320fe16eceaSSrujana Challa otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM,
321fe16eceaSSrujana Challa 0, RVU_PF_VFPF_MBOX_INTX(i),
322fe16eceaSSrujana Challa BIT_ULL(vf->intr_idx));
323fe16eceaSSrujana Challa }
324fe16eceaSSrujana Challa }
325fe16eceaSSrujana Challa }
326fe16eceaSSrujana Challa return IRQ_HANDLED;
327fe16eceaSSrujana Challa }
328fe16eceaSSrujana Challa
otx2_cptpf_vfpf_mbox_handler(struct work_struct * work)329fe16eceaSSrujana Challa void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
330fe16eceaSSrujana Challa {
331fe16eceaSSrujana Challa struct otx2_cptpf_dev *cptpf;
332fe16eceaSSrujana Challa struct otx2_cptvf_info *vf;
333fe16eceaSSrujana Challa struct otx2_mbox_dev *mdev;
334fe16eceaSSrujana Challa struct mbox_hdr *req_hdr;
335fe16eceaSSrujana Challa struct mbox_msghdr *msg;
336fe16eceaSSrujana Challa struct otx2_mbox *mbox;
337fe16eceaSSrujana Challa int offset, i, err;
338fe16eceaSSrujana Challa
339fe16eceaSSrujana Challa vf = container_of(work, struct otx2_cptvf_info, vfpf_mbox_work);
340fe16eceaSSrujana Challa cptpf = vf->cptpf;
341fe16eceaSSrujana Challa mbox = &cptpf->vfpf_mbox;
342fe16eceaSSrujana Challa /* sync with mbox memory region */
343fe16eceaSSrujana Challa smp_rmb();
344fe16eceaSSrujana Challa mdev = &mbox->dev[vf->vf_id];
345fe16eceaSSrujana Challa /* Process received mbox messages */
346fe16eceaSSrujana Challa req_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
347fe16eceaSSrujana Challa offset = mbox->rx_start + ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
348fe16eceaSSrujana Challa
349fe16eceaSSrujana Challa for (i = 0; i < req_hdr->num_msgs; i++) {
350fe16eceaSSrujana Challa msg = (struct mbox_msghdr *)(mdev->mbase + offset);
351fe16eceaSSrujana Challa
352fe16eceaSSrujana Challa /* Set which VF sent this message based on mbox IRQ */
353fe16eceaSSrujana Challa msg->pcifunc = ((u16)cptpf->pf_id << RVU_PFVF_PF_SHIFT) |
354fe16eceaSSrujana Challa ((vf->vf_id + 1) & RVU_PFVF_FUNC_MASK);
355fe16eceaSSrujana Challa
356fe16eceaSSrujana Challa err = cptpf_handle_vf_req(cptpf, vf, msg,
357fe16eceaSSrujana Challa msg->next_msgoff - offset);
358fe16eceaSSrujana Challa /*
359fe16eceaSSrujana Challa * Behave as the AF, drop the msg if there is
360fe16eceaSSrujana Challa * no memory, timeout handling also goes here
361fe16eceaSSrujana Challa */
362fe16eceaSSrujana Challa if (err == -ENOMEM || err == -EIO)
363fe16eceaSSrujana Challa break;
364fe16eceaSSrujana Challa offset = msg->next_msgoff;
3654363f3d3SHarman Kalra /* Write barrier required for VF responses which are handled by
3664363f3d3SHarman Kalra * PF driver and not forwarded to AF.
3674363f3d3SHarman Kalra */
3684363f3d3SHarman Kalra smp_wmb();
369fe16eceaSSrujana Challa }
370fe16eceaSSrujana Challa /* Send mbox responses to VF */
371fe16eceaSSrujana Challa if (mdev->num_msgs)
372fe16eceaSSrujana Challa otx2_mbox_msg_send(mbox, vf->vf_id);
373fe16eceaSSrujana Challa }
374fe16eceaSSrujana Challa
otx2_cptpf_afpf_mbox_intr(int __always_unused irq,void * arg)37583ffcf78SSrujana Challa irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
37683ffcf78SSrujana Challa {
37783ffcf78SSrujana Challa struct otx2_cptpf_dev *cptpf = arg;
3785c553114SSrujana Challa struct otx2_mbox_dev *mdev;
3795c553114SSrujana Challa struct otx2_mbox *mbox;
3805c553114SSrujana Challa struct mbox_hdr *hdr;
38183ffcf78SSrujana Challa u64 intr;
38283ffcf78SSrujana Challa
38383ffcf78SSrujana Challa /* Read the interrupt bits */
38483ffcf78SSrujana Challa intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);
38583ffcf78SSrujana Challa
38683ffcf78SSrujana Challa if (intr & 0x1ULL) {
3875c553114SSrujana Challa mbox = &cptpf->afpf_mbox;
3885c553114SSrujana Challa mdev = &mbox->dev[0];
3895c553114SSrujana Challa hdr = mdev->mbase + mbox->rx_start;
3905c553114SSrujana Challa if (hdr->num_msgs)
39183ffcf78SSrujana Challa /* Schedule work queue function to process the MBOX request */
39283ffcf78SSrujana Challa queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
3935c553114SSrujana Challa
3945c553114SSrujana Challa mbox = &cptpf->afpf_mbox_up;
3955c553114SSrujana Challa mdev = &mbox->dev[0];
3965c553114SSrujana Challa hdr = mdev->mbase + mbox->rx_start;
3975c553114SSrujana Challa if (hdr->num_msgs)
3985c553114SSrujana Challa /* Schedule work queue function to process the MBOX request */
3995c553114SSrujana Challa queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_up_work);
40083ffcf78SSrujana Challa /* Clear and ack the interrupt */
40183ffcf78SSrujana Challa otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
40283ffcf78SSrujana Challa 0x1ULL);
40383ffcf78SSrujana Challa }
40483ffcf78SSrujana Challa return IRQ_HANDLED;
40583ffcf78SSrujana Challa }
40683ffcf78SSrujana Challa
process_afpf_mbox_msg(struct otx2_cptpf_dev * cptpf,struct mbox_msghdr * msg)40783ffcf78SSrujana Challa static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
40883ffcf78SSrujana Challa struct mbox_msghdr *msg)
40983ffcf78SSrujana Challa {
410*a4855a8cSSrujana Challa struct otx2_cptlfs_info *lfs = &cptpf->lfs;
41183ffcf78SSrujana Challa struct device *dev = &cptpf->pdev->dev;
41243ac0b82SSrujana Challa struct cpt_rd_wr_reg_msg *rsp_rd_wr;
41383ffcf78SSrujana Challa
41483ffcf78SSrujana Challa if (msg->id >= MBOX_MSG_MAX) {
41583ffcf78SSrujana Challa dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
41683ffcf78SSrujana Challa return;
41783ffcf78SSrujana Challa }
41883ffcf78SSrujana Challa if (msg->sig != OTX2_MBOX_RSP_SIG) {
41983ffcf78SSrujana Challa dev_err(dev, "MBOX msg with wrong signature %x, ID %d\n",
42083ffcf78SSrujana Challa msg->sig, msg->id);
42183ffcf78SSrujana Challa return;
42283ffcf78SSrujana Challa }
423*a4855a8cSSrujana Challa if (cptpf->rsrc_req_blkaddr == BLKADDR_CPT1)
424*a4855a8cSSrujana Challa lfs = &cptpf->cpt1_lfs;
42583ffcf78SSrujana Challa
42683ffcf78SSrujana Challa switch (msg->id) {
42783ffcf78SSrujana Challa case MBOX_MSG_READY:
42883ffcf78SSrujana Challa cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
42983ffcf78SSrujana Challa RVU_PFVF_PF_MASK;
43083ffcf78SSrujana Challa break;
43143ac0b82SSrujana Challa case MBOX_MSG_CPT_RD_WR_REGISTER:
43243ac0b82SSrujana Challa rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg;
43343ac0b82SSrujana Challa if (msg->rc) {
43443ac0b82SSrujana Challa dev_err(dev, "Reg %llx rd/wr(%d) failed %d\n",
43543ac0b82SSrujana Challa rsp_rd_wr->reg_offset, rsp_rd_wr->is_write,
43643ac0b82SSrujana Challa msg->rc);
43743ac0b82SSrujana Challa return;
43843ac0b82SSrujana Challa }
43943ac0b82SSrujana Challa if (!rsp_rd_wr->is_write)
44043ac0b82SSrujana Challa *rsp_rd_wr->ret_val = rsp_rd_wr->val;
44143ac0b82SSrujana Challa break;
44264506017SSrujana Challa case MBOX_MSG_ATTACH_RESOURCES:
44364506017SSrujana Challa if (!msg->rc)
444*a4855a8cSSrujana Challa lfs->are_lfs_attached = 1;
44564506017SSrujana Challa break;
44664506017SSrujana Challa case MBOX_MSG_DETACH_RESOURCES:
44764506017SSrujana Challa if (!msg->rc)
448*a4855a8cSSrujana Challa lfs->are_lfs_attached = 0;
449*a4855a8cSSrujana Challa break;
450*a4855a8cSSrujana Challa case MBOX_MSG_CPT_INLINE_IPSEC_CFG:
451*a4855a8cSSrujana Challa case MBOX_MSG_NIX_INLINE_IPSEC_CFG:
45264506017SSrujana Challa break;
45343ac0b82SSrujana Challa
45483ffcf78SSrujana Challa default:
45583ffcf78SSrujana Challa dev_err(dev,
45683ffcf78SSrujana Challa "Unsupported msg %d received.\n", msg->id);
45783ffcf78SSrujana Challa break;
45883ffcf78SSrujana Challa }
45983ffcf78SSrujana Challa }
46083ffcf78SSrujana Challa
forward_to_vf(struct otx2_cptpf_dev * cptpf,struct mbox_msghdr * msg,int vf_id,int size)461fe16eceaSSrujana Challa static void forward_to_vf(struct otx2_cptpf_dev *cptpf, struct mbox_msghdr *msg,
462fe16eceaSSrujana Challa int vf_id, int size)
463fe16eceaSSrujana Challa {
464fe16eceaSSrujana Challa struct otx2_mbox *vfpf_mbox;
465fe16eceaSSrujana Challa struct mbox_msghdr *fwd;
466fe16eceaSSrujana Challa
467fe16eceaSSrujana Challa if (msg->id >= MBOX_MSG_MAX) {
468fe16eceaSSrujana Challa dev_err(&cptpf->pdev->dev,
469fe16eceaSSrujana Challa "MBOX msg with unknown ID %d\n", msg->id);
470fe16eceaSSrujana Challa return;
471fe16eceaSSrujana Challa }
472fe16eceaSSrujana Challa if (msg->sig != OTX2_MBOX_RSP_SIG) {
473fe16eceaSSrujana Challa dev_err(&cptpf->pdev->dev,
474fe16eceaSSrujana Challa "MBOX msg with wrong signature %x, ID %d\n",
475fe16eceaSSrujana Challa msg->sig, msg->id);
476fe16eceaSSrujana Challa return;
477fe16eceaSSrujana Challa }
478fe16eceaSSrujana Challa vfpf_mbox = &cptpf->vfpf_mbox;
479fe16eceaSSrujana Challa vf_id--;
480fe16eceaSSrujana Challa if (vf_id >= cptpf->enabled_vfs) {
481fe16eceaSSrujana Challa dev_err(&cptpf->pdev->dev,
482fe16eceaSSrujana Challa "MBOX msg to unknown VF: %d >= %d\n",
483fe16eceaSSrujana Challa vf_id, cptpf->enabled_vfs);
484fe16eceaSSrujana Challa return;
485fe16eceaSSrujana Challa }
486fe16eceaSSrujana Challa if (msg->id == MBOX_MSG_VF_FLR)
487fe16eceaSSrujana Challa return;
488fe16eceaSSrujana Challa
489fe16eceaSSrujana Challa fwd = otx2_mbox_alloc_msg(vfpf_mbox, vf_id, size);
490fe16eceaSSrujana Challa if (!fwd) {
491fe16eceaSSrujana Challa dev_err(&cptpf->pdev->dev,
492fe16eceaSSrujana Challa "Forwarding to VF%d failed.\n", vf_id);
493fe16eceaSSrujana Challa return;
494fe16eceaSSrujana Challa }
495fe16eceaSSrujana Challa memcpy((uint8_t *)fwd + sizeof(struct mbox_msghdr),
496fe16eceaSSrujana Challa (uint8_t *)msg + sizeof(struct mbox_msghdr), size);
497fe16eceaSSrujana Challa fwd->id = msg->id;
498fe16eceaSSrujana Challa fwd->pcifunc = msg->pcifunc;
499fe16eceaSSrujana Challa fwd->sig = msg->sig;
500fe16eceaSSrujana Challa fwd->ver = msg->ver;
501fe16eceaSSrujana Challa fwd->rc = msg->rc;
502fe16eceaSSrujana Challa }
503fe16eceaSSrujana Challa
50483ffcf78SSrujana Challa /* Handle mailbox messages received from AF */
otx2_cptpf_afpf_mbox_handler(struct work_struct * work)50583ffcf78SSrujana Challa void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
50683ffcf78SSrujana Challa {
50783ffcf78SSrujana Challa struct otx2_cptpf_dev *cptpf;
50883ffcf78SSrujana Challa struct otx2_mbox *afpf_mbox;
50983ffcf78SSrujana Challa struct otx2_mbox_dev *mdev;
51083ffcf78SSrujana Challa struct mbox_hdr *rsp_hdr;
51183ffcf78SSrujana Challa struct mbox_msghdr *msg;
512fe16eceaSSrujana Challa int offset, vf_id, i;
51383ffcf78SSrujana Challa
51483ffcf78SSrujana Challa cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_work);
51583ffcf78SSrujana Challa afpf_mbox = &cptpf->afpf_mbox;
51683ffcf78SSrujana Challa mdev = &afpf_mbox->dev[0];
51783ffcf78SSrujana Challa /* Sync mbox data into memory */
51883ffcf78SSrujana Challa smp_wmb();
51983ffcf78SSrujana Challa
52083ffcf78SSrujana Challa rsp_hdr = (struct mbox_hdr *)(mdev->mbase + afpf_mbox->rx_start);
52183ffcf78SSrujana Challa offset = ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
52283ffcf78SSrujana Challa
52383ffcf78SSrujana Challa for (i = 0; i < rsp_hdr->num_msgs; i++) {
52483ffcf78SSrujana Challa msg = (struct mbox_msghdr *)(mdev->mbase + afpf_mbox->rx_start +
52583ffcf78SSrujana Challa offset);
526fe16eceaSSrujana Challa vf_id = (msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) &
527fe16eceaSSrujana Challa RVU_PFVF_FUNC_MASK;
528fe16eceaSSrujana Challa if (vf_id > 0)
529fe16eceaSSrujana Challa forward_to_vf(cptpf, msg, vf_id,
530fe16eceaSSrujana Challa msg->next_msgoff - offset);
531fe16eceaSSrujana Challa else
53283ffcf78SSrujana Challa process_afpf_mbox_msg(cptpf, msg);
533fe16eceaSSrujana Challa
53483ffcf78SSrujana Challa offset = msg->next_msgoff;
5354363f3d3SHarman Kalra /* Sync VF response ready to be sent */
5364363f3d3SHarman Kalra smp_wmb();
53783ffcf78SSrujana Challa mdev->msgs_acked++;
53883ffcf78SSrujana Challa }
53983ffcf78SSrujana Challa otx2_mbox_reset(afpf_mbox, 0);
54083ffcf78SSrujana Challa }
5415c553114SSrujana Challa
handle_msg_cpt_inst_lmtst(struct otx2_cptpf_dev * cptpf,struct mbox_msghdr * msg)5425c553114SSrujana Challa static void handle_msg_cpt_inst_lmtst(struct otx2_cptpf_dev *cptpf,
5435c553114SSrujana Challa struct mbox_msghdr *msg)
5445c553114SSrujana Challa {
5455c553114SSrujana Challa struct cpt_inst_lmtst_req *req = (struct cpt_inst_lmtst_req *)msg;
5465c553114SSrujana Challa struct otx2_cptlfs_info *lfs = &cptpf->lfs;
5475c553114SSrujana Challa struct msg_rsp *rsp;
5485c553114SSrujana Challa
5495c553114SSrujana Challa if (cptpf->lfs.lfs_num)
5505c553114SSrujana Challa lfs->ops->send_cmd((union otx2_cpt_inst_s *)req->inst, 1,
5515c553114SSrujana Challa &lfs->lf[0]);
5525c553114SSrujana Challa
5535c553114SSrujana Challa rsp = (struct msg_rsp *)otx2_mbox_alloc_msg(&cptpf->afpf_mbox_up, 0,
5545c553114SSrujana Challa sizeof(*rsp));
5555c553114SSrujana Challa if (!rsp)
5565c553114SSrujana Challa return;
5575c553114SSrujana Challa
5585c553114SSrujana Challa rsp->hdr.id = msg->id;
5595c553114SSrujana Challa rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
5605c553114SSrujana Challa rsp->hdr.pcifunc = 0;
5615c553114SSrujana Challa rsp->hdr.rc = 0;
5625c553114SSrujana Challa }
5635c553114SSrujana Challa
process_afpf_mbox_up_msg(struct otx2_cptpf_dev * cptpf,struct mbox_msghdr * msg)5645c553114SSrujana Challa static void process_afpf_mbox_up_msg(struct otx2_cptpf_dev *cptpf,
5655c553114SSrujana Challa struct mbox_msghdr *msg)
5665c553114SSrujana Challa {
5675c553114SSrujana Challa if (msg->id >= MBOX_MSG_MAX) {
5685c553114SSrujana Challa dev_err(&cptpf->pdev->dev,
5695c553114SSrujana Challa "MBOX msg with unknown ID %d\n", msg->id);
5705c553114SSrujana Challa return;
5715c553114SSrujana Challa }
5725c553114SSrujana Challa
5735c553114SSrujana Challa switch (msg->id) {
5745c553114SSrujana Challa case MBOX_MSG_CPT_INST_LMTST:
5755c553114SSrujana Challa handle_msg_cpt_inst_lmtst(cptpf, msg);
5765c553114SSrujana Challa break;
5775c553114SSrujana Challa default:
5785c553114SSrujana Challa otx2_reply_invalid_msg(&cptpf->afpf_mbox_up, 0, 0, msg->id);
5795c553114SSrujana Challa }
5805c553114SSrujana Challa }
5815c553114SSrujana Challa
otx2_cptpf_afpf_mbox_up_handler(struct work_struct * work)5825c553114SSrujana Challa void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work)
5835c553114SSrujana Challa {
5845c553114SSrujana Challa struct otx2_cptpf_dev *cptpf;
5855c553114SSrujana Challa struct otx2_mbox_dev *mdev;
5865c553114SSrujana Challa struct mbox_hdr *rsp_hdr;
5875c553114SSrujana Challa struct mbox_msghdr *msg;
5885c553114SSrujana Challa struct otx2_mbox *mbox;
5895c553114SSrujana Challa int offset, i;
5905c553114SSrujana Challa
5915c553114SSrujana Challa cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_up_work);
5925c553114SSrujana Challa mbox = &cptpf->afpf_mbox_up;
5935c553114SSrujana Challa mdev = &mbox->dev[0];
5945c553114SSrujana Challa /* Sync mbox data into memory */
5955c553114SSrujana Challa smp_wmb();
5965c553114SSrujana Challa
5975c553114SSrujana Challa rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
5985c553114SSrujana Challa offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
5995c553114SSrujana Challa
6005c553114SSrujana Challa for (i = 0; i < rsp_hdr->num_msgs; i++) {
6015c553114SSrujana Challa msg = (struct mbox_msghdr *)(mdev->mbase + offset);
6025c553114SSrujana Challa
6035c553114SSrujana Challa process_afpf_mbox_up_msg(cptpf, msg);
6045c553114SSrujana Challa
6055c553114SSrujana Challa offset = mbox->rx_start + msg->next_msgoff;
6065c553114SSrujana Challa }
6075c553114SSrujana Challa otx2_mbox_msg_send(mbox, 0);
6085c553114SSrujana Challa }
609