xref: /dpdk/drivers/crypto/octeontx/otx_cryptodev_mbox.c (revision 13d711f353c109ca93f2649d0935660824f25176)
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
otx_cpt_handle_mbox_intr(struct cpt_vf * cptvf)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
otx_cpt_send_msg_to_pf(struct cpt_vf * cptvf,struct cpt_mbox * mbx)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
otx_cpt_send_msg_to_pf_timeout(struct cpt_vf * cptvf,struct cpt_mbox * mbx)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
otx_cpt_check_pf_ready(struct cpt_vf * cptvf)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
otx_cpt_get_dev_type(struct cpt_vf * cptvf)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
otx_cpt_send_vq_size_msg(struct cpt_vf * cptvf)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
otx_cpt_send_vf_grp_msg(struct cpt_vf * cptvf,uint32_t group)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
otx_cpt_send_vf_up(struct cpt_vf * cptvf)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
otx_cpt_send_vf_down(struct cpt_vf * cptvf)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