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_VF_UP: 28 cptvf->pf_acked = true; 29 break; 30 case OTX_CPT_MSG_READY: 31 { 32 otx_cpt_chipid_vfid_t cid; 33 34 cid.u64 = mbx.data; 35 cptvf->pf_acked = true; 36 cptvf->vfid = cid.s.vfid; 37 CPT_LOG_DP_DEBUG("%s: Received VFID %d chip_id %d", 38 cptvf->dev_name, 39 cptvf->vfid, cid.s.chip_id); 40 } 41 break; 42 case OTX_CPT_MSG_QBIND_GRP: 43 cptvf->pf_acked = true; 44 cptvf->vftype = mbx.data; 45 CPT_LOG_DP_DEBUG("%s: VF %d group %d", 46 cptvf->dev_name, cptvf->vfid, 47 cptvf->vfgrp); 48 break; 49 case OTX_CPT_MSG_PF_TYPE: 50 cptvf->pf_acked = true; 51 if (mbx.data == OTX_CPT_PF_TYPE_AE) 52 cptvf->vftype = OTX_CPT_VF_TYPE_AE; 53 else if (mbx.data == OTX_CPT_PF_TYPE_SE) 54 cptvf->vftype = OTX_CPT_VF_TYPE_SE; 55 else 56 cptvf->vftype = OTX_CPT_VF_TYPE_INVALID; 57 break; 58 case OTX_CPT_MBOX_MSG_TYPE_ACK: 59 cptvf->pf_acked = true; 60 break; 61 case OTX_CPT_MBOX_MSG_TYPE_NACK: 62 cptvf->pf_nacked = true; 63 break; 64 default: 65 CPT_LOG_DP_DEBUG("%s: Invalid msg from PF, msg 0x%lx", 66 cptvf->dev_name, (unsigned int long)mbx.msg); 67 break; 68 } 69 } 70 71 /* Send a mailbox message to PF 72 * @vf: vf from which this message to be sent 73 * @mbx: Message to be sent 74 */ 75 static void 76 otx_cpt_send_msg_to_pf(struct cpt_vf *cptvf, struct cpt_mbox *mbx) 77 { 78 /* Writing mbox(1) causes interrupt */ 79 CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 80 CPTX_VFX_PF_MBOXX(0, 0, 0), mbx->msg); 81 CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf), 82 CPTX_VFX_PF_MBOXX(0, 0, 1), mbx->data); 83 } 84 85 static int32_t 86 otx_cpt_send_msg_to_pf_timeout(struct cpt_vf *cptvf, struct cpt_mbox *mbx) 87 { 88 int timeout = OTX_CPT_MBOX_MSG_TIMEOUT; 89 int sleep_ms = 10; 90 91 cptvf->pf_acked = false; 92 cptvf->pf_nacked = false; 93 94 otx_cpt_send_msg_to_pf(cptvf, mbx); 95 96 /* Wait for previous message to be acked, timeout 2sec */ 97 while (!cptvf->pf_acked) { 98 if (cptvf->pf_nacked) 99 return -EINVAL; 100 usleep(sleep_ms * 1000); 101 otx_cpt_poll_misc(cptvf); 102 if (cptvf->pf_acked) 103 break; 104 timeout -= sleep_ms; 105 if (!timeout) { 106 CPT_LOG_ERR("%s: PF didn't ack mbox msg %lx(vfid %u)", 107 cptvf->dev_name, 108 (unsigned int long)(mbx->msg & 0xFF), 109 cptvf->vfid); 110 return -EBUSY; 111 } 112 } 113 return 0; 114 } 115 116 int 117 otx_cpt_check_pf_ready(struct cpt_vf *cptvf) 118 { 119 struct cpt_mbox mbx = {0, 0}; 120 121 mbx.msg = OTX_CPT_MSG_READY; 122 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 123 CPT_LOG_ERR("%s: PF didn't respond to READY msg", 124 cptvf->dev_name); 125 return 1; 126 } 127 return 0; 128 } 129 130 int 131 otx_cpt_get_dev_type(struct cpt_vf *cptvf) 132 { 133 struct cpt_mbox mbx = {0, 0}; 134 135 mbx.msg = OTX_CPT_MSG_PF_TYPE; 136 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 137 CPT_LOG_ERR("%s: PF didn't respond to query msg", 138 cptvf->dev_name); 139 return 1; 140 } 141 return 0; 142 } 143 144 int 145 otx_cpt_send_vq_size_msg(struct cpt_vf *cptvf) 146 { 147 struct cpt_mbox mbx = {0, 0}; 148 149 mbx.msg = OTX_CPT_MSG_QLEN; 150 151 mbx.data = cptvf->qsize; 152 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 153 CPT_LOG_ERR("%s: PF didn't respond to vq_size msg", 154 cptvf->dev_name); 155 return 1; 156 } 157 return 0; 158 } 159 160 int 161 otx_cpt_send_vf_grp_msg(struct cpt_vf *cptvf, uint32_t group) 162 { 163 struct cpt_mbox mbx = {0, 0}; 164 165 mbx.msg = OTX_CPT_MSG_QBIND_GRP; 166 167 /* Convey group of the VF */ 168 mbx.data = group; 169 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 170 CPT_LOG_ERR("%s: PF didn't respond to vf_type msg", 171 cptvf->dev_name); 172 return 1; 173 } 174 return 0; 175 } 176 177 int 178 otx_cpt_send_vf_up(struct cpt_vf *cptvf) 179 { 180 struct cpt_mbox mbx = {0, 0}; 181 182 mbx.msg = OTX_CPT_MSG_VF_UP; 183 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 184 CPT_LOG_ERR("%s: PF didn't respond to UP msg", 185 cptvf->dev_name); 186 return 1; 187 } 188 return 0; 189 } 190 191 int 192 otx_cpt_send_vf_down(struct cpt_vf *cptvf) 193 { 194 struct cpt_mbox mbx = {0, 0}; 195 196 mbx.msg = OTX_CPT_MSG_VF_DOWN; 197 if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) { 198 CPT_LOG_ERR("%s: PF didn't respond to DOWN msg", 199 cptvf->dev_name); 200 return 1; 201 } 202 return 0; 203 } 204