xref: /linux/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c (revision 44a8c96edd0ee9320a1ad87afc7b10f38e55d5ec)
1f0bbfc39SXin Zeng // SPDX-License-Identifier: GPL-2.0-only
2f0bbfc39SXin Zeng /* Copyright(c) 2024 Intel Corporation */
3f0bbfc39SXin Zeng #include <linux/delay.h>
4f0bbfc39SXin Zeng #include <linux/dev_printk.h>
5f0bbfc39SXin Zeng #include <linux/kernel.h>
6f0bbfc39SXin Zeng #include <linux/slab.h>
7f0bbfc39SXin Zeng #include <linux/string.h>
8f0bbfc39SXin Zeng #include <linux/types.h>
9f0bbfc39SXin Zeng #include <asm/errno.h>
10f0bbfc39SXin Zeng 
11f0bbfc39SXin Zeng #include "adf_accel_devices.h"
12*a47dc5d1SSuman Kumar Chakraborty #include "adf_bank_state.h"
13f0bbfc39SXin Zeng #include "adf_common_drv.h"
14f0bbfc39SXin Zeng #include "adf_gen4_hw_data.h"
15f0bbfc39SXin Zeng #include "adf_gen4_pfvf.h"
16f0bbfc39SXin Zeng #include "adf_pfvf_utils.h"
17f0bbfc39SXin Zeng #include "adf_mstate_mgr.h"
18f0bbfc39SXin Zeng #include "adf_gen4_vf_mig.h"
19f0bbfc39SXin Zeng 
20f0bbfc39SXin Zeng #define ADF_GEN4_VF_MSTATE_SIZE		4096
21f0bbfc39SXin Zeng #define ADF_GEN4_PFVF_RSP_TIMEOUT_US	5000
22f0bbfc39SXin Zeng 
23f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_setup(struct qat_mig_dev *mdev);
24f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_setup(struct qat_mig_dev *mdev, int len);
25f0bbfc39SXin Zeng 
adf_gen4_vfmig_init_device(struct qat_mig_dev * mdev)26f0bbfc39SXin Zeng static int adf_gen4_vfmig_init_device(struct qat_mig_dev *mdev)
27f0bbfc39SXin Zeng {
28f0bbfc39SXin Zeng 	u8 *state;
29f0bbfc39SXin Zeng 
30f0bbfc39SXin Zeng 	state = kmalloc(ADF_GEN4_VF_MSTATE_SIZE, GFP_KERNEL);
31f0bbfc39SXin Zeng 	if (!state)
32f0bbfc39SXin Zeng 		return -ENOMEM;
33f0bbfc39SXin Zeng 
34f0bbfc39SXin Zeng 	mdev->state = state;
35f0bbfc39SXin Zeng 	mdev->state_size = ADF_GEN4_VF_MSTATE_SIZE;
36f0bbfc39SXin Zeng 	mdev->setup_size = 0;
37f0bbfc39SXin Zeng 	mdev->remote_setup_size = 0;
38f0bbfc39SXin Zeng 
39f0bbfc39SXin Zeng 	return 0;
40f0bbfc39SXin Zeng }
41f0bbfc39SXin Zeng 
adf_gen4_vfmig_cleanup_device(struct qat_mig_dev * mdev)42f0bbfc39SXin Zeng static void adf_gen4_vfmig_cleanup_device(struct qat_mig_dev *mdev)
43f0bbfc39SXin Zeng {
44f0bbfc39SXin Zeng 	kfree(mdev->state);
45f0bbfc39SXin Zeng 	mdev->state = NULL;
46f0bbfc39SXin Zeng }
47f0bbfc39SXin Zeng 
adf_gen4_vfmig_reset_device(struct qat_mig_dev * mdev)48f0bbfc39SXin Zeng static void adf_gen4_vfmig_reset_device(struct qat_mig_dev *mdev)
49f0bbfc39SXin Zeng {
50f0bbfc39SXin Zeng 	mdev->setup_size = 0;
51f0bbfc39SXin Zeng 	mdev->remote_setup_size = 0;
52f0bbfc39SXin Zeng }
53f0bbfc39SXin Zeng 
adf_gen4_vfmig_open_device(struct qat_mig_dev * mdev)54f0bbfc39SXin Zeng static int adf_gen4_vfmig_open_device(struct qat_mig_dev *mdev)
55f0bbfc39SXin Zeng {
56f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
57f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
58f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
59f0bbfc39SXin Zeng 
60f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[mdev->vf_id];
61f0bbfc39SXin Zeng 
62f0bbfc39SXin Zeng 	vfmig = kzalloc(sizeof(*vfmig), GFP_KERNEL);
63f0bbfc39SXin Zeng 	if (!vfmig)
64f0bbfc39SXin Zeng 		return -ENOMEM;
65f0bbfc39SXin Zeng 
66f0bbfc39SXin Zeng 	vfmig->mstate_mgr = adf_mstate_mgr_new(mdev->state, mdev->state_size);
67f0bbfc39SXin Zeng 	if (!vfmig->mstate_mgr) {
68f0bbfc39SXin Zeng 		kfree(vfmig);
69f0bbfc39SXin Zeng 		return -ENOMEM;
70f0bbfc39SXin Zeng 	}
71f0bbfc39SXin Zeng 	vf_info->mig_priv = vfmig;
72f0bbfc39SXin Zeng 	mdev->setup_size = 0;
73f0bbfc39SXin Zeng 	mdev->remote_setup_size = 0;
74f0bbfc39SXin Zeng 
75f0bbfc39SXin Zeng 	return 0;
76f0bbfc39SXin Zeng }
77f0bbfc39SXin Zeng 
adf_gen4_vfmig_close_device(struct qat_mig_dev * mdev)78f0bbfc39SXin Zeng static void adf_gen4_vfmig_close_device(struct qat_mig_dev *mdev)
79f0bbfc39SXin Zeng {
80f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
81f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
82f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
83f0bbfc39SXin Zeng 
84f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[mdev->vf_id];
85f0bbfc39SXin Zeng 	if (vf_info->mig_priv) {
86f0bbfc39SXin Zeng 		vfmig = vf_info->mig_priv;
87f0bbfc39SXin Zeng 		adf_mstate_mgr_destroy(vfmig->mstate_mgr);
88f0bbfc39SXin Zeng 		kfree(vfmig);
89f0bbfc39SXin Zeng 		vf_info->mig_priv = NULL;
90f0bbfc39SXin Zeng 	}
91f0bbfc39SXin Zeng }
92f0bbfc39SXin Zeng 
adf_gen4_vfmig_suspend_device(struct qat_mig_dev * mdev)93f0bbfc39SXin Zeng static int adf_gen4_vfmig_suspend_device(struct qat_mig_dev *mdev)
94f0bbfc39SXin Zeng {
95f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
96f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
97f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
98f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vf_mig;
99f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
100f0bbfc39SXin Zeng 	int ret, i;
101f0bbfc39SXin Zeng 
102f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
103f0bbfc39SXin Zeng 	vf_mig = vf_info->mig_priv;
104f0bbfc39SXin Zeng 
105f0bbfc39SXin Zeng 	/* Stop all inflight jobs */
106f0bbfc39SXin Zeng 	for (i = 0; i < hw_data->num_banks_per_vf; i++) {
107f0bbfc39SXin Zeng 		u32 pf_bank_nr = i + vf_nr * hw_data->num_banks_per_vf;
108f0bbfc39SXin Zeng 
109f0bbfc39SXin Zeng 		ret = adf_gen4_bank_drain_start(accel_dev, pf_bank_nr,
110f0bbfc39SXin Zeng 						ADF_RPRESET_POLL_TIMEOUT_US);
111f0bbfc39SXin Zeng 		if (ret) {
112f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev),
113f0bbfc39SXin Zeng 				"Failed to drain bank %d for vf_nr %d\n", i,
114f0bbfc39SXin Zeng 				vf_nr);
115f0bbfc39SXin Zeng 			return ret;
116f0bbfc39SXin Zeng 		}
117f0bbfc39SXin Zeng 		vf_mig->bank_stopped[i] = true;
118f0bbfc39SXin Zeng 
119f0bbfc39SXin Zeng 		adf_gen4_bank_quiesce_coal_timer(accel_dev, pf_bank_nr,
120f0bbfc39SXin Zeng 						 ADF_COALESCED_POLL_TIMEOUT_US);
121f0bbfc39SXin Zeng 	}
122f0bbfc39SXin Zeng 
123f0bbfc39SXin Zeng 	return 0;
124f0bbfc39SXin Zeng }
125f0bbfc39SXin Zeng 
adf_gen4_vfmig_resume_device(struct qat_mig_dev * mdev)126f0bbfc39SXin Zeng static int adf_gen4_vfmig_resume_device(struct qat_mig_dev *mdev)
127f0bbfc39SXin Zeng {
128f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
129f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
130f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
131f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vf_mig;
132f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
133f0bbfc39SXin Zeng 	int i;
134f0bbfc39SXin Zeng 
135f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
136f0bbfc39SXin Zeng 	vf_mig = vf_info->mig_priv;
137f0bbfc39SXin Zeng 
138f0bbfc39SXin Zeng 	for (i = 0; i < hw_data->num_banks_per_vf; i++) {
139f0bbfc39SXin Zeng 		u32 pf_bank_nr = i + vf_nr * hw_data->num_banks_per_vf;
140f0bbfc39SXin Zeng 
141f0bbfc39SXin Zeng 		if (vf_mig->bank_stopped[i]) {
142f0bbfc39SXin Zeng 			adf_gen4_bank_drain_finish(accel_dev, pf_bank_nr);
143f0bbfc39SXin Zeng 			vf_mig->bank_stopped[i] = false;
144f0bbfc39SXin Zeng 		}
145f0bbfc39SXin Zeng 	}
146f0bbfc39SXin Zeng 
147f0bbfc39SXin Zeng 	return 0;
148f0bbfc39SXin Zeng }
149f0bbfc39SXin Zeng 
150f0bbfc39SXin Zeng struct adf_vf_bank_info {
151f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev;
152f0bbfc39SXin Zeng 	u32 vf_nr;
153f0bbfc39SXin Zeng 	u32 bank_nr;
154f0bbfc39SXin Zeng };
155f0bbfc39SXin Zeng 
156f0bbfc39SXin Zeng struct mig_user_sla {
157f0bbfc39SXin Zeng 	enum adf_base_services srv;
158f0bbfc39SXin Zeng 	u64 rp_mask;
159f0bbfc39SXin Zeng 	u32 cir;
160f0bbfc39SXin Zeng 	u32 pir;
161f0bbfc39SXin Zeng };
162f0bbfc39SXin Zeng 
adf_mstate_sla_check(struct adf_mstate_mgr * sub_mgr,u8 * src_buf,u32 src_size,void * opaque)163f0bbfc39SXin Zeng static int adf_mstate_sla_check(struct adf_mstate_mgr *sub_mgr, u8 *src_buf,
164f0bbfc39SXin Zeng 				u32 src_size, void *opaque)
165f0bbfc39SXin Zeng {
166f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo _sinfo = { src_buf, src_size };
167f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo *sinfo = &_sinfo, *dinfo = opaque;
168f0bbfc39SXin Zeng 	u32 src_sla_cnt = sinfo->size / sizeof(struct mig_user_sla);
169f0bbfc39SXin Zeng 	u32 dst_sla_cnt = dinfo->size / sizeof(struct mig_user_sla);
170f0bbfc39SXin Zeng 	struct mig_user_sla *src_slas = sinfo->addr;
171f0bbfc39SXin Zeng 	struct mig_user_sla *dst_slas = dinfo->addr;
172f0bbfc39SXin Zeng 	int i, j;
173f0bbfc39SXin Zeng 
174f0bbfc39SXin Zeng 	for (i = 0; i < src_sla_cnt; i++) {
175f0bbfc39SXin Zeng 		for (j = 0; j < dst_sla_cnt; j++) {
176f0bbfc39SXin Zeng 			if (src_slas[i].srv != dst_slas[j].srv ||
177f0bbfc39SXin Zeng 			    src_slas[i].rp_mask != dst_slas[j].rp_mask)
178f0bbfc39SXin Zeng 				continue;
179f0bbfc39SXin Zeng 
180f0bbfc39SXin Zeng 			if (src_slas[i].cir > dst_slas[j].cir ||
181f0bbfc39SXin Zeng 			    src_slas[i].pir > dst_slas[j].pir) {
182f0bbfc39SXin Zeng 				pr_err("QAT: DST VF rate limiting mismatch.\n");
183f0bbfc39SXin Zeng 				return -EINVAL;
184f0bbfc39SXin Zeng 			}
185f0bbfc39SXin Zeng 			break;
186f0bbfc39SXin Zeng 		}
187f0bbfc39SXin Zeng 
188f0bbfc39SXin Zeng 		if (j == dst_sla_cnt) {
189f0bbfc39SXin Zeng 			pr_err("QAT: SRC VF rate limiting mismatch - SRC srv %d and rp_mask 0x%llx.\n",
190f0bbfc39SXin Zeng 			       src_slas[i].srv, src_slas[i].rp_mask);
191f0bbfc39SXin Zeng 			return -EINVAL;
192f0bbfc39SXin Zeng 		}
193f0bbfc39SXin Zeng 	}
194f0bbfc39SXin Zeng 
195f0bbfc39SXin Zeng 	return 0;
196f0bbfc39SXin Zeng }
197f0bbfc39SXin Zeng 
adf_mstate_check_cap_size(u32 src_sz,u32 dst_sz,u32 max_sz)198f0bbfc39SXin Zeng static inline int adf_mstate_check_cap_size(u32 src_sz, u32 dst_sz, u32 max_sz)
199f0bbfc39SXin Zeng {
200f0bbfc39SXin Zeng 	if (src_sz > max_sz || dst_sz > max_sz)
201f0bbfc39SXin Zeng 		return -EINVAL;
202f0bbfc39SXin Zeng 	else
203f0bbfc39SXin Zeng 		return 0;
204f0bbfc39SXin Zeng }
205f0bbfc39SXin Zeng 
adf_mstate_compatver_check(struct adf_mstate_mgr * sub_mgr,u8 * src_buf,u32 src_sz,void * opaque)206f0bbfc39SXin Zeng static int adf_mstate_compatver_check(struct adf_mstate_mgr *sub_mgr,
207f0bbfc39SXin Zeng 				      u8 *src_buf, u32 src_sz, void *opaque)
208f0bbfc39SXin Zeng {
209f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo *info = opaque;
210f0bbfc39SXin Zeng 	u8 compat = 0;
211f0bbfc39SXin Zeng 	u8 *pcompat;
212f0bbfc39SXin Zeng 
213f0bbfc39SXin Zeng 	if (src_sz != info->size) {
214f0bbfc39SXin Zeng 		pr_debug("QAT: State mismatch (compat version size), current %u, expected %u\n",
215f0bbfc39SXin Zeng 			 src_sz, info->size);
216f0bbfc39SXin Zeng 		return -EINVAL;
217f0bbfc39SXin Zeng 	}
218f0bbfc39SXin Zeng 
219f0bbfc39SXin Zeng 	memcpy(info->addr, src_buf, info->size);
220f0bbfc39SXin Zeng 	pcompat = info->addr;
221f0bbfc39SXin Zeng 	if (*pcompat == 0) {
222f0bbfc39SXin Zeng 		pr_warn("QAT: Unable to determine the version of VF\n");
223f0bbfc39SXin Zeng 		return 0;
224f0bbfc39SXin Zeng 	}
225f0bbfc39SXin Zeng 
226f0bbfc39SXin Zeng 	compat = adf_vf_compat_checker(*pcompat);
227f0bbfc39SXin Zeng 	if (compat == ADF_PF2VF_VF_INCOMPATIBLE) {
228f0bbfc39SXin Zeng 		pr_debug("QAT: SRC VF driver (ver=%u) is incompatible with DST PF driver (ver=%u)\n",
229f0bbfc39SXin Zeng 			 *pcompat, ADF_PFVF_COMPAT_THIS_VERSION);
230f0bbfc39SXin Zeng 		return -EINVAL;
231f0bbfc39SXin Zeng 	}
232f0bbfc39SXin Zeng 
233f0bbfc39SXin Zeng 	if (compat == ADF_PF2VF_VF_COMPAT_UNKNOWN)
234f0bbfc39SXin Zeng 		pr_debug("QAT: SRC VF driver (ver=%u) is newer than DST PF driver (ver=%u)\n",
235f0bbfc39SXin Zeng 			 *pcompat, ADF_PFVF_COMPAT_THIS_VERSION);
236f0bbfc39SXin Zeng 
237f0bbfc39SXin Zeng 	return 0;
238f0bbfc39SXin Zeng }
239f0bbfc39SXin Zeng 
240f0bbfc39SXin Zeng /*
241f0bbfc39SXin Zeng  * adf_mstate_capmask_compare() - compare QAT device capability mask
242f0bbfc39SXin Zeng  * @sinfo:	Pointer to source capability info
243f0bbfc39SXin Zeng  * @dinfo:	Pointer to target capability info
244f0bbfc39SXin Zeng  *
245f0bbfc39SXin Zeng  * This function compares the capability mask between source VF and target VF
246f0bbfc39SXin Zeng  *
247f0bbfc39SXin Zeng  * Returns: 0 if target capability mask is identical to source capability mask,
248f0bbfc39SXin Zeng  * 1 if target mask can represent all the capabilities represented by source mask,
249f0bbfc39SXin Zeng  * -1 if target mask can't represent all the capabilities represented by source
250f0bbfc39SXin Zeng  * mask.
251f0bbfc39SXin Zeng  */
adf_mstate_capmask_compare(struct adf_mstate_vreginfo * sinfo,struct adf_mstate_vreginfo * dinfo)252f0bbfc39SXin Zeng static int adf_mstate_capmask_compare(struct adf_mstate_vreginfo *sinfo,
253f0bbfc39SXin Zeng 				      struct adf_mstate_vreginfo *dinfo)
254f0bbfc39SXin Zeng {
255f0bbfc39SXin Zeng 	u64 src = 0, dst = 0;
256f0bbfc39SXin Zeng 
257f0bbfc39SXin Zeng 	if (adf_mstate_check_cap_size(sinfo->size, dinfo->size, sizeof(u64))) {
258f0bbfc39SXin Zeng 		pr_debug("QAT: Unexpected capability size %u %u %zu\n",
259f0bbfc39SXin Zeng 			 sinfo->size, dinfo->size, sizeof(u64));
260f0bbfc39SXin Zeng 		return -1;
261f0bbfc39SXin Zeng 	}
262f0bbfc39SXin Zeng 
263f0bbfc39SXin Zeng 	memcpy(&src, sinfo->addr, sinfo->size);
264f0bbfc39SXin Zeng 	memcpy(&dst, dinfo->addr, dinfo->size);
265f0bbfc39SXin Zeng 
266f0bbfc39SXin Zeng 	pr_debug("QAT: Check cap compatibility of cap %llu %llu\n", src, dst);
267f0bbfc39SXin Zeng 
268f0bbfc39SXin Zeng 	if (src == dst)
269f0bbfc39SXin Zeng 		return 0;
270f0bbfc39SXin Zeng 
271f0bbfc39SXin Zeng 	if ((src | dst) == dst)
272f0bbfc39SXin Zeng 		return 1;
273f0bbfc39SXin Zeng 
274f0bbfc39SXin Zeng 	return -1;
275f0bbfc39SXin Zeng }
276f0bbfc39SXin Zeng 
adf_mstate_capmask_superset(struct adf_mstate_mgr * sub_mgr,u8 * buf,u32 size,void * opa)277f0bbfc39SXin Zeng static int adf_mstate_capmask_superset(struct adf_mstate_mgr *sub_mgr, u8 *buf,
278f0bbfc39SXin Zeng 				       u32 size, void *opa)
279f0bbfc39SXin Zeng {
280f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo sinfo = { buf, size };
281f0bbfc39SXin Zeng 
282f0bbfc39SXin Zeng 	if (adf_mstate_capmask_compare(&sinfo, opa) >= 0)
283f0bbfc39SXin Zeng 		return 0;
284f0bbfc39SXin Zeng 
285f0bbfc39SXin Zeng 	return -EINVAL;
286f0bbfc39SXin Zeng }
287f0bbfc39SXin Zeng 
adf_mstate_capmask_equal(struct adf_mstate_mgr * sub_mgr,u8 * buf,u32 size,void * opa)288f0bbfc39SXin Zeng static int adf_mstate_capmask_equal(struct adf_mstate_mgr *sub_mgr, u8 *buf,
289f0bbfc39SXin Zeng 				    u32 size, void *opa)
290f0bbfc39SXin Zeng {
291f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo sinfo = { buf, size };
292f0bbfc39SXin Zeng 
293f0bbfc39SXin Zeng 	if (adf_mstate_capmask_compare(&sinfo, opa) == 0)
294f0bbfc39SXin Zeng 		return 0;
295f0bbfc39SXin Zeng 
296f0bbfc39SXin Zeng 	return -EINVAL;
297f0bbfc39SXin Zeng }
298f0bbfc39SXin Zeng 
adf_mstate_set_vreg(struct adf_mstate_mgr * sub_mgr,u8 * buf,u32 size,void * opa)299f0bbfc39SXin Zeng static int adf_mstate_set_vreg(struct adf_mstate_mgr *sub_mgr, u8 *buf,
300f0bbfc39SXin Zeng 			       u32 size, void *opa)
301f0bbfc39SXin Zeng {
302f0bbfc39SXin Zeng 	struct adf_mstate_vreginfo *info = opa;
303f0bbfc39SXin Zeng 
304f0bbfc39SXin Zeng 	if (size != info->size) {
305f0bbfc39SXin Zeng 		pr_debug("QAT: Unexpected cap size %u %u\n", size, info->size);
306f0bbfc39SXin Zeng 		return -EINVAL;
307f0bbfc39SXin Zeng 	}
308f0bbfc39SXin Zeng 	memcpy(info->addr, buf, info->size);
309f0bbfc39SXin Zeng 
310f0bbfc39SXin Zeng 	return 0;
311f0bbfc39SXin Zeng }
312f0bbfc39SXin Zeng 
adf_gen4_vfmig_get_slas(struct adf_accel_dev * accel_dev,u32 vf_nr,struct mig_user_sla * pmig_slas)313f0bbfc39SXin Zeng static u32 adf_gen4_vfmig_get_slas(struct adf_accel_dev *accel_dev, u32 vf_nr,
314f0bbfc39SXin Zeng 				   struct mig_user_sla *pmig_slas)
315f0bbfc39SXin Zeng {
316f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
317f0bbfc39SXin Zeng 	struct adf_rl *rl_data = accel_dev->rate_limiting;
318f0bbfc39SXin Zeng 	struct rl_sla **sla_type_arr = NULL;
319f0bbfc39SXin Zeng 	u64 rp_mask, rp_index;
320f0bbfc39SXin Zeng 	u32 max_num_sla;
321f0bbfc39SXin Zeng 	u32 sla_cnt = 0;
322f0bbfc39SXin Zeng 	int i, j;
323f0bbfc39SXin Zeng 
324f0bbfc39SXin Zeng 	if (!accel_dev->rate_limiting)
325f0bbfc39SXin Zeng 		return 0;
326f0bbfc39SXin Zeng 
327f0bbfc39SXin Zeng 	rp_index = vf_nr * hw_data->num_banks_per_vf;
328f0bbfc39SXin Zeng 	max_num_sla = adf_rl_get_sla_arr_of_type(rl_data, RL_LEAF, &sla_type_arr);
329f0bbfc39SXin Zeng 
330f0bbfc39SXin Zeng 	for (i = 0; i < max_num_sla; i++) {
331f0bbfc39SXin Zeng 		if (!sla_type_arr[i])
332f0bbfc39SXin Zeng 			continue;
333f0bbfc39SXin Zeng 
334f0bbfc39SXin Zeng 		rp_mask = 0;
335f0bbfc39SXin Zeng 		for (j = 0; j < sla_type_arr[i]->ring_pairs_cnt; j++)
336f0bbfc39SXin Zeng 			rp_mask |= BIT(sla_type_arr[i]->ring_pairs_ids[j]);
337f0bbfc39SXin Zeng 
338f0bbfc39SXin Zeng 		if (rp_mask & GENMASK_ULL(rp_index + 3, rp_index)) {
339f0bbfc39SXin Zeng 			pmig_slas->rp_mask = rp_mask;
340f0bbfc39SXin Zeng 			pmig_slas->cir = sla_type_arr[i]->cir;
341f0bbfc39SXin Zeng 			pmig_slas->pir = sla_type_arr[i]->pir;
342f0bbfc39SXin Zeng 			pmig_slas->srv = sla_type_arr[i]->srv;
343f0bbfc39SXin Zeng 			pmig_slas++;
344f0bbfc39SXin Zeng 			sla_cnt++;
345f0bbfc39SXin Zeng 		}
346f0bbfc39SXin Zeng 	}
347f0bbfc39SXin Zeng 
348f0bbfc39SXin Zeng 	return sla_cnt;
349f0bbfc39SXin Zeng }
350f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_etr_regs(struct adf_mstate_mgr * sub_mgr,u8 * state,u32 size,void * opa)351f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_etr_regs(struct adf_mstate_mgr *sub_mgr,
352f0bbfc39SXin Zeng 					u8 *state, u32 size, void *opa)
353f0bbfc39SXin Zeng {
354f0bbfc39SXin Zeng 	struct adf_vf_bank_info *vf_bank_info = opa;
355f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = vf_bank_info->accel_dev;
356f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
357f0bbfc39SXin Zeng 	u32 pf_bank_nr;
358f0bbfc39SXin Zeng 	int ret;
359f0bbfc39SXin Zeng 
360f0bbfc39SXin Zeng 	pf_bank_nr = vf_bank_info->bank_nr + vf_bank_info->vf_nr * hw_data->num_banks_per_vf;
361f0bbfc39SXin Zeng 	ret = hw_data->bank_state_restore(accel_dev, pf_bank_nr,
362*a47dc5d1SSuman Kumar Chakraborty 					  (struct adf_bank_state *)state);
363f0bbfc39SXin Zeng 	if (ret) {
364f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
365f0bbfc39SXin Zeng 			"Failed to load regs for vf%d bank%d\n",
366f0bbfc39SXin Zeng 			vf_bank_info->vf_nr, vf_bank_info->bank_nr);
367f0bbfc39SXin Zeng 		return ret;
368f0bbfc39SXin Zeng 	}
369f0bbfc39SXin Zeng 
370f0bbfc39SXin Zeng 	return 0;
371f0bbfc39SXin Zeng }
372f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_etr_bank(struct adf_accel_dev * accel_dev,u32 vf_nr,u32 bank_nr,struct adf_mstate_mgr * mstate_mgr)373f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_etr_bank(struct adf_accel_dev *accel_dev,
374f0bbfc39SXin Zeng 					u32 vf_nr, u32 bank_nr,
375f0bbfc39SXin Zeng 					struct adf_mstate_mgr *mstate_mgr)
376f0bbfc39SXin Zeng {
377f0bbfc39SXin Zeng 	struct adf_vf_bank_info vf_bank_info = {accel_dev, vf_nr, bank_nr};
378f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
379f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
380f0bbfc39SXin Zeng 	char bank_ids[ADF_MSTATE_ID_LEN];
381f0bbfc39SXin Zeng 
382f0bbfc39SXin Zeng 	snprintf(bank_ids, sizeof(bank_ids), ADF_MSTATE_BANK_IDX_IDS "%x", bank_nr);
383f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_lookup(mstate_mgr, bank_ids, NULL, NULL);
384f0bbfc39SXin Zeng 	if (!subsec) {
385f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
386f0bbfc39SXin Zeng 			"Failed to lookup sec %s for vf%d bank%d\n",
387f0bbfc39SXin Zeng 			ADF_MSTATE_BANK_IDX_IDS, vf_nr, bank_nr);
388f0bbfc39SXin Zeng 		return -EINVAL;
389f0bbfc39SXin Zeng 	}
390f0bbfc39SXin Zeng 
391f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_psect(&sub_sects_mgr, subsec);
392f0bbfc39SXin Zeng 	l2_subsec = adf_mstate_sect_lookup(&sub_sects_mgr, ADF_MSTATE_ETR_REGS_IDS,
393f0bbfc39SXin Zeng 					   adf_gen4_vfmig_load_etr_regs,
394f0bbfc39SXin Zeng 					   &vf_bank_info);
395f0bbfc39SXin Zeng 	if (!l2_subsec) {
396f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
397f0bbfc39SXin Zeng 			"Failed to add sec %s for vf%d bank%d\n",
398f0bbfc39SXin Zeng 			ADF_MSTATE_ETR_REGS_IDS, vf_nr, bank_nr);
399f0bbfc39SXin Zeng 		return -EINVAL;
400f0bbfc39SXin Zeng 	}
401f0bbfc39SXin Zeng 
402f0bbfc39SXin Zeng 	return 0;
403f0bbfc39SXin Zeng }
404f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_etr(struct adf_accel_dev * accel_dev,u32 vf_nr)405f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_etr(struct adf_accel_dev *accel_dev, u32 vf_nr)
406f0bbfc39SXin Zeng {
407f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
408f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
409f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
410f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
411f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
412f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec;
413f0bbfc39SXin Zeng 	int ret, i;
414f0bbfc39SXin Zeng 
415f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_lookup(mstate_mgr, ADF_MSTATE_ETRB_IDS, NULL,
416f0bbfc39SXin Zeng 					NULL);
417f0bbfc39SXin Zeng 	if (!subsec) {
418f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
419f0bbfc39SXin Zeng 			ADF_MSTATE_ETRB_IDS);
420f0bbfc39SXin Zeng 		return -EINVAL;
421f0bbfc39SXin Zeng 	}
422f0bbfc39SXin Zeng 
423f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_psect(&sub_sects_mgr, subsec);
424f0bbfc39SXin Zeng 	for (i = 0; i < hw_data->num_banks_per_vf; i++) {
425f0bbfc39SXin Zeng 		ret = adf_gen4_vfmig_load_etr_bank(accel_dev, vf_nr, i,
426f0bbfc39SXin Zeng 						   &sub_sects_mgr);
427f0bbfc39SXin Zeng 		if (ret)
428f0bbfc39SXin Zeng 			return ret;
429f0bbfc39SXin Zeng 	}
430f0bbfc39SXin Zeng 
431f0bbfc39SXin Zeng 	return 0;
432f0bbfc39SXin Zeng }
433f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_misc(struct adf_accel_dev * accel_dev,u32 vf_nr)434f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_misc(struct adf_accel_dev *accel_dev, u32 vf_nr)
435f0bbfc39SXin Zeng {
436f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
437f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
438f0bbfc39SXin Zeng 	void __iomem *csr = adf_get_pmisc_base(accel_dev);
439f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
440f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
441f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
442f0bbfc39SXin Zeng 	struct {
443f0bbfc39SXin Zeng 		char *id;
444f0bbfc39SXin Zeng 		u64 ofs;
445f0bbfc39SXin Zeng 	} misc_states[] = {
446f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTMSK_IDS, ADF_GEN4_VINTMSK_OFFSET(vf_nr)},
447f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTMSK_PF2VM_IDS, ADF_GEN4_VINTMSKPF2VM_OFFSET(vf_nr)},
448f0bbfc39SXin Zeng 		{ADF_MSTATE_PF2VM_IDS, ADF_GEN4_PF2VM_OFFSET(vf_nr)},
449f0bbfc39SXin Zeng 		{ADF_MSTATE_VM2PF_IDS, ADF_GEN4_VM2PF_OFFSET(vf_nr)},
450f0bbfc39SXin Zeng 	};
451f0bbfc39SXin Zeng 	int i;
452f0bbfc39SXin Zeng 
453f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_lookup(mstate_mgr, ADF_MSTATE_MISCB_IDS, NULL,
454f0bbfc39SXin Zeng 					NULL);
455f0bbfc39SXin Zeng 	if (!subsec) {
456f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
457f0bbfc39SXin Zeng 			ADF_MSTATE_MISCB_IDS);
458f0bbfc39SXin Zeng 		return -EINVAL;
459f0bbfc39SXin Zeng 	}
460f0bbfc39SXin Zeng 
461f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_psect(&sub_sects_mgr, subsec);
462f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(misc_states); i++) {
463f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
464f0bbfc39SXin Zeng 		u32 regv;
465f0bbfc39SXin Zeng 
466f0bbfc39SXin Zeng 		info.addr = &regv;
467f0bbfc39SXin Zeng 		info.size = sizeof(regv);
468f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_lookup(&sub_sects_mgr,
469f0bbfc39SXin Zeng 						   misc_states[i].id,
470f0bbfc39SXin Zeng 						   adf_mstate_set_vreg,
471f0bbfc39SXin Zeng 						   &info);
472f0bbfc39SXin Zeng 		if (!l2_subsec) {
473f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev),
474f0bbfc39SXin Zeng 				"Failed to load sec %s\n", misc_states[i].id);
475f0bbfc39SXin Zeng 			return -EINVAL;
476f0bbfc39SXin Zeng 		}
477f0bbfc39SXin Zeng 		ADF_CSR_WR(csr, misc_states[i].ofs, regv);
478f0bbfc39SXin Zeng 	}
479f0bbfc39SXin Zeng 
480f0bbfc39SXin Zeng 	return 0;
481f0bbfc39SXin Zeng }
482f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_generic(struct adf_accel_dev * accel_dev,u32 vf_nr)483f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_generic(struct adf_accel_dev *accel_dev, u32 vf_nr)
484f0bbfc39SXin Zeng {
485f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
486f0bbfc39SXin Zeng 	struct mig_user_sla dst_slas[RL_RP_CNT_PER_LEAF_MAX] = { };
487f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
488f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
489f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
490f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
491f0bbfc39SXin Zeng 	u32 dst_sla_cnt;
492f0bbfc39SXin Zeng 	struct {
493f0bbfc39SXin Zeng 		char *id;
494f0bbfc39SXin Zeng 		int (*action)(struct adf_mstate_mgr *sub_mgr, u8 *buf, u32 size, void *opa);
495f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
496f0bbfc39SXin Zeng 	} gen_states[] = {
497f0bbfc39SXin Zeng 		{ADF_MSTATE_IOV_INIT_IDS, adf_mstate_set_vreg,
498f0bbfc39SXin Zeng 		{&vf_info->init, sizeof(vf_info->init)}},
499f0bbfc39SXin Zeng 		{ADF_MSTATE_COMPAT_VER_IDS, adf_mstate_compatver_check,
500f0bbfc39SXin Zeng 		{&vf_info->vf_compat_ver, sizeof(vf_info->vf_compat_ver)}},
501f0bbfc39SXin Zeng 		{ADF_MSTATE_SLA_IDS, adf_mstate_sla_check, {dst_slas, 0}},
502f0bbfc39SXin Zeng 	};
503f0bbfc39SXin Zeng 	int i;
504f0bbfc39SXin Zeng 
505f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_lookup(mstate_mgr, ADF_MSTATE_GEN_IDS, NULL, NULL);
506f0bbfc39SXin Zeng 	if (!subsec) {
507f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
508f0bbfc39SXin Zeng 			ADF_MSTATE_GEN_IDS);
509f0bbfc39SXin Zeng 		return -EINVAL;
510f0bbfc39SXin Zeng 	}
511f0bbfc39SXin Zeng 
512f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_psect(&sub_sects_mgr, subsec);
513f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(gen_states); i++) {
514f0bbfc39SXin Zeng 		if (gen_states[i].info.addr == dst_slas) {
515f0bbfc39SXin Zeng 			dst_sla_cnt = adf_gen4_vfmig_get_slas(accel_dev, vf_nr, dst_slas);
516f0bbfc39SXin Zeng 			gen_states[i].info.size = dst_sla_cnt * sizeof(struct mig_user_sla);
517f0bbfc39SXin Zeng 		}
518f0bbfc39SXin Zeng 
519f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_lookup(&sub_sects_mgr,
520f0bbfc39SXin Zeng 						   gen_states[i].id,
521f0bbfc39SXin Zeng 						   gen_states[i].action,
522f0bbfc39SXin Zeng 						   &gen_states[i].info);
523f0bbfc39SXin Zeng 		if (!l2_subsec) {
524f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
525f0bbfc39SXin Zeng 				gen_states[i].id);
526f0bbfc39SXin Zeng 			return -EINVAL;
527f0bbfc39SXin Zeng 		}
528f0bbfc39SXin Zeng 	}
529f0bbfc39SXin Zeng 
530f0bbfc39SXin Zeng 	return 0;
531f0bbfc39SXin Zeng }
532f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_config(struct adf_accel_dev * accel_dev,u32 vf_nr)533f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_config(struct adf_accel_dev *accel_dev, u32 vf_nr)
534f0bbfc39SXin Zeng {
535f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
536f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
537f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
538f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
539f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
540f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
541f0bbfc39SXin Zeng 	struct {
542f0bbfc39SXin Zeng 		char *id;
543f0bbfc39SXin Zeng 		int (*action)(struct adf_mstate_mgr *sub_mgr, u8 *buf, u32 size, void *opa);
544f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
545f0bbfc39SXin Zeng 	} setups[] = {
546f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_CAP_IDS, adf_mstate_capmask_superset,
547f0bbfc39SXin Zeng 		{&hw_data->accel_capabilities_mask, sizeof(hw_data->accel_capabilities_mask)}},
548f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_SVCMAP_IDS, adf_mstate_capmask_equal,
549f0bbfc39SXin Zeng 		{&hw_data->ring_to_svc_map, sizeof(hw_data->ring_to_svc_map)}},
550f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_EXTDC_IDS, adf_mstate_capmask_superset,
551f0bbfc39SXin Zeng 		{&hw_data->extended_dc_capabilities, sizeof(hw_data->extended_dc_capabilities)}},
552f0bbfc39SXin Zeng 	};
553f0bbfc39SXin Zeng 	int i;
554f0bbfc39SXin Zeng 
555f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_lookup(mstate_mgr, ADF_MSTATE_CONFIG_IDS, NULL, NULL);
556f0bbfc39SXin Zeng 	if (!subsec) {
557f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
558f0bbfc39SXin Zeng 			ADF_MSTATE_CONFIG_IDS);
559f0bbfc39SXin Zeng 		return -EINVAL;
560f0bbfc39SXin Zeng 	}
561f0bbfc39SXin Zeng 
562f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_psect(&sub_sects_mgr, subsec);
563f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(setups); i++) {
564f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_lookup(&sub_sects_mgr, setups[i].id,
565f0bbfc39SXin Zeng 						   setups[i].action, &setups[i].info);
566f0bbfc39SXin Zeng 		if (!l2_subsec) {
567f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to load sec %s\n",
568f0bbfc39SXin Zeng 				setups[i].id);
569f0bbfc39SXin Zeng 			return -EINVAL;
570f0bbfc39SXin Zeng 		}
571f0bbfc39SXin Zeng 	}
572f0bbfc39SXin Zeng 
573f0bbfc39SXin Zeng 	return 0;
574f0bbfc39SXin Zeng }
575f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_etr_regs(struct adf_mstate_mgr * subs,u8 * state,u32 size,void * opa)576f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_etr_regs(struct adf_mstate_mgr *subs, u8 *state,
577f0bbfc39SXin Zeng 					u32 size, void *opa)
578f0bbfc39SXin Zeng {
579f0bbfc39SXin Zeng 	struct adf_vf_bank_info *vf_bank_info = opa;
580f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = vf_bank_info->accel_dev;
581f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
582f0bbfc39SXin Zeng 	u32 pf_bank_nr;
583f0bbfc39SXin Zeng 	int ret;
584f0bbfc39SXin Zeng 
585f0bbfc39SXin Zeng 	pf_bank_nr = vf_bank_info->bank_nr;
586f0bbfc39SXin Zeng 	pf_bank_nr += vf_bank_info->vf_nr * hw_data->num_banks_per_vf;
587f0bbfc39SXin Zeng 
588f0bbfc39SXin Zeng 	ret = hw_data->bank_state_save(accel_dev, pf_bank_nr,
589*a47dc5d1SSuman Kumar Chakraborty 				       (struct adf_bank_state *)state);
590f0bbfc39SXin Zeng 	if (ret) {
591f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
592f0bbfc39SXin Zeng 			"Failed to save regs for vf%d bank%d\n",
593f0bbfc39SXin Zeng 			vf_bank_info->vf_nr, vf_bank_info->bank_nr);
594f0bbfc39SXin Zeng 		return ret;
595f0bbfc39SXin Zeng 	}
596f0bbfc39SXin Zeng 
597*a47dc5d1SSuman Kumar Chakraborty 	return sizeof(struct adf_bank_state);
598f0bbfc39SXin Zeng }
599f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_etr_bank(struct adf_accel_dev * accel_dev,u32 vf_nr,u32 bank_nr,struct adf_mstate_mgr * mstate_mgr)600f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_etr_bank(struct adf_accel_dev *accel_dev,
601f0bbfc39SXin Zeng 					u32 vf_nr, u32 bank_nr,
602f0bbfc39SXin Zeng 					struct adf_mstate_mgr *mstate_mgr)
603f0bbfc39SXin Zeng {
604f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
605f0bbfc39SXin Zeng 	struct adf_vf_bank_info vf_bank_info;
606f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
607f0bbfc39SXin Zeng 	char bank_ids[ADF_MSTATE_ID_LEN];
608f0bbfc39SXin Zeng 
609f0bbfc39SXin Zeng 	snprintf(bank_ids, sizeof(bank_ids), ADF_MSTATE_BANK_IDX_IDS "%x", bank_nr);
610f0bbfc39SXin Zeng 
611f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_add(mstate_mgr, bank_ids, NULL, NULL);
612f0bbfc39SXin Zeng 	if (!subsec) {
613f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
614f0bbfc39SXin Zeng 			"Failed to add sec %s for vf%d bank%d\n",
615f0bbfc39SXin Zeng 			ADF_MSTATE_BANK_IDX_IDS, vf_nr, bank_nr);
616f0bbfc39SXin Zeng 		return -EINVAL;
617f0bbfc39SXin Zeng 	}
618f0bbfc39SXin Zeng 
619f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mstate_mgr);
620f0bbfc39SXin Zeng 	vf_bank_info.accel_dev = accel_dev;
621f0bbfc39SXin Zeng 	vf_bank_info.vf_nr = vf_nr;
622f0bbfc39SXin Zeng 	vf_bank_info.bank_nr = bank_nr;
623f0bbfc39SXin Zeng 	l2_subsec = adf_mstate_sect_add(&sub_sects_mgr, ADF_MSTATE_ETR_REGS_IDS,
624f0bbfc39SXin Zeng 					adf_gen4_vfmig_save_etr_regs,
625f0bbfc39SXin Zeng 					&vf_bank_info);
626f0bbfc39SXin Zeng 	if (!l2_subsec) {
627f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
628f0bbfc39SXin Zeng 			"Failed to add sec %s for vf%d bank%d\n",
629f0bbfc39SXin Zeng 			ADF_MSTATE_ETR_REGS_IDS, vf_nr, bank_nr);
630f0bbfc39SXin Zeng 		return -EINVAL;
631f0bbfc39SXin Zeng 	}
632f0bbfc39SXin Zeng 	adf_mstate_sect_update(mstate_mgr, &sub_sects_mgr, subsec);
633f0bbfc39SXin Zeng 
634f0bbfc39SXin Zeng 	return 0;
635f0bbfc39SXin Zeng }
636f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_etr(struct adf_accel_dev * accel_dev,u32 vf_nr)637f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_etr(struct adf_accel_dev *accel_dev, u32 vf_nr)
638f0bbfc39SXin Zeng {
639f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
640f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
641f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
642f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
643f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
644f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec;
645f0bbfc39SXin Zeng 	int ret, i;
646f0bbfc39SXin Zeng 
647f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_add(mstate_mgr, ADF_MSTATE_ETRB_IDS, NULL, NULL);
648f0bbfc39SXin Zeng 	if (!subsec) {
649f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
650f0bbfc39SXin Zeng 			ADF_MSTATE_ETRB_IDS);
651f0bbfc39SXin Zeng 		return -EINVAL;
652f0bbfc39SXin Zeng 	}
653f0bbfc39SXin Zeng 
654f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mstate_mgr);
655f0bbfc39SXin Zeng 	for (i = 0; i < hw_data->num_banks_per_vf; i++) {
656f0bbfc39SXin Zeng 		ret = adf_gen4_vfmig_save_etr_bank(accel_dev, vf_nr, i,
657f0bbfc39SXin Zeng 						   &sub_sects_mgr);
658f0bbfc39SXin Zeng 		if (ret)
659f0bbfc39SXin Zeng 			return ret;
660f0bbfc39SXin Zeng 	}
661f0bbfc39SXin Zeng 	adf_mstate_sect_update(mstate_mgr, &sub_sects_mgr, subsec);
662f0bbfc39SXin Zeng 
663f0bbfc39SXin Zeng 	return 0;
664f0bbfc39SXin Zeng }
665f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_misc(struct adf_accel_dev * accel_dev,u32 vf_nr)666f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_misc(struct adf_accel_dev *accel_dev, u32 vf_nr)
667f0bbfc39SXin Zeng {
668f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
669f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
670f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
671f0bbfc39SXin Zeng 	void __iomem *csr = adf_get_pmisc_base(accel_dev);
672f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
673f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
674f0bbfc39SXin Zeng 	struct {
675f0bbfc39SXin Zeng 		char *id;
676f0bbfc39SXin Zeng 		u64 offset;
677f0bbfc39SXin Zeng 	} misc_states[] = {
678f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTSRC_IDS, ADF_GEN4_VINTSOU_OFFSET(vf_nr)},
679f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTMSK_IDS, ADF_GEN4_VINTMSK_OFFSET(vf_nr)},
680f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTSRC_PF2VM_IDS, ADF_GEN4_VINTSOUPF2VM_OFFSET(vf_nr)},
681f0bbfc39SXin Zeng 		{ADF_MSTATE_VINTMSK_PF2VM_IDS, ADF_GEN4_VINTMSKPF2VM_OFFSET(vf_nr)},
682f0bbfc39SXin Zeng 		{ADF_MSTATE_PF2VM_IDS, ADF_GEN4_PF2VM_OFFSET(vf_nr)},
683f0bbfc39SXin Zeng 		{ADF_MSTATE_VM2PF_IDS, ADF_GEN4_VM2PF_OFFSET(vf_nr)},
684f0bbfc39SXin Zeng 	};
685f0bbfc39SXin Zeng 	ktime_t time_exp;
686f0bbfc39SXin Zeng 	int i;
687f0bbfc39SXin Zeng 
688f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_add(mstate_mgr, ADF_MSTATE_MISCB_IDS, NULL, NULL);
689f0bbfc39SXin Zeng 	if (!subsec) {
690f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
691f0bbfc39SXin Zeng 			ADF_MSTATE_MISCB_IDS);
692f0bbfc39SXin Zeng 		return -EINVAL;
693f0bbfc39SXin Zeng 	}
694f0bbfc39SXin Zeng 
695f0bbfc39SXin Zeng 	time_exp = ktime_add_us(ktime_get(), ADF_GEN4_PFVF_RSP_TIMEOUT_US);
696f0bbfc39SXin Zeng 	while (!mutex_trylock(&vf_info->pfvf_mig_lock)) {
697f0bbfc39SXin Zeng 		if (ktime_after(ktime_get(), time_exp)) {
698f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to get pfvf mig lock\n");
699f0bbfc39SXin Zeng 			return -ETIMEDOUT;
700f0bbfc39SXin Zeng 		}
701f0bbfc39SXin Zeng 		usleep_range(500, 1000);
702f0bbfc39SXin Zeng 	}
703f0bbfc39SXin Zeng 
704f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mstate_mgr);
705f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(misc_states); i++) {
706f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
707f0bbfc39SXin Zeng 		u32 regv;
708f0bbfc39SXin Zeng 
709f0bbfc39SXin Zeng 		info.addr = &regv;
710f0bbfc39SXin Zeng 		info.size = sizeof(regv);
711f0bbfc39SXin Zeng 		regv = ADF_CSR_RD(csr, misc_states[i].offset);
712f0bbfc39SXin Zeng 
713f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_add_vreg(&sub_sects_mgr,
714f0bbfc39SXin Zeng 						     misc_states[i].id,
715f0bbfc39SXin Zeng 						     &info);
716f0bbfc39SXin Zeng 		if (!l2_subsec) {
717f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
718f0bbfc39SXin Zeng 				misc_states[i].id);
719f0bbfc39SXin Zeng 			mutex_unlock(&vf_info->pfvf_mig_lock);
720f0bbfc39SXin Zeng 			return -EINVAL;
721f0bbfc39SXin Zeng 		}
722f0bbfc39SXin Zeng 	}
723f0bbfc39SXin Zeng 
724f0bbfc39SXin Zeng 	mutex_unlock(&vf_info->pfvf_mig_lock);
725f0bbfc39SXin Zeng 	adf_mstate_sect_update(mstate_mgr, &sub_sects_mgr, subsec);
726f0bbfc39SXin Zeng 
727f0bbfc39SXin Zeng 	return 0;
728f0bbfc39SXin Zeng }
729f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_generic(struct adf_accel_dev * accel_dev,u32 vf_nr)730f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_generic(struct adf_accel_dev *accel_dev, u32 vf_nr)
731f0bbfc39SXin Zeng {
732f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
733f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
734f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
735f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
736f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
737f0bbfc39SXin Zeng 	struct mig_user_sla src_slas[RL_RP_CNT_PER_LEAF_MAX] = { };
738f0bbfc39SXin Zeng 	u32 src_sla_cnt;
739f0bbfc39SXin Zeng 	struct {
740f0bbfc39SXin Zeng 		char *id;
741f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
742f0bbfc39SXin Zeng 	} gen_states[] = {
743f0bbfc39SXin Zeng 		{ADF_MSTATE_IOV_INIT_IDS,
744f0bbfc39SXin Zeng 		{&vf_info->init, sizeof(vf_info->init)}},
745f0bbfc39SXin Zeng 		{ADF_MSTATE_COMPAT_VER_IDS,
746f0bbfc39SXin Zeng 		{&vf_info->vf_compat_ver, sizeof(vf_info->vf_compat_ver)}},
747f0bbfc39SXin Zeng 		{ADF_MSTATE_SLA_IDS, {src_slas, 0}},
748f0bbfc39SXin Zeng 	};
749f0bbfc39SXin Zeng 	int i;
750f0bbfc39SXin Zeng 
751f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_add(mstate_mgr, ADF_MSTATE_GEN_IDS, NULL, NULL);
752f0bbfc39SXin Zeng 	if (!subsec) {
753f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
754f0bbfc39SXin Zeng 			ADF_MSTATE_GEN_IDS);
755f0bbfc39SXin Zeng 		return -EINVAL;
756f0bbfc39SXin Zeng 	}
757f0bbfc39SXin Zeng 
758f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mstate_mgr);
759f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(gen_states); i++) {
760f0bbfc39SXin Zeng 		if (gen_states[i].info.addr == src_slas) {
761f0bbfc39SXin Zeng 			src_sla_cnt = adf_gen4_vfmig_get_slas(accel_dev, vf_nr, src_slas);
762f0bbfc39SXin Zeng 			gen_states[i].info.size = src_sla_cnt * sizeof(struct mig_user_sla);
763f0bbfc39SXin Zeng 		}
764f0bbfc39SXin Zeng 
765f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_add_vreg(&sub_sects_mgr,
766f0bbfc39SXin Zeng 						     gen_states[i].id,
767f0bbfc39SXin Zeng 						     &gen_states[i].info);
768f0bbfc39SXin Zeng 		if (!l2_subsec) {
769f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
770f0bbfc39SXin Zeng 				gen_states[i].id);
771f0bbfc39SXin Zeng 			return -EINVAL;
772f0bbfc39SXin Zeng 		}
773f0bbfc39SXin Zeng 	}
774f0bbfc39SXin Zeng 	adf_mstate_sect_update(mstate_mgr, &sub_sects_mgr, subsec);
775f0bbfc39SXin Zeng 
776f0bbfc39SXin Zeng 	return 0;
777f0bbfc39SXin Zeng }
778f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_config(struct adf_accel_dev * accel_dev,u32 vf_nr)779f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_config(struct adf_accel_dev *accel_dev, u32 vf_nr)
780f0bbfc39SXin Zeng {
781f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
782f0bbfc39SXin Zeng 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
783f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig = vf_info->mig_priv;
784f0bbfc39SXin Zeng 	struct adf_mstate_mgr *mstate_mgr = vfmig->mstate_mgr;
785f0bbfc39SXin Zeng 	struct adf_mstate_mgr sub_sects_mgr;
786f0bbfc39SXin Zeng 	struct adf_mstate_sect_h *subsec, *l2_subsec;
787f0bbfc39SXin Zeng 	struct {
788f0bbfc39SXin Zeng 		char *id;
789f0bbfc39SXin Zeng 		struct adf_mstate_vreginfo info;
790f0bbfc39SXin Zeng 	} setups[] = {
791f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_CAP_IDS,
792f0bbfc39SXin Zeng 		{&hw_data->accel_capabilities_mask, sizeof(hw_data->accel_capabilities_mask)}},
793f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_SVCMAP_IDS,
794f0bbfc39SXin Zeng 		{&hw_data->ring_to_svc_map, sizeof(hw_data->ring_to_svc_map)}},
795f0bbfc39SXin Zeng 		{ADF_MSTATE_GEN_EXTDC_IDS,
796f0bbfc39SXin Zeng 		{&hw_data->extended_dc_capabilities, sizeof(hw_data->extended_dc_capabilities)}},
797f0bbfc39SXin Zeng 	};
798f0bbfc39SXin Zeng 	int i;
799f0bbfc39SXin Zeng 
800f0bbfc39SXin Zeng 	subsec = adf_mstate_sect_add(mstate_mgr, ADF_MSTATE_CONFIG_IDS, NULL, NULL);
801f0bbfc39SXin Zeng 	if (!subsec) {
802f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
803f0bbfc39SXin Zeng 			ADF_MSTATE_CONFIG_IDS);
804f0bbfc39SXin Zeng 		return -EINVAL;
805f0bbfc39SXin Zeng 	}
806f0bbfc39SXin Zeng 
807f0bbfc39SXin Zeng 	adf_mstate_mgr_init_from_parent(&sub_sects_mgr, mstate_mgr);
808f0bbfc39SXin Zeng 	for (i = 0; i < ARRAY_SIZE(setups); i++) {
809f0bbfc39SXin Zeng 		l2_subsec = adf_mstate_sect_add_vreg(&sub_sects_mgr, setups[i].id,
810f0bbfc39SXin Zeng 						     &setups[i].info);
811f0bbfc39SXin Zeng 		if (!l2_subsec) {
812f0bbfc39SXin Zeng 			dev_err(&GET_DEV(accel_dev), "Failed to add sec %s\n",
813f0bbfc39SXin Zeng 				setups[i].id);
814f0bbfc39SXin Zeng 			return -EINVAL;
815f0bbfc39SXin Zeng 		}
816f0bbfc39SXin Zeng 	}
817f0bbfc39SXin Zeng 	adf_mstate_sect_update(mstate_mgr, &sub_sects_mgr, subsec);
818f0bbfc39SXin Zeng 
819f0bbfc39SXin Zeng 	return 0;
820f0bbfc39SXin Zeng }
821f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_state(struct qat_mig_dev * mdev)822f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_state(struct qat_mig_dev *mdev)
823f0bbfc39SXin Zeng {
824f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
825f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
826f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
827f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
828f0bbfc39SXin Zeng 	int ret;
829f0bbfc39SXin Zeng 
830f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
831f0bbfc39SXin Zeng 	vfmig = vf_info->mig_priv;
832f0bbfc39SXin Zeng 
833f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_save_setup(mdev);
834f0bbfc39SXin Zeng 	if (ret) {
835f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
836f0bbfc39SXin Zeng 			"Failed to save setup for vf_nr %d\n", vf_nr);
837f0bbfc39SXin Zeng 		return ret;
838f0bbfc39SXin Zeng 	}
839f0bbfc39SXin Zeng 
840f0bbfc39SXin Zeng 	adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state + mdev->setup_size,
841f0bbfc39SXin Zeng 			    mdev->state_size - mdev->setup_size);
842f0bbfc39SXin Zeng 	if (!adf_mstate_preamble_add(vfmig->mstate_mgr))
843f0bbfc39SXin Zeng 		return -EINVAL;
844f0bbfc39SXin Zeng 
845f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_save_generic(accel_dev, vf_nr);
846f0bbfc39SXin Zeng 	if (ret) {
847f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
848f0bbfc39SXin Zeng 			"Failed to save generic state for vf_nr %d\n", vf_nr);
849f0bbfc39SXin Zeng 		return ret;
850f0bbfc39SXin Zeng 	}
851f0bbfc39SXin Zeng 
852f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_save_misc(accel_dev, vf_nr);
853f0bbfc39SXin Zeng 	if (ret) {
854f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
855f0bbfc39SXin Zeng 			"Failed to save misc bar state for vf_nr %d\n", vf_nr);
856f0bbfc39SXin Zeng 		return ret;
857f0bbfc39SXin Zeng 	}
858f0bbfc39SXin Zeng 
859f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_save_etr(accel_dev, vf_nr);
860f0bbfc39SXin Zeng 	if (ret) {
861f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
862f0bbfc39SXin Zeng 			"Failed to save etr bar state for vf_nr %d\n", vf_nr);
863f0bbfc39SXin Zeng 		return ret;
864f0bbfc39SXin Zeng 	}
865f0bbfc39SXin Zeng 
866f0bbfc39SXin Zeng 	adf_mstate_preamble_update(vfmig->mstate_mgr);
867f0bbfc39SXin Zeng 
868f0bbfc39SXin Zeng 	return 0;
869f0bbfc39SXin Zeng }
870f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_state(struct qat_mig_dev * mdev)871f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_state(struct qat_mig_dev *mdev)
872f0bbfc39SXin Zeng {
873f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
874f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
875f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
876f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
877f0bbfc39SXin Zeng 	int ret;
878f0bbfc39SXin Zeng 
879f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
880f0bbfc39SXin Zeng 	vfmig = vf_info->mig_priv;
881f0bbfc39SXin Zeng 
882f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_load_setup(mdev, mdev->state_size);
883f0bbfc39SXin Zeng 	if (ret) {
884f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Failed to load setup for vf_nr %d\n",
885f0bbfc39SXin Zeng 			vf_nr);
886f0bbfc39SXin Zeng 		return ret;
887f0bbfc39SXin Zeng 	}
888f0bbfc39SXin Zeng 
889f0bbfc39SXin Zeng 	ret = adf_mstate_mgr_init_from_remote(vfmig->mstate_mgr,
890f0bbfc39SXin Zeng 					      mdev->state + mdev->remote_setup_size,
891f0bbfc39SXin Zeng 					      mdev->state_size - mdev->remote_setup_size,
892f0bbfc39SXin Zeng 					      NULL, NULL);
893f0bbfc39SXin Zeng 	if (ret) {
894f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev), "Invalid state for vf_nr %d\n",
895f0bbfc39SXin Zeng 			vf_nr);
896f0bbfc39SXin Zeng 		return ret;
897f0bbfc39SXin Zeng 	}
898f0bbfc39SXin Zeng 
899f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_load_generic(accel_dev, vf_nr);
900f0bbfc39SXin Zeng 	if (ret) {
901f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
902f0bbfc39SXin Zeng 			"Failed to load general state for vf_nr %d\n", vf_nr);
903f0bbfc39SXin Zeng 		return ret;
904f0bbfc39SXin Zeng 	}
905f0bbfc39SXin Zeng 
906f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_load_misc(accel_dev, vf_nr);
907f0bbfc39SXin Zeng 	if (ret) {
908f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
909f0bbfc39SXin Zeng 			"Failed to load misc bar state for vf_nr %d\n", vf_nr);
910f0bbfc39SXin Zeng 		return ret;
911f0bbfc39SXin Zeng 	}
912f0bbfc39SXin Zeng 
913f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_load_etr(accel_dev, vf_nr);
914f0bbfc39SXin Zeng 	if (ret) {
915f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
916f0bbfc39SXin Zeng 			"Failed to load etr bar state for vf_nr %d\n", vf_nr);
917f0bbfc39SXin Zeng 		return ret;
918f0bbfc39SXin Zeng 	}
919f0bbfc39SXin Zeng 
920f0bbfc39SXin Zeng 	return 0;
921f0bbfc39SXin Zeng }
922f0bbfc39SXin Zeng 
adf_gen4_vfmig_save_setup(struct qat_mig_dev * mdev)923f0bbfc39SXin Zeng static int adf_gen4_vfmig_save_setup(struct qat_mig_dev *mdev)
924f0bbfc39SXin Zeng {
925f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
926f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
927f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
928f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
929f0bbfc39SXin Zeng 	int ret;
930f0bbfc39SXin Zeng 
931f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
932f0bbfc39SXin Zeng 	vfmig = vf_info->mig_priv;
933f0bbfc39SXin Zeng 
934f0bbfc39SXin Zeng 	if (mdev->setup_size)
935f0bbfc39SXin Zeng 		return 0;
936f0bbfc39SXin Zeng 
937f0bbfc39SXin Zeng 	adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state, mdev->state_size);
938f0bbfc39SXin Zeng 	if (!adf_mstate_preamble_add(vfmig->mstate_mgr))
939f0bbfc39SXin Zeng 		return -EINVAL;
940f0bbfc39SXin Zeng 
941f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_save_config(accel_dev, mdev->vf_id);
942f0bbfc39SXin Zeng 	if (ret)
943f0bbfc39SXin Zeng 		return ret;
944f0bbfc39SXin Zeng 
945f0bbfc39SXin Zeng 	adf_mstate_preamble_update(vfmig->mstate_mgr);
946f0bbfc39SXin Zeng 	mdev->setup_size = adf_mstate_state_size(vfmig->mstate_mgr);
947f0bbfc39SXin Zeng 
948f0bbfc39SXin Zeng 	return 0;
949f0bbfc39SXin Zeng }
950f0bbfc39SXin Zeng 
adf_gen4_vfmig_load_setup(struct qat_mig_dev * mdev,int len)951f0bbfc39SXin Zeng static int adf_gen4_vfmig_load_setup(struct qat_mig_dev *mdev, int len)
952f0bbfc39SXin Zeng {
953f0bbfc39SXin Zeng 	struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
954f0bbfc39SXin Zeng 	struct adf_accel_vf_info *vf_info;
955f0bbfc39SXin Zeng 	struct adf_gen4_vfmig *vfmig;
956f0bbfc39SXin Zeng 	u32 vf_nr = mdev->vf_id;
957f0bbfc39SXin Zeng 	u32 setup_size;
958f0bbfc39SXin Zeng 	int ret;
959f0bbfc39SXin Zeng 
960f0bbfc39SXin Zeng 	vf_info = &accel_dev->pf.vf_info[vf_nr];
961f0bbfc39SXin Zeng 	vfmig = vf_info->mig_priv;
962f0bbfc39SXin Zeng 
963f0bbfc39SXin Zeng 	if (mdev->remote_setup_size)
964f0bbfc39SXin Zeng 		return 0;
965f0bbfc39SXin Zeng 
966f0bbfc39SXin Zeng 	if (len < sizeof(struct adf_mstate_preh))
967f0bbfc39SXin Zeng 		return -EAGAIN;
968f0bbfc39SXin Zeng 
969f0bbfc39SXin Zeng 	adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state, mdev->state_size);
970f0bbfc39SXin Zeng 	setup_size = adf_mstate_state_size_from_remote(vfmig->mstate_mgr);
971f0bbfc39SXin Zeng 	if (setup_size > mdev->state_size)
972f0bbfc39SXin Zeng 		return -EINVAL;
973f0bbfc39SXin Zeng 
974f0bbfc39SXin Zeng 	if (len < setup_size)
975f0bbfc39SXin Zeng 		return -EAGAIN;
976f0bbfc39SXin Zeng 
977f0bbfc39SXin Zeng 	ret = adf_mstate_mgr_init_from_remote(vfmig->mstate_mgr, mdev->state,
978f0bbfc39SXin Zeng 					      setup_size, NULL, NULL);
979f0bbfc39SXin Zeng 	if (ret) {
980f5c2cf9dSColin Ian King 		dev_err(&GET_DEV(accel_dev), "Invalid setup for vf_nr %d\n",
981f0bbfc39SXin Zeng 			vf_nr);
982f0bbfc39SXin Zeng 		return ret;
983f0bbfc39SXin Zeng 	}
984f0bbfc39SXin Zeng 
985f0bbfc39SXin Zeng 	mdev->remote_setup_size = setup_size;
986f0bbfc39SXin Zeng 
987f0bbfc39SXin Zeng 	ret = adf_gen4_vfmig_load_config(accel_dev, vf_nr);
988f0bbfc39SXin Zeng 	if (ret) {
989f0bbfc39SXin Zeng 		dev_err(&GET_DEV(accel_dev),
990f0bbfc39SXin Zeng 			"Failed to load config for vf_nr %d\n", vf_nr);
991f0bbfc39SXin Zeng 		return ret;
992f0bbfc39SXin Zeng 	}
993f0bbfc39SXin Zeng 
994f0bbfc39SXin Zeng 	return 0;
995f0bbfc39SXin Zeng }
996f0bbfc39SXin Zeng 
adf_gen4_init_vf_mig_ops(struct qat_migdev_ops * vfmig_ops)997f0bbfc39SXin Zeng void adf_gen4_init_vf_mig_ops(struct qat_migdev_ops *vfmig_ops)
998f0bbfc39SXin Zeng {
999f0bbfc39SXin Zeng 	vfmig_ops->init = adf_gen4_vfmig_init_device;
1000f0bbfc39SXin Zeng 	vfmig_ops->cleanup = adf_gen4_vfmig_cleanup_device;
1001f0bbfc39SXin Zeng 	vfmig_ops->reset = adf_gen4_vfmig_reset_device;
1002f0bbfc39SXin Zeng 	vfmig_ops->open = adf_gen4_vfmig_open_device;
1003f0bbfc39SXin Zeng 	vfmig_ops->close = adf_gen4_vfmig_close_device;
1004f0bbfc39SXin Zeng 	vfmig_ops->suspend = adf_gen4_vfmig_suspend_device;
1005f0bbfc39SXin Zeng 	vfmig_ops->resume = adf_gen4_vfmig_resume_device;
1006f0bbfc39SXin Zeng 	vfmig_ops->save_state = adf_gen4_vfmig_save_state;
1007f0bbfc39SXin Zeng 	vfmig_ops->load_state = adf_gen4_vfmig_load_state;
1008f0bbfc39SXin Zeng 	vfmig_ops->load_setup = adf_gen4_vfmig_load_setup;
1009f0bbfc39SXin Zeng 	vfmig_ops->save_setup = adf_gen4_vfmig_save_setup;
1010f0bbfc39SXin Zeng }
1011f0bbfc39SXin Zeng EXPORT_SYMBOL_GPL(adf_gen4_init_vf_mig_ops);
1012