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 } 667