10dc1cffaSAnkur Dwivedi /* SPDX-License-Identifier: BSD-3-Clause 20dc1cffaSAnkur Dwivedi * Copyright(c) 2018 Cavium, Inc 30dc1cffaSAnkur Dwivedi */ 40dc1cffaSAnkur Dwivedi #include <string.h> 5*0906b99fSMurthy NSSR #include <unistd.h> 60dc1cffaSAnkur Dwivedi 784eb02f7SAnkur Dwivedi #include <rte_branch_prediction.h> 80dc1cffaSAnkur Dwivedi #include <rte_common.h> 90dc1cffaSAnkur Dwivedi 100dc1cffaSAnkur Dwivedi #include "otx_cryptodev_hw_access.h" 11ae500541SMurthy NSSR #include "otx_cryptodev_mbox.h" 120dc1cffaSAnkur Dwivedi 130dc1cffaSAnkur Dwivedi #include "cpt_pmd_logs.h" 1484eb02f7SAnkur Dwivedi #include "cpt_hw_types.h" 1584eb02f7SAnkur Dwivedi 1684eb02f7SAnkur Dwivedi /* 1784eb02f7SAnkur Dwivedi * VF HAL functions 1884eb02f7SAnkur Dwivedi * Access its own BAR0/4 registers by passing VF number as 0. 1984eb02f7SAnkur Dwivedi * OS/PCI maps them accordingly. 2084eb02f7SAnkur Dwivedi */ 210dc1cffaSAnkur Dwivedi 220dc1cffaSAnkur Dwivedi static int 230dc1cffaSAnkur Dwivedi otx_cpt_vf_init(struct cpt_vf *cptvf) 240dc1cffaSAnkur Dwivedi { 250dc1cffaSAnkur Dwivedi int ret = 0; 260dc1cffaSAnkur Dwivedi 27ae500541SMurthy NSSR /* Check ready with PF */ 28ae500541SMurthy NSSR /* Gets chip ID / device Id from PF if ready */ 29ae500541SMurthy NSSR ret = otx_cpt_check_pf_ready(cptvf); 30ae500541SMurthy NSSR if (ret) { 31ae500541SMurthy NSSR CPT_LOG_ERR("%s: PF not responding to READY msg", 32ae500541SMurthy NSSR cptvf->dev_name); 33ae500541SMurthy NSSR ret = -EBUSY; 34ae500541SMurthy NSSR goto exit; 35ae500541SMurthy NSSR } 36ae500541SMurthy NSSR 370dc1cffaSAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: %s done", cptvf->dev_name, __func__); 380dc1cffaSAnkur Dwivedi 39ae500541SMurthy NSSR exit: 400dc1cffaSAnkur Dwivedi return ret; 410dc1cffaSAnkur Dwivedi } 420dc1cffaSAnkur Dwivedi 4384eb02f7SAnkur Dwivedi /* 4484eb02f7SAnkur Dwivedi * Read Interrupt status of the VF 4584eb02f7SAnkur Dwivedi * 4684eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 4784eb02f7SAnkur Dwivedi */ 4884eb02f7SAnkur Dwivedi static uint64_t 4984eb02f7SAnkur Dwivedi otx_cpt_read_vf_misc_intr_status(struct cpt_vf *cptvf) 5084eb02f7SAnkur Dwivedi { 5184eb02f7SAnkur Dwivedi return CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), CPTX_VQX_MISC_INT(0, 0)); 5284eb02f7SAnkur Dwivedi } 5384eb02f7SAnkur Dwivedi 5484eb02f7SAnkur Dwivedi /* 5584eb02f7SAnkur Dwivedi * Clear mailbox interrupt of the VF 5684eb02f7SAnkur Dwivedi * 5784eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 5884eb02f7SAnkur Dwivedi */ 5984eb02f7SAnkur Dwivedi static void 6084eb02f7SAnkur Dwivedi otx_cpt_clear_mbox_intr(struct cpt_vf *cptvf) 6184eb02f7SAnkur Dwivedi { 6284eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 6384eb02f7SAnkur Dwivedi 6484eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 6584eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 6684eb02f7SAnkur Dwivedi /* W1C for the VF */ 6784eb02f7SAnkur Dwivedi vqx_misc_int.s.mbox = 1; 6884eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 6984eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 7084eb02f7SAnkur Dwivedi } 7184eb02f7SAnkur Dwivedi 7284eb02f7SAnkur Dwivedi /* 7384eb02f7SAnkur Dwivedi * Clear instruction NCB read error interrupt of the VF 7484eb02f7SAnkur Dwivedi * 7584eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 7684eb02f7SAnkur Dwivedi */ 7784eb02f7SAnkur Dwivedi static void 7884eb02f7SAnkur Dwivedi otx_cpt_clear_irde_intr(struct cpt_vf *cptvf) 7984eb02f7SAnkur Dwivedi { 8084eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 8184eb02f7SAnkur Dwivedi 8284eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 8384eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 8484eb02f7SAnkur Dwivedi /* W1C for the VF */ 8584eb02f7SAnkur Dwivedi vqx_misc_int.s.irde = 1; 8684eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 8784eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 8884eb02f7SAnkur Dwivedi } 8984eb02f7SAnkur Dwivedi 9084eb02f7SAnkur Dwivedi /* 9184eb02f7SAnkur Dwivedi * Clear NCB result write response error interrupt of the VF 9284eb02f7SAnkur Dwivedi * 9384eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 9484eb02f7SAnkur Dwivedi */ 9584eb02f7SAnkur Dwivedi static void 9684eb02f7SAnkur Dwivedi otx_cpt_clear_nwrp_intr(struct cpt_vf *cptvf) 9784eb02f7SAnkur Dwivedi { 9884eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 9984eb02f7SAnkur Dwivedi 10084eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 10184eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 10284eb02f7SAnkur Dwivedi /* W1C for the VF */ 10384eb02f7SAnkur Dwivedi vqx_misc_int.s.nwrp = 1; 10484eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 10584eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 10684eb02f7SAnkur Dwivedi } 10784eb02f7SAnkur Dwivedi 10884eb02f7SAnkur Dwivedi /* 10984eb02f7SAnkur Dwivedi * Clear swerr interrupt of the VF 11084eb02f7SAnkur Dwivedi * 11184eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 11284eb02f7SAnkur Dwivedi */ 11384eb02f7SAnkur Dwivedi static void 11484eb02f7SAnkur Dwivedi otx_cpt_clear_swerr_intr(struct cpt_vf *cptvf) 11584eb02f7SAnkur Dwivedi { 11684eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 11784eb02f7SAnkur Dwivedi 11884eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 11984eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 12084eb02f7SAnkur Dwivedi /* W1C for the VF */ 12184eb02f7SAnkur Dwivedi vqx_misc_int.s.swerr = 1; 12284eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 12384eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 12484eb02f7SAnkur Dwivedi } 12584eb02f7SAnkur Dwivedi 12684eb02f7SAnkur Dwivedi /* 12784eb02f7SAnkur Dwivedi * Clear hwerr interrupt of the VF 12884eb02f7SAnkur Dwivedi * 12984eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 13084eb02f7SAnkur Dwivedi */ 13184eb02f7SAnkur Dwivedi static void 13284eb02f7SAnkur Dwivedi otx_cpt_clear_hwerr_intr(struct cpt_vf *cptvf) 13384eb02f7SAnkur Dwivedi { 13484eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 13584eb02f7SAnkur Dwivedi 13684eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 13784eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 13884eb02f7SAnkur Dwivedi /* W1C for the VF */ 13984eb02f7SAnkur Dwivedi vqx_misc_int.s.hwerr = 1; 14084eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 14184eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 14284eb02f7SAnkur Dwivedi } 14384eb02f7SAnkur Dwivedi 14484eb02f7SAnkur Dwivedi /* 14584eb02f7SAnkur Dwivedi * Clear translation fault interrupt of the VF 14684eb02f7SAnkur Dwivedi * 14784eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 14884eb02f7SAnkur Dwivedi */ 14984eb02f7SAnkur Dwivedi static void 15084eb02f7SAnkur Dwivedi otx_cpt_clear_fault_intr(struct cpt_vf *cptvf) 15184eb02f7SAnkur Dwivedi { 15284eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 15384eb02f7SAnkur Dwivedi 15484eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 15584eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 15684eb02f7SAnkur Dwivedi /* W1C for the VF */ 15784eb02f7SAnkur Dwivedi vqx_misc_int.s.fault = 1; 15884eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 15984eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 16084eb02f7SAnkur Dwivedi } 16184eb02f7SAnkur Dwivedi 16284eb02f7SAnkur Dwivedi /* 16384eb02f7SAnkur Dwivedi * Clear doorbell overflow interrupt of the VF 16484eb02f7SAnkur Dwivedi * 16584eb02f7SAnkur Dwivedi * @param cptvf cptvf structure 16684eb02f7SAnkur Dwivedi */ 16784eb02f7SAnkur Dwivedi static void 16884eb02f7SAnkur Dwivedi otx_cpt_clear_dovf_intr(struct cpt_vf *cptvf) 16984eb02f7SAnkur Dwivedi { 17084eb02f7SAnkur Dwivedi cptx_vqx_misc_int_t vqx_misc_int; 17184eb02f7SAnkur Dwivedi 17284eb02f7SAnkur Dwivedi vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 17384eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0)); 17484eb02f7SAnkur Dwivedi /* W1C for the VF */ 17584eb02f7SAnkur Dwivedi vqx_misc_int.s.dovf = 1; 17684eb02f7SAnkur Dwivedi CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 17784eb02f7SAnkur Dwivedi CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u); 17884eb02f7SAnkur Dwivedi } 17984eb02f7SAnkur Dwivedi 1800dc1cffaSAnkur Dwivedi void 1810dc1cffaSAnkur Dwivedi otx_cpt_poll_misc(struct cpt_vf *cptvf) 1820dc1cffaSAnkur Dwivedi { 18384eb02f7SAnkur Dwivedi uint64_t intr; 18484eb02f7SAnkur Dwivedi 18584eb02f7SAnkur Dwivedi intr = otx_cpt_read_vf_misc_intr_status(cptvf); 18684eb02f7SAnkur Dwivedi 18784eb02f7SAnkur Dwivedi if (!intr) 18884eb02f7SAnkur Dwivedi return; 18984eb02f7SAnkur Dwivedi 19084eb02f7SAnkur Dwivedi /* Check for MISC interrupt types */ 19184eb02f7SAnkur Dwivedi if (likely(intr & CPT_VF_INTR_MBOX_MASK)) { 19284eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Mailbox interrupt 0x%lx on CPT VF %d", 19384eb02f7SAnkur Dwivedi cptvf->dev_name, (unsigned int long)intr, cptvf->vfid); 194ae500541SMurthy NSSR otx_cpt_handle_mbox_intr(cptvf); 19584eb02f7SAnkur Dwivedi otx_cpt_clear_mbox_intr(cptvf); 19684eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_IRDE_MASK)) { 19784eb02f7SAnkur Dwivedi otx_cpt_clear_irde_intr(cptvf); 19884eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Instruction NCB read error interrupt " 19984eb02f7SAnkur Dwivedi "0x%lx on CPT VF %d", cptvf->dev_name, 20084eb02f7SAnkur Dwivedi (unsigned int long)intr, cptvf->vfid); 20184eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_NWRP_MASK)) { 20284eb02f7SAnkur Dwivedi otx_cpt_clear_nwrp_intr(cptvf); 20384eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: NCB response write error interrupt 0x%lx" 20484eb02f7SAnkur Dwivedi " on CPT VF %d", cptvf->dev_name, 20584eb02f7SAnkur Dwivedi (unsigned int long)intr, cptvf->vfid); 20684eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_SWERR_MASK)) { 20784eb02f7SAnkur Dwivedi otx_cpt_clear_swerr_intr(cptvf); 20884eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Software error interrupt 0x%lx on CPT VF " 20984eb02f7SAnkur Dwivedi "%d", cptvf->dev_name, (unsigned int long)intr, 21084eb02f7SAnkur Dwivedi cptvf->vfid); 21184eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_HWERR_MASK)) { 21284eb02f7SAnkur Dwivedi otx_cpt_clear_hwerr_intr(cptvf); 21384eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Hardware error interrupt 0x%lx on CPT VF " 21484eb02f7SAnkur Dwivedi "%d", cptvf->dev_name, (unsigned int long)intr, 21584eb02f7SAnkur Dwivedi cptvf->vfid); 21684eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_FAULT_MASK)) { 21784eb02f7SAnkur Dwivedi otx_cpt_clear_fault_intr(cptvf); 21884eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Translation fault interrupt 0x%lx on CPT VF " 21984eb02f7SAnkur Dwivedi "%d", cptvf->dev_name, (unsigned int long)intr, 22084eb02f7SAnkur Dwivedi cptvf->vfid); 22184eb02f7SAnkur Dwivedi } else if (unlikely(intr & CPT_VF_INTR_DOVF_MASK)) { 22284eb02f7SAnkur Dwivedi otx_cpt_clear_dovf_intr(cptvf); 22384eb02f7SAnkur Dwivedi CPT_LOG_DP_DEBUG("%s: Doorbell overflow interrupt 0x%lx on CPT VF " 22484eb02f7SAnkur Dwivedi "%d", cptvf->dev_name, (unsigned int long)intr, 22584eb02f7SAnkur Dwivedi cptvf->vfid); 22684eb02f7SAnkur Dwivedi } else 22784eb02f7SAnkur Dwivedi CPT_LOG_DP_ERR("%s: Unhandled interrupt 0x%lx in CPT VF %d", 22884eb02f7SAnkur Dwivedi cptvf->dev_name, (unsigned int long)intr, 22984eb02f7SAnkur Dwivedi cptvf->vfid); 2300dc1cffaSAnkur Dwivedi } 2310dc1cffaSAnkur Dwivedi 2320dc1cffaSAnkur Dwivedi int 2330dc1cffaSAnkur Dwivedi otx_cpt_hw_init(struct cpt_vf *cptvf, void *pdev, void *reg_base, char *name) 2340dc1cffaSAnkur Dwivedi { 2350dc1cffaSAnkur Dwivedi memset(cptvf, 0, sizeof(struct cpt_vf)); 2360dc1cffaSAnkur Dwivedi 2370dc1cffaSAnkur Dwivedi /* Bar0 base address */ 2380dc1cffaSAnkur Dwivedi cptvf->reg_base = reg_base; 2390dc1cffaSAnkur Dwivedi strncpy(cptvf->dev_name, name, 32); 2400dc1cffaSAnkur Dwivedi 2410dc1cffaSAnkur Dwivedi cptvf->pdev = pdev; 2420dc1cffaSAnkur Dwivedi 2430dc1cffaSAnkur Dwivedi /* To clear if there are any pending mbox msgs */ 2440dc1cffaSAnkur Dwivedi otx_cpt_poll_misc(cptvf); 2450dc1cffaSAnkur Dwivedi 2460dc1cffaSAnkur Dwivedi if (otx_cpt_vf_init(cptvf)) { 2470dc1cffaSAnkur Dwivedi CPT_LOG_ERR("Failed to initialize CPT VF device"); 2480dc1cffaSAnkur Dwivedi return -1; 2490dc1cffaSAnkur Dwivedi } 2500dc1cffaSAnkur Dwivedi 2510dc1cffaSAnkur Dwivedi return 0; 2520dc1cffaSAnkur Dwivedi } 253273487f7SAnoob Joseph 254273487f7SAnoob Joseph int 255273487f7SAnoob Joseph otx_cpt_deinit_device(void *dev) 256273487f7SAnoob Joseph { 257273487f7SAnoob Joseph struct cpt_vf *cptvf = (struct cpt_vf *)dev; 258273487f7SAnoob Joseph 259273487f7SAnoob Joseph /* Do misc work one last time */ 260273487f7SAnoob Joseph otx_cpt_poll_misc(cptvf); 261273487f7SAnoob Joseph 262273487f7SAnoob Joseph return 0; 263273487f7SAnoob Joseph } 264*0906b99fSMurthy NSSR 265*0906b99fSMurthy NSSR int 266*0906b99fSMurthy NSSR otx_cpt_start_device(void *dev) 267*0906b99fSMurthy NSSR { 268*0906b99fSMurthy NSSR int rc; 269*0906b99fSMurthy NSSR struct cpt_vf *cptvf = (struct cpt_vf *)dev; 270*0906b99fSMurthy NSSR 271*0906b99fSMurthy NSSR rc = otx_cpt_send_vf_up(cptvf); 272*0906b99fSMurthy NSSR if (rc) { 273*0906b99fSMurthy NSSR CPT_LOG_ERR("Failed to mark CPT VF device %s UP, rc = %d", 274*0906b99fSMurthy NSSR cptvf->dev_name, rc); 275*0906b99fSMurthy NSSR return -EFAULT; 276*0906b99fSMurthy NSSR } 277*0906b99fSMurthy NSSR 278*0906b99fSMurthy NSSR if ((cptvf->vftype != SE_TYPE) && (cptvf->vftype != AE_TYPE)) { 279*0906b99fSMurthy NSSR CPT_LOG_ERR("Fatal error, unexpected vf type %u, for CPT VF " 280*0906b99fSMurthy NSSR "device %s", cptvf->vftype, cptvf->dev_name); 281*0906b99fSMurthy NSSR return -ENOENT; 282*0906b99fSMurthy NSSR } 283*0906b99fSMurthy NSSR 284*0906b99fSMurthy NSSR return 0; 285*0906b99fSMurthy NSSR } 286*0906b99fSMurthy NSSR 287*0906b99fSMurthy NSSR void 288*0906b99fSMurthy NSSR otx_cpt_stop_device(void *dev) 289*0906b99fSMurthy NSSR { 290*0906b99fSMurthy NSSR int rc; 291*0906b99fSMurthy NSSR uint32_t pending, retries = 5; 292*0906b99fSMurthy NSSR struct cpt_vf *cptvf = (struct cpt_vf *)dev; 293*0906b99fSMurthy NSSR 294*0906b99fSMurthy NSSR /* Wait for pending entries to complete */ 295*0906b99fSMurthy NSSR pending = otx_cpt_read_vq_doorbell(cptvf); 296*0906b99fSMurthy NSSR while (pending) { 297*0906b99fSMurthy NSSR CPT_LOG_DP_DEBUG("%s: Waiting for pending %u cmds to complete", 298*0906b99fSMurthy NSSR cptvf->dev_name, pending); 299*0906b99fSMurthy NSSR sleep(1); 300*0906b99fSMurthy NSSR pending = otx_cpt_read_vq_doorbell(cptvf); 301*0906b99fSMurthy NSSR retries--; 302*0906b99fSMurthy NSSR if (!retries) 303*0906b99fSMurthy NSSR break; 304*0906b99fSMurthy NSSR } 305*0906b99fSMurthy NSSR 306*0906b99fSMurthy NSSR if (!retries && pending) { 307*0906b99fSMurthy NSSR CPT_LOG_ERR("%s: Timeout waiting for commands(%u)", 308*0906b99fSMurthy NSSR cptvf->dev_name, pending); 309*0906b99fSMurthy NSSR return; 310*0906b99fSMurthy NSSR } 311*0906b99fSMurthy NSSR 312*0906b99fSMurthy NSSR rc = otx_cpt_send_vf_down(cptvf); 313*0906b99fSMurthy NSSR if (rc) { 314*0906b99fSMurthy NSSR CPT_LOG_ERR("Failed to bring down vf %s, rc %d", 315*0906b99fSMurthy NSSR cptvf->dev_name, rc); 316*0906b99fSMurthy NSSR return; 317*0906b99fSMurthy NSSR } 318*0906b99fSMurthy NSSR } 319