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 "adf_accel_devices.h"
5*a4b16dadSTom Zanussi #include "adf_common_drv.h"
6*a4b16dadSTom Zanussi #include "adf_pfvf_msg.h"
7*a4b16dadSTom Zanussi #include "adf_pfvf_vf_msg.h"
8*a4b16dadSTom Zanussi #include "adf_pfvf_vf_proto.h"
9*a4b16dadSTom Zanussi 
10*a4b16dadSTom Zanussi /**
11*a4b16dadSTom Zanussi  * adf_vf2pf_notify_init() - send init msg to PF
12*a4b16dadSTom Zanussi  * @accel_dev:  Pointer to acceleration VF device.
13*a4b16dadSTom Zanussi  *
14*a4b16dadSTom Zanussi  * Function sends an init message from the VF to a PF
15*a4b16dadSTom Zanussi  *
16*a4b16dadSTom Zanussi  * Return: 0 on success, error code otherwise.
17*a4b16dadSTom Zanussi  */
adf_vf2pf_notify_init(struct adf_accel_dev * accel_dev)18*a4b16dadSTom Zanussi int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
19*a4b16dadSTom Zanussi {
20*a4b16dadSTom Zanussi 	struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT };
21*a4b16dadSTom Zanussi 
22*a4b16dadSTom Zanussi 	if (adf_send_vf2pf_msg(accel_dev, msg)) {
23*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
24*a4b16dadSTom Zanussi 			"Failed to send Init event to PF\n");
25*a4b16dadSTom Zanussi 		return -EFAULT;
26*a4b16dadSTom Zanussi 	}
27*a4b16dadSTom Zanussi 	set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
28*a4b16dadSTom Zanussi 	return 0;
29*a4b16dadSTom Zanussi }
30*a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init);
31*a4b16dadSTom Zanussi 
32*a4b16dadSTom Zanussi /**
33*a4b16dadSTom Zanussi  * adf_vf2pf_notify_shutdown() - send shutdown msg to PF
34*a4b16dadSTom Zanussi  * @accel_dev:  Pointer to acceleration VF device.
35*a4b16dadSTom Zanussi  *
36*a4b16dadSTom Zanussi  * Function sends a shutdown message from the VF to a PF
37*a4b16dadSTom Zanussi  *
38*a4b16dadSTom Zanussi  * Return: void
39*a4b16dadSTom Zanussi  */
adf_vf2pf_notify_shutdown(struct adf_accel_dev * accel_dev)40*a4b16dadSTom Zanussi void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
41*a4b16dadSTom Zanussi {
42*a4b16dadSTom Zanussi 	struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_SHUTDOWN };
43*a4b16dadSTom Zanussi 
44*a4b16dadSTom Zanussi 	if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status))
45*a4b16dadSTom Zanussi 		if (adf_send_vf2pf_msg(accel_dev, msg))
46*a4b16dadSTom Zanussi 			dev_err(&GET_DEV(accel_dev),
47*a4b16dadSTom Zanussi 				"Failed to send Shutdown event to PF\n");
48*a4b16dadSTom Zanussi }
49*a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown);
50*a4b16dadSTom Zanussi 
adf_vf2pf_request_version(struct adf_accel_dev * accel_dev)51*a4b16dadSTom Zanussi int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
52*a4b16dadSTom Zanussi {
53*a4b16dadSTom Zanussi 	u8 pf_version;
54*a4b16dadSTom Zanussi 	int compat;
55*a4b16dadSTom Zanussi 	int ret;
56*a4b16dadSTom Zanussi 	struct pfvf_message resp;
57*a4b16dadSTom Zanussi 	struct pfvf_message msg = {
58*a4b16dadSTom Zanussi 		.type = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ,
59*a4b16dadSTom Zanussi 		.data = ADF_PFVF_COMPAT_THIS_VERSION,
60*a4b16dadSTom Zanussi 	};
61*a4b16dadSTom Zanussi 
62*a4b16dadSTom Zanussi 	BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255);
63*a4b16dadSTom Zanussi 
64*a4b16dadSTom Zanussi 	ret = adf_send_vf2pf_req(accel_dev, msg, &resp);
65*a4b16dadSTom Zanussi 	if (ret) {
66*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
67*a4b16dadSTom Zanussi 			"Failed to send Compatibility Version Request.\n");
68*a4b16dadSTom Zanussi 		return ret;
69*a4b16dadSTom Zanussi 	}
70*a4b16dadSTom Zanussi 
71*a4b16dadSTom Zanussi 	pf_version = FIELD_GET(ADF_PF2VF_VERSION_RESP_VERS_MASK, resp.data);
72*a4b16dadSTom Zanussi 	compat = FIELD_GET(ADF_PF2VF_VERSION_RESP_RESULT_MASK, resp.data);
73*a4b16dadSTom Zanussi 
74*a4b16dadSTom Zanussi 	/* Response from PF received, check compatibility */
75*a4b16dadSTom Zanussi 	switch (compat) {
76*a4b16dadSTom Zanussi 	case ADF_PF2VF_VF_COMPATIBLE:
77*a4b16dadSTom Zanussi 		break;
78*a4b16dadSTom Zanussi 	case ADF_PF2VF_VF_COMPAT_UNKNOWN:
79*a4b16dadSTom Zanussi 		/* VF is newer than PF - compatible for now */
80*a4b16dadSTom Zanussi 		break;
81*a4b16dadSTom Zanussi 	case ADF_PF2VF_VF_INCOMPATIBLE:
82*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
83*a4b16dadSTom Zanussi 			"PF (vers %d) and VF (vers %d) are not compatible\n",
84*a4b16dadSTom Zanussi 			pf_version, ADF_PFVF_COMPAT_THIS_VERSION);
85*a4b16dadSTom Zanussi 		return -EINVAL;
86*a4b16dadSTom Zanussi 	default:
87*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
88*a4b16dadSTom Zanussi 			"Invalid response from PF; assume not compatible\n");
89*a4b16dadSTom Zanussi 		return -EINVAL;
90*a4b16dadSTom Zanussi 	}
91*a4b16dadSTom Zanussi 
92*a4b16dadSTom Zanussi 	accel_dev->vf.pf_compat_ver = pf_version;
93*a4b16dadSTom Zanussi 	return 0;
94*a4b16dadSTom Zanussi }
95*a4b16dadSTom Zanussi 
adf_vf2pf_get_capabilities(struct adf_accel_dev * accel_dev)96*a4b16dadSTom Zanussi int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)
97*a4b16dadSTom Zanussi {
98*a4b16dadSTom Zanussi 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
99*a4b16dadSTom Zanussi 	struct capabilities_v3 cap_msg = { 0 };
100*a4b16dadSTom Zanussi 	unsigned int len = sizeof(cap_msg);
101*a4b16dadSTom Zanussi 
102*a4b16dadSTom Zanussi 	if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES)
103*a4b16dadSTom Zanussi 		/* The PF is too old to support the extended capabilities */
104*a4b16dadSTom Zanussi 		return 0;
105*a4b16dadSTom Zanussi 
106*a4b16dadSTom Zanussi 	if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY,
107*a4b16dadSTom Zanussi 				      (u8 *)&cap_msg, &len)) {
108*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
109*a4b16dadSTom Zanussi 			"QAT: Failed to get block message response\n");
110*a4b16dadSTom Zanussi 		return -EFAULT;
111*a4b16dadSTom Zanussi 	}
112*a4b16dadSTom Zanussi 
113*a4b16dadSTom Zanussi 	switch (cap_msg.hdr.version) {
114*a4b16dadSTom Zanussi 	default:
115*a4b16dadSTom Zanussi 		/* Newer version received, handle only the know parts */
116*a4b16dadSTom Zanussi 		fallthrough;
117*a4b16dadSTom Zanussi 	case ADF_PFVF_CAPABILITIES_V3_VERSION:
118*a4b16dadSTom Zanussi 		if (likely(len >= sizeof(struct capabilities_v3)))
119*a4b16dadSTom Zanussi 			hw_data->clock_frequency = cap_msg.frequency;
120*a4b16dadSTom Zanussi 		else
121*a4b16dadSTom Zanussi 			dev_info(&GET_DEV(accel_dev), "Could not get frequency");
122*a4b16dadSTom Zanussi 		fallthrough;
123*a4b16dadSTom Zanussi 	case ADF_PFVF_CAPABILITIES_V2_VERSION:
124*a4b16dadSTom Zanussi 		if (likely(len >= sizeof(struct capabilities_v2)))
125*a4b16dadSTom Zanussi 			hw_data->accel_capabilities_mask = cap_msg.capabilities;
126*a4b16dadSTom Zanussi 		else
127*a4b16dadSTom Zanussi 			dev_info(&GET_DEV(accel_dev), "Could not get capabilities");
128*a4b16dadSTom Zanussi 		fallthrough;
129*a4b16dadSTom Zanussi 	case ADF_PFVF_CAPABILITIES_V1_VERSION:
130*a4b16dadSTom Zanussi 		if (likely(len >= sizeof(struct capabilities_v1))) {
131*a4b16dadSTom Zanussi 			hw_data->extended_dc_capabilities = cap_msg.ext_dc_caps;
132*a4b16dadSTom Zanussi 		} else {
133*a4b16dadSTom Zanussi 			dev_err(&GET_DEV(accel_dev),
134*a4b16dadSTom Zanussi 				"Capabilities message truncated to %d bytes\n", len);
135*a4b16dadSTom Zanussi 			return -EFAULT;
136*a4b16dadSTom Zanussi 		}
137*a4b16dadSTom Zanussi 	}
138*a4b16dadSTom Zanussi 
139*a4b16dadSTom Zanussi 	return 0;
140*a4b16dadSTom Zanussi }
141*a4b16dadSTom Zanussi 
adf_vf2pf_get_ring_to_svc(struct adf_accel_dev * accel_dev)142*a4b16dadSTom Zanussi int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev)
143*a4b16dadSTom Zanussi {
144*a4b16dadSTom Zanussi 	struct ring_to_svc_map_v1 rts_map_msg = { 0 };
145*a4b16dadSTom Zanussi 	unsigned int len = sizeof(rts_map_msg);
146*a4b16dadSTom Zanussi 
147*a4b16dadSTom Zanussi 	if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP)
148*a4b16dadSTom Zanussi 		/* Use already set default mappings */
149*a4b16dadSTom Zanussi 		return 0;
150*a4b16dadSTom Zanussi 
151*a4b16dadSTom Zanussi 	if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP,
152*a4b16dadSTom Zanussi 				      (u8 *)&rts_map_msg, &len)) {
153*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
154*a4b16dadSTom Zanussi 			"QAT: Failed to get block message response\n");
155*a4b16dadSTom Zanussi 		return -EFAULT;
156*a4b16dadSTom Zanussi 	}
157*a4b16dadSTom Zanussi 
158*a4b16dadSTom Zanussi 	if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) {
159*a4b16dadSTom Zanussi 		dev_err(&GET_DEV(accel_dev),
160*a4b16dadSTom Zanussi 			"RING_TO_SVC message truncated to %d bytes\n", len);
161*a4b16dadSTom Zanussi 		return -EFAULT;
162*a4b16dadSTom Zanussi 	}
163*a4b16dadSTom Zanussi 
164*a4b16dadSTom Zanussi 	/* Only v1 at present */
165*a4b16dadSTom Zanussi 	accel_dev->hw_device->ring_to_svc_map = rts_map_msg.map;
166*a4b16dadSTom Zanussi 	return 0;
167*a4b16dadSTom Zanussi }
168