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