1*a4b16dadSTom Zanussi // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2*a4b16dadSTom Zanussi /* Copyright(c) 2015 - 2021 Intel Corporation */
3*a4b16dadSTom Zanussi #include <linux/bitfield.h>
4*a4b16dadSTom Zanussi #include <linux/completion.h>
5*a4b16dadSTom Zanussi #include <linux/minmax.h>
6*a4b16dadSTom Zanussi #include <linux/types.h>
7*a4b16dadSTom Zanussi #include "adf_accel_devices.h"
8*a4b16dadSTom Zanussi #include "adf_common_drv.h"
9*a4b16dadSTom Zanussi #include "adf_pfvf_msg.h"
10*a4b16dadSTom Zanussi #include "adf_pfvf_utils.h"
11*a4b16dadSTom Zanussi #include "adf_pfvf_vf_msg.h"
12*a4b16dadSTom Zanussi #include "adf_pfvf_vf_proto.h"
13*a4b16dadSTom Zanussi 
14*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_COLLISION_DETECT_DELAY	10
15*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_ACK_DELAY			2
16*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_ACK_MAX_RETRY		100
17*a4b16dadSTom Zanussi 
18*a4b16dadSTom Zanussi /* How often to retry if there is no response */
19*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_RESP_RETRIES	5
20*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_RESP_TIMEOUT	(ADF_PFVF_MSG_ACK_DELAY * \
21*a4b16dadSTom Zanussi 					 ADF_PFVF_MSG_ACK_MAX_RETRY + \
22*a4b16dadSTom Zanussi 					 ADF_PFVF_MSG_COLLISION_DETECT_DELAY)
23*a4b16dadSTom Zanussi 
24*a4b16dadSTom Zanussi /**
25*a4b16dadSTom Zanussi  * adf_send_vf2pf_msg() - send VF to PF message
26*a4b16dadSTom Zanussi  * @accel_dev:	Pointer to acceleration device
27*a4b16dadSTom Zanussi  * @msg:	Message to send
28*a4b16dadSTom Zanussi  *
29*a4b16dadSTom Zanussi  * This function allows the VF to send a message to the PF.
30*a4b16dadSTom Zanussi  *
31*a4b16dadSTom Zanussi  * Return: 0 on success, error code otherwise.
32*a4b16dadSTom Zanussi  */
adf_send_vf2pf_msg(struct adf_accel_dev * accel_dev,struct pfvf_message msg)33*a4b16dadSTom Zanussi int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg)
34*a4b16dadSTom Zanussi {
35*a4b16dadSTom Zanussi 	struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
36*a4b16dadSTom Zanussi 	u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0);
37*a4b16dadSTom Zanussi 
38*a4b16dadSTom Zanussi 	return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset,
39*a4b16dadSTom Zanussi 				  &accel_dev->vf.vf2pf_lock);
40*a4b16dadSTom Zanussi }
41*a4b16dadSTom Zanussi 
42*a4b16dadSTom Zanussi /**
43*a4b16dadSTom Zanussi  * adf_recv_pf2vf_msg() - receive a PF to VF message
44*a4b16dadSTom Zanussi  * @accel_dev:	Pointer to acceleration device
45*a4b16dadSTom Zanussi  *
46*a4b16dadSTom Zanussi  * This function allows the VF to receive a message from the PF.
47*a4b16dadSTom Zanussi  *
48*a4b16dadSTom Zanussi  * Return: a valid message on success, zero otherwise.
49*a4b16dadSTom Zanussi  */
adf_recv_pf2vf_msg(struct adf_accel_dev * accel_dev)50*a4b16dadSTom Zanussi static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
51*a4b16dadSTom Zanussi {
52*a4b16dadSTom Zanussi 	struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
53*a4b16dadSTom Zanussi 	u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);
54*a4b16dadSTom Zanussi 
55*a4b16dadSTom Zanussi 	return pfvf_ops->recv_msg(accel_dev, pfvf_offset, accel_dev->vf.pf_compat_ver);
56*a4b16dadSTom Zanussi }
57*a4b16dadSTom Zanussi 
58*a4b16dadSTom Zanussi /**
59*a4b16dadSTom Zanussi  * adf_send_vf2pf_req() - send VF2PF request message
60*a4b16dadSTom Zanussi  * @accel_dev:	Pointer to acceleration device.
61*a4b16dadSTom Zanussi  * @msg:	Request message to send
62*a4b16dadSTom Zanussi  * @resp:	Returned PF response
63*a4b16dadSTom Zanussi  *
64*a4b16dadSTom Zanussi  * This function sends a message that requires a response from the VF to the PF
65*a4b16dadSTom Zanussi  * and waits for a reply.
66*a4b16dadSTom Zanussi  *
67*a4b16dadSTom Zanussi  * Return: 0 on success, error code otherwise.
68*a4b16dadSTom Zanussi  */
adf_send_vf2pf_req(struct adf_accel_dev * accel_dev,struct pfvf_message msg,struct pfvf_message * resp)69*a4b16dadSTom Zanussi int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
70*a4b16dadSTom Zanussi 		       struct pfvf_message *resp)
71*a4b16dadSTom Zanussi {
72*a4b16dadSTom Zanussi 	unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT);
73*a4b16dadSTom Zanussi 	unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES;
74*a4b16dadSTom Zanussi 	int ret;
75*a4b16dadSTom Zanussi 
76*a4b16dadSTom Zanussi 	reinit_completion(&accel_dev->vf.msg_received);
77*a4b16dadSTom Zanussi 
78*a4b16dadSTom Zanussi 	/* Send request from VF to PF */
79*a4b16dadSTom Zanussi 	do {
80*a4b16dadSTom Zanussi 		ret = adf_send_vf2pf_msg(accel_dev, msg);
81*a4b16dadSTom Zanussi 		if (ret) {
82*a4b16dadSTom Zanussi 			dev_err(&GET_DEV(accel_dev),
83*a4b16dadSTom Zanussi 				"Failed to send request msg to PF\n");
84*a4b16dadSTom Zanussi 			return ret;
85*a4b16dadSTom Zanussi 		}
86*a4b16dadSTom Zanussi 
87*a4b16dadSTom Zanussi 		/* Wait for response, if it times out retry */
88*a4b16dadSTom Zanussi 		ret = wait_for_completion_timeout(&accel_dev->vf.msg_received,
89*a4b16dadSTom Zanussi 						  timeout);
90*a4b16dadSTom Zanussi 		if (ret) {
91*a4b16dadSTom Zanussi 			if (likely(resp))
92*a4b16dadSTom Zanussi 				*resp = accel_dev->vf.response;
93*a4b16dadSTom Zanussi 
94*a4b16dadSTom Zanussi 			/* Once copied, set to an invalid value */
95*a4b16dadSTom Zanussi 			accel_dev->vf.response.type = 0;
96*a4b16dadSTom Zanussi 
97*a4b16dadSTom Zanussi 			return 0;
98*a4b16dadSTom Zanussi 		}
99*a4b16dadSTom Zanussi 
100*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev), "PFVF response message timeout\n");
101*a4b16dadSTom Zanussi 	} while (--retries);
102*a4b16dadSTom Zanussi 
103*a4b16dadSTom Zanussi 	return -EIO;
104*a4b16dadSTom Zanussi }
105*a4b16dadSTom Zanussi 
adf_vf2pf_blkmsg_data_req(struct adf_accel_dev * accel_dev,bool crc,u8 * type,u8 * data)106*a4b16dadSTom Zanussi static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
107*a4b16dadSTom Zanussi 				     u8 *type, u8 *data)
108*a4b16dadSTom Zanussi {
109*a4b16dadSTom Zanussi 	struct pfvf_message req = { 0 };
110*a4b16dadSTom Zanussi 	struct pfvf_message resp = { 0 };
111*a4b16dadSTom Zanussi 	u8 blk_type;
112*a4b16dadSTom Zanussi 	u8 blk_byte;
113*a4b16dadSTom Zanussi 	u8 msg_type;
114*a4b16dadSTom Zanussi 	u8 max_data;
115*a4b16dadSTom Zanussi 	int err;
116*a4b16dadSTom Zanussi 
117*a4b16dadSTom Zanussi 	/* Convert the block type to {small, medium, large} size category */
118*a4b16dadSTom Zanussi 	if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) {
119*a4b16dadSTom Zanussi 		msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ;
120*a4b16dadSTom Zanussi 		blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type);
121*a4b16dadSTom Zanussi 		blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data);
122*a4b16dadSTom Zanussi 		max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
123*a4b16dadSTom Zanussi 	} else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) {
124*a4b16dadSTom Zanussi 		msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ;
125*a4b16dadSTom Zanussi 		blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK,
126*a4b16dadSTom Zanussi 				      *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX);
127*a4b16dadSTom Zanussi 		blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data);
128*a4b16dadSTom Zanussi 		max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
129*a4b16dadSTom Zanussi 	} else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) {
130*a4b16dadSTom Zanussi 		msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ;
131*a4b16dadSTom Zanussi 		blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK,
132*a4b16dadSTom Zanussi 				      *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX);
133*a4b16dadSTom Zanussi 		blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data);
134*a4b16dadSTom Zanussi 		max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
135*a4b16dadSTom Zanussi 	} else {
136*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type);
137*a4b16dadSTom Zanussi 		return -EINVAL;
138*a4b16dadSTom Zanussi 	}
139*a4b16dadSTom Zanussi 
140*a4b16dadSTom Zanussi 	/* Sanity check */
141*a4b16dadSTom Zanussi 	if (*data > max_data) {
142*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
143*a4b16dadSTom Zanussi 			"Invalid byte %s %u for message type %u\n",
144*a4b16dadSTom Zanussi 			crc ? "count" : "index", *data, *type);
145*a4b16dadSTom Zanussi 		return -EINVAL;
146*a4b16dadSTom Zanussi 	}
147*a4b16dadSTom Zanussi 
148*a4b16dadSTom Zanussi 	/* Build the block message */
149*a4b16dadSTom Zanussi 	req.type = msg_type;
150*a4b16dadSTom Zanussi 	req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc);
151*a4b16dadSTom Zanussi 
152*a4b16dadSTom Zanussi 	err = adf_send_vf2pf_req(accel_dev, req, &resp);
153*a4b16dadSTom Zanussi 	if (err)
154*a4b16dadSTom Zanussi 		return err;
155*a4b16dadSTom Zanussi 
156*a4b16dadSTom Zanussi 	*type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data);
157*a4b16dadSTom Zanussi 	*data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data);
158*a4b16dadSTom Zanussi 
159*a4b16dadSTom Zanussi 	return 0;
160*a4b16dadSTom Zanussi }
161*a4b16dadSTom Zanussi 
adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev * accel_dev,u8 type,u8 index,u8 * data)162*a4b16dadSTom Zanussi static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type,
163*a4b16dadSTom Zanussi 				     u8 index, u8 *data)
164*a4b16dadSTom Zanussi {
165*a4b16dadSTom Zanussi 	int ret;
166*a4b16dadSTom Zanussi 
167*a4b16dadSTom Zanussi 	ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index);
168*a4b16dadSTom Zanussi 	if (ret < 0)
169*a4b16dadSTom Zanussi 		return ret;
170*a4b16dadSTom Zanussi 
171*a4b16dadSTom Zanussi 	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) {
172*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
173*a4b16dadSTom Zanussi 			"Unexpected BLKMSG response type %u, byte 0x%x\n",
174*a4b16dadSTom Zanussi 			type, index);
175*a4b16dadSTom Zanussi 		return -EFAULT;
176*a4b16dadSTom Zanussi 	}
177*a4b16dadSTom Zanussi 
178*a4b16dadSTom Zanussi 	*data = index;
179*a4b16dadSTom Zanussi 	return 0;
180*a4b16dadSTom Zanussi }
181*a4b16dadSTom Zanussi 
adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev * accel_dev,u8 type,u8 bytes,u8 * crc)182*a4b16dadSTom Zanussi static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type,
183*a4b16dadSTom Zanussi 				    u8 bytes, u8 *crc)
184*a4b16dadSTom Zanussi {
185*a4b16dadSTom Zanussi 	int ret;
186*a4b16dadSTom Zanussi 
187*a4b16dadSTom Zanussi 	/* The count of bytes refers to a length, however shift it to a 0-based
188*a4b16dadSTom Zanussi 	 * count to avoid overflows. Thus, a request for 0 bytes is technically
189*a4b16dadSTom Zanussi 	 * valid.
190*a4b16dadSTom Zanussi 	 */
191*a4b16dadSTom Zanussi 	--bytes;
192*a4b16dadSTom Zanussi 
193*a4b16dadSTom Zanussi 	ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes);
194*a4b16dadSTom Zanussi 	if (ret < 0)
195*a4b16dadSTom Zanussi 		return ret;
196*a4b16dadSTom Zanussi 
197*a4b16dadSTom Zanussi 	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) {
198*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
199*a4b16dadSTom Zanussi 			"Unexpected CRC BLKMSG response type %u, crc 0x%x\n",
200*a4b16dadSTom Zanussi 			type, bytes);
201*a4b16dadSTom Zanussi 		return  -EFAULT;
202*a4b16dadSTom Zanussi 	}
203*a4b16dadSTom Zanussi 
204*a4b16dadSTom Zanussi 	*crc = bytes;
205*a4b16dadSTom Zanussi 	return 0;
206*a4b16dadSTom Zanussi }
207*a4b16dadSTom Zanussi 
208*a4b16dadSTom Zanussi /**
209*a4b16dadSTom Zanussi  * adf_send_vf2pf_blkmsg_req() - retrieve block message
210*a4b16dadSTom Zanussi  * @accel_dev:	Pointer to acceleration VF device.
211*a4b16dadSTom Zanussi  * @type:	The block message type, see adf_pfvf_msg.h for allowed values
212*a4b16dadSTom Zanussi  * @buffer:	input buffer where to place the received data
213*a4b16dadSTom Zanussi  * @buffer_len:	buffer length as input, the amount of written bytes on output
214*a4b16dadSTom Zanussi  *
215*a4b16dadSTom Zanussi  * Request a message of type 'type' over the block message transport.
216*a4b16dadSTom Zanussi  * This function will send the required amount block message requests and
217*a4b16dadSTom Zanussi  * return the overall content back to the caller through the provided buffer.
218*a4b16dadSTom Zanussi  * The buffer should be large enough to contain the requested message type,
219*a4b16dadSTom Zanussi  * otherwise the response will be truncated.
220*a4b16dadSTom Zanussi  *
221*a4b16dadSTom Zanussi  * Return: 0 on success, error code otherwise.
222*a4b16dadSTom Zanussi  */
adf_send_vf2pf_blkmsg_req(struct adf_accel_dev * accel_dev,u8 type,u8 * buffer,unsigned int * buffer_len)223*a4b16dadSTom Zanussi int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
224*a4b16dadSTom Zanussi 			      u8 *buffer, unsigned int *buffer_len)
225*a4b16dadSTom Zanussi {
226*a4b16dadSTom Zanussi 	unsigned int index;
227*a4b16dadSTom Zanussi 	unsigned int msg_len;
228*a4b16dadSTom Zanussi 	int ret;
229*a4b16dadSTom Zanussi 	u8 remote_crc;
230*a4b16dadSTom Zanussi 	u8 local_crc;
231*a4b16dadSTom Zanussi 
232*a4b16dadSTom Zanussi 	if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) {
233*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n",
234*a4b16dadSTom Zanussi 			type);
235*a4b16dadSTom Zanussi 		return -EINVAL;
236*a4b16dadSTom Zanussi 	}
237*a4b16dadSTom Zanussi 
238*a4b16dadSTom Zanussi 	if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) {
239*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
240*a4b16dadSTom Zanussi 			"Buffer size too small for a block message\n");
241*a4b16dadSTom Zanussi 		return -EINVAL;
242*a4b16dadSTom Zanussi 	}
243*a4b16dadSTom Zanussi 
244*a4b16dadSTom Zanussi 	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
245*a4b16dadSTom Zanussi 					ADF_PFVF_BLKMSG_VER_BYTE,
246*a4b16dadSTom Zanussi 					&buffer[ADF_PFVF_BLKMSG_VER_BYTE]);
247*a4b16dadSTom Zanussi 	if (unlikely(ret))
248*a4b16dadSTom Zanussi 		return ret;
249*a4b16dadSTom Zanussi 
250*a4b16dadSTom Zanussi 	if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) {
251*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
252*a4b16dadSTom Zanussi 			"Invalid version 0 received for block request %u", type);
253*a4b16dadSTom Zanussi 		return -EFAULT;
254*a4b16dadSTom Zanussi 	}
255*a4b16dadSTom Zanussi 
256*a4b16dadSTom Zanussi 	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
257*a4b16dadSTom Zanussi 					ADF_PFVF_BLKMSG_LEN_BYTE,
258*a4b16dadSTom Zanussi 					&buffer[ADF_PFVF_BLKMSG_LEN_BYTE]);
259*a4b16dadSTom Zanussi 	if (unlikely(ret))
260*a4b16dadSTom Zanussi 		return ret;
261*a4b16dadSTom Zanussi 
262*a4b16dadSTom Zanussi 	if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) {
263*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
264*a4b16dadSTom Zanussi 			"Invalid size 0 received for block request %u", type);
265*a4b16dadSTom Zanussi 		return -EFAULT;
266*a4b16dadSTom Zanussi 	}
267*a4b16dadSTom Zanussi 
268*a4b16dadSTom Zanussi 	/* We need to pick the minimum since there is no way to request a
269*a4b16dadSTom Zanussi 	 * specific version. As a consequence any scenario is possible:
270*a4b16dadSTom Zanussi 	 * - PF has a newer (longer) version which doesn't fit in the buffer
271*a4b16dadSTom Zanussi 	 * - VF expects a newer (longer) version, so we must not ask for
272*a4b16dadSTom Zanussi 	 *   bytes in excess
273*a4b16dadSTom Zanussi 	 * - PF and VF share the same version, no problem
274*a4b16dadSTom Zanussi 	 */
275*a4b16dadSTom Zanussi 	msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE];
276*a4b16dadSTom Zanussi 	msg_len = min(*buffer_len, msg_len);
277*a4b16dadSTom Zanussi 
278*a4b16dadSTom Zanussi 	/* Get the payload */
279*a4b16dadSTom Zanussi 	for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) {
280*a4b16dadSTom Zanussi 		ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index,
281*a4b16dadSTom Zanussi 						&buffer[index]);
282*a4b16dadSTom Zanussi 		if (unlikely(ret))
283*a4b16dadSTom Zanussi 			return ret;
284*a4b16dadSTom Zanussi 	}
285*a4b16dadSTom Zanussi 
286*a4b16dadSTom Zanussi 	ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc);
287*a4b16dadSTom Zanussi 	if (unlikely(ret))
288*a4b16dadSTom Zanussi 		return ret;
289*a4b16dadSTom Zanussi 
290*a4b16dadSTom Zanussi 	local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len);
291*a4b16dadSTom Zanussi 	if (unlikely(local_crc != remote_crc)) {
292*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
293*a4b16dadSTom Zanussi 			"CRC error on msg type %d. Local %02X, remote %02X\n",
294*a4b16dadSTom Zanussi 			type, local_crc, remote_crc);
295*a4b16dadSTom Zanussi 		return -EIO;
296*a4b16dadSTom Zanussi 	}
297*a4b16dadSTom Zanussi 
298*a4b16dadSTom Zanussi 	*buffer_len = msg_len;
299*a4b16dadSTom Zanussi 	return 0;
300*a4b16dadSTom Zanussi }
301*a4b16dadSTom Zanussi 
adf_handle_pf2vf_msg(struct adf_accel_dev * accel_dev,struct pfvf_message msg)302*a4b16dadSTom Zanussi static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
303*a4b16dadSTom Zanussi 				 struct pfvf_message msg)
304*a4b16dadSTom Zanussi {
305*a4b16dadSTom Zanussi 	switch (msg.type) {
306*a4b16dadSTom Zanussi 	case ADF_PF2VF_MSGTYPE_RESTARTING:
307*a4b16dadSTom Zanussi 		dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n");
308*a4b16dadSTom Zanussi 
309*a4b16dadSTom Zanussi 		adf_pf2vf_handle_pf_restarting(accel_dev);
310*a4b16dadSTom Zanussi 		return false;
311*a4b16dadSTom Zanussi 	case ADF_PF2VF_MSGTYPE_VERSION_RESP:
312*a4b16dadSTom Zanussi 	case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
313*a4b16dadSTom Zanussi 	case ADF_PF2VF_MSGTYPE_RP_RESET_RESP:
314*a4b16dadSTom Zanussi 		dev_dbg(&GET_DEV(accel_dev),
315*a4b16dadSTom Zanussi 			"Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
316*a4b16dadSTom Zanussi 			msg.type, msg.data);
317*a4b16dadSTom Zanussi 		accel_dev->vf.response = msg;
318*a4b16dadSTom Zanussi 		complete(&accel_dev->vf.msg_received);
319*a4b16dadSTom Zanussi 		return true;
320*a4b16dadSTom Zanussi 	default:
321*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
322*a4b16dadSTom Zanussi 			"Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n",
323*a4b16dadSTom Zanussi 			msg.type, msg.data);
324*a4b16dadSTom Zanussi 	}
325*a4b16dadSTom Zanussi 
326*a4b16dadSTom Zanussi 	return false;
327*a4b16dadSTom Zanussi }
328*a4b16dadSTom Zanussi 
adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev * accel_dev)329*a4b16dadSTom Zanussi bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
330*a4b16dadSTom Zanussi {
331*a4b16dadSTom Zanussi 	struct pfvf_message msg;
332*a4b16dadSTom Zanussi 
333*a4b16dadSTom Zanussi 	msg = adf_recv_pf2vf_msg(accel_dev);
334*a4b16dadSTom Zanussi 	if (msg.type)  /* Invalid or no message */
335*a4b16dadSTom Zanussi 		return adf_handle_pf2vf_msg(accel_dev, msg);
336*a4b16dadSTom Zanussi 
337*a4b16dadSTom Zanussi 	/* No replies for PF->VF messages at present */
338*a4b16dadSTom Zanussi 
339*a4b16dadSTom Zanussi 	return true;
340*a4b16dadSTom Zanussi }
341*a4b16dadSTom Zanussi 
342*a4b16dadSTom Zanussi /**
343*a4b16dadSTom Zanussi  * adf_enable_vf2pf_comms() - Function enables communication from vf to pf
344*a4b16dadSTom Zanussi  *
345*a4b16dadSTom Zanussi  * @accel_dev:	Pointer to acceleration device virtual function.
346*a4b16dadSTom Zanussi  *
347*a4b16dadSTom Zanussi  * Return: 0 on success, error code otherwise.
348*a4b16dadSTom Zanussi  */
adf_enable_vf2pf_comms(struct adf_accel_dev * accel_dev)349*a4b16dadSTom Zanussi int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
350*a4b16dadSTom Zanussi {
351*a4b16dadSTom Zanussi 	int ret;
352*a4b16dadSTom Zanussi 
353*a4b16dadSTom Zanussi 	adf_pfvf_crc_init();
354*a4b16dadSTom Zanussi 	adf_enable_pf2vf_interrupts(accel_dev);
355*a4b16dadSTom Zanussi 
356*a4b16dadSTom Zanussi 	ret = adf_vf2pf_request_version(accel_dev);
357*a4b16dadSTom Zanussi 	if (ret)
358*a4b16dadSTom Zanussi 		return ret;
359*a4b16dadSTom Zanussi 
360*a4b16dadSTom Zanussi 	ret = adf_vf2pf_get_capabilities(accel_dev);
361*a4b16dadSTom Zanussi 	if (ret)
362*a4b16dadSTom Zanussi 		return ret;
363*a4b16dadSTom Zanussi 
364*a4b16dadSTom Zanussi 	ret = adf_vf2pf_get_ring_to_svc(accel_dev);
365*a4b16dadSTom Zanussi 
366*a4b16dadSTom Zanussi 	return ret;
367*a4b16dadSTom Zanussi }
368*a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms);
369