1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Cavium, Inc 3 */ 4 5 #include <unistd.h> 6 7 #include "otx_cryptodev_hw_access.h" 8 #include "otx_cryptodev_mbox.h" 9 10 void 11 otx_cpt_handle_mbox_intr(struct cpt_vf *cptvf) 12 { 13 struct cpt_mbox mbx = {0, 0}; 14 15 /* 16 * MBOX[0] contains msg 17 * MBOX[1] contains data 18 */ 19 mbx.msg = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 20 CPTX_VFX_PF_MBOXX(0, 0, 0)); 21 mbx.data = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), 22 CPTX_VFX_PF_MBOXX(0, 0, 1)); 23 24 CPT_LOG_DP_DEBUG("%s: Mailbox msg 0x%lx from PF", 25 cptvf->dev_name, (unsigned int long)mbx.msg); 26 switch (mbx.msg) { 27 case OTX_CPT_MSG_READY: 28 { 29 otx_cpt_chipid_vfid_t cid; 30 31 cid.u64 = mbx.data; 32 cptvf->pf_acked = true; 33 cptvf->vfid = cid.s.vfid; 34 CPT_LOG_DP_DEBUG("%s: Received VFID %d chip_id %d", 35 cptvf->dev_name, 36 cptvf->vfid, cid.s.chip_id); 37 } 38 break; 39 case OTX_CPT_MSG_QBIND_GRP: 40 cptvf->pf_acked = true; 41 cptvf->vftype = mbx.data; 42 CPT_LOG_DP_DEBUG("%s: VF %d type %s group %d", 43 cptvf->dev_name, cptvf->vfid, 44 ((mbx.data == SE_TYPE) ? "SE" : "AE"), 45 cptvf->vfgrp); 46 break; 47 case OTX_CPT_MBOX_MSG_TYPE_ACK: 48 cptvf->pf_acked = true; 49 break; 50 case OTX_CPT_MBOX_MSG_TYPE_NACK: 51 cptvf->pf_nacked = true; 52 break; 53 default: 54 CPT_LOG_DP_DEBUG("%s: Invalid msg from PF, msg 0x%lx", 55 cptvf->dev_name, (unsigned int long)mbx.msg); 56 break; 57 } 58 } 59 60 /* Send a mailbox message to PF 61 * @vf: vf from which this message to be sent 62 * @mbx: Message to be sent 63 */ 64 static void 65 otx_cpt_send_msg_to_pf(struct cpt_vf *cptvf, struct cpt_mbox *mbx) 66 { 67 /* Writing mbox(1) causes interrupt */ 68 CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 69 CPTX_VFX_PF_MBOXX(0, 0, 0), mbx->msg); 70 CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 71 CPTX_VFX_PF_MBOXX(0, 0, 1), mbx->data); 72 } 73 74 static int32_t 75 otx_cpt_send_msg_to_pf_timeout(struct cpt_vf *cptvf, struct cpt_mbox *mbx) 76 { 77 int timeout = OTX_CPT_MBOX_MSG_TIMEOUT; 78 int sleep_ms = 10; 79 80 cptvf->pf_acked = false; 81 cptvf->pf_nacked = false; 82 83 otx_cpt_send_msg_to_pf(cptvf, mbx); 84 85 /* Wait for previous message to be acked, timeout 2sec */ 86 while (!cptvf->pf_acked) { 87 if (cptvf->pf_nacked) 88 return -EINVAL; 89 usleep(sleep_ms * 1000); 90 otx_cpt_poll_misc(cptvf); 91 if (cptvf->pf_acked) 92 break; 93 timeout -= sleep_ms; 94 if (!timeout) { 95 CPT_LOG_ERR("%s: PF didn't ack mbox msg %lx(vfid %u)", 96 cptvf->dev_name, 97 (unsigned int long)(mbx->msg & 0xFF), 98 cptvf->vfid); 99 return -EBUSY; 100 } 101 } 102 return 0; 103 } 104 105 int 106 otx_cpt_check_pf_ready(struct cpt_vf *cptvf) 107 { 108 struct cpt_mbox mbx = {0, 0}; 109 110 mbx.msg = OTX_CPT_MSG_READY; 111 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 112 CPT_LOG_ERR("%s: PF didn't respond to READY msg", 113 cptvf->dev_name); 114 return 1; 115 } 116 return 0; 117 } 118 119 int 120 otx_cpt_send_vq_size_msg(struct cpt_vf *cptvf) 121 { 122 struct cpt_mbox mbx = {0, 0}; 123 124 mbx.msg = OTX_CPT_MSG_QLEN; 125 126 mbx.data = cptvf->qsize; 127 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 128 CPT_LOG_ERR("%s: PF didn't respond to vq_size msg", 129 cptvf->dev_name); 130 return 1; 131 } 132 return 0; 133 } 134 135 int 136 otx_cpt_send_vf_grp_msg(struct cpt_vf *cptvf, uint32_t group) 137 { 138 struct cpt_mbox mbx = {0, 0}; 139 140 mbx.msg = OTX_CPT_MSG_QBIND_GRP; 141 142 /* Convey group of the VF */ 143 mbx.data = group; 144 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 145 CPT_LOG_ERR("%s: PF didn't respond to vf_type msg", 146 cptvf->dev_name); 147 return 1; 148 } 149 return 0; 150 } 151 152 int 153 otx_cpt_send_vf_up(struct cpt_vf *cptvf) 154 { 155 struct cpt_mbox mbx = {0, 0}; 156 157 mbx.msg = OTX_CPT_MSG_VF_UP; 158 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 159 CPT_LOG_ERR("%s: PF didn't respond to UP msg", 160 cptvf->dev_name); 161 return 1; 162 } 163 return 0; 164 } 165 166 int 167 otx_cpt_send_vf_down(struct cpt_vf *cptvf) 168 { 169 struct cpt_mbox mbx = {0, 0}; 170 171 mbx.msg = OTX_CPT_MSG_VF_DOWN; 172 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 173 CPT_LOG_ERR("%s: PF didn't respond to DOWN msg", 174 cptvf->dev_name); 175 return 1; 176 } 177 return 0; 178 } 179