1b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk/*
2b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  This file is provided under a dual BSD/GPLv2 license.  When using or
3b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  redistributing this file, you may do so under either license.
4b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
5b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  GPL LICENSE SUMMARY
6b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  Copyright(c) 2014 Intel Corporation.
7b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  This program is free software; you can redistribute it and/or modify
8b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  it under the terms of version 2 of the GNU General Public License as
9b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  published by the Free Software Foundation.
10b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
11b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  This program is distributed in the hope that it will be useful, but
12b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  WITHOUT ANY WARRANTY; without even the implied warranty of
13b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  General Public License for more details.
15b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
16b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  Contact Information:
17b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  qat-linux@intel.com
18b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
19b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  BSD LICENSE
20b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  Copyright(c) 2014 Intel Corporation.
21b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  Redistribution and use in source and binary forms, with or without
22b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  modification, are permitted provided that the following conditions
23b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  are met:
24b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
25b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk    * Redistributions of source code must retain the above copyright
26b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      notice, this list of conditions and the following disclaimer.
27b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk    * Redistributions in binary form must reproduce the above copyright
28b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      notice, this list of conditions and the following disclaimer in
29b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      the documentation and/or other materials provided with the
30b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      distribution.
31b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk    * Neither the name of Intel Corporation nor the names of its
32b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      contributors may be used to endorse or promote products derived
33b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk      from this software without specific prior written permission.
34b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
35b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk*/
47b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include <linux/slab.h>
48b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include <linux/ctype.h>
49b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include <linux/kernel.h>
50b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
51b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include "adf_accel_devices.h"
52b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include "adf_common_drv.h"
53b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include "icp_qat_uclo.h"
54b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include "icp_qat_hal.h"
55b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#include "icp_qat_fw_loader_handle.h"
56b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
57b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define UWORD_CPYBUF_SIZE 1024
58b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define INVLD_UWORD 0xffffffffffull
59b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define PID_MINOR_REV 0xf
60b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define PID_MAJOR_REV (0xf << 4)
61b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
62b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_ae_data(struct icp_qat_uclo_objhandle *obj_handle,
63b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int ae, unsigned int image_num)
64b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
65b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_aedata *ae_data;
66b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_encapme *encap_image;
67b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_page *page = NULL;
68b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_aeslice *ae_slice = NULL;
69b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
70b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ae_data = &obj_handle->ae_data[ae];
71b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	encap_image = &obj_handle->ae_uimage[image_num];
72b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ae_slice = &ae_data->ae_slices[ae_data->slice_num];
73b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ae_slice->encap_image = encap_image;
74b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
75b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (encap_image->img_ptr) {
76b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae_slice->ctx_mask_assigned =
77b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					encap_image->img_ptr->ctx_assigned;
78b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae_data->eff_ustore_size = obj_handle->ustore_phy_size;
79b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	} else {
80b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae_slice->ctx_mask_assigned = 0;
81b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
828c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	ae_slice->region = kzalloc(sizeof(*ae_slice->region), GFP_KERNEL);
838c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	if (!ae_slice->region)
84b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -ENOMEM;
8545cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	ae_slice->page = kzalloc(sizeof(*ae_slice->page), GFP_KERNEL);
8645cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	if (!ae_slice->page)
87b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_err;
88b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page = ae_slice->page;
89b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->encap_page = encap_image->page;
908c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	ae_slice->page->region = ae_slice->region;
91b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ae_data->slice_num++;
92b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
93b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
948c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	kfree(ae_slice->region);
958c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	ae_slice->region = NULL;
96b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -ENOMEM;
97b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
98b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
99b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_free_ae_data(struct icp_qat_uclo_aedata *ae_data)
100b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1018c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	unsigned int i;
102b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
103b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!ae_data) {
104b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: bad argument, ae_data is NULL\n ");
105b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
106b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
107b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1088c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk	for (i = 0; i < ae_data->slice_num; i++) {
1098c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk		kfree(ae_data->ae_slices[i].region);
1108c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk		ae_data->ae_slices[i].region = NULL;
1118c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk		kfree(ae_data->ae_slices[i].page);
1128c1f8e3bbf60d0d06190be81f55d5199d52a463fTadeusz Struk		ae_data->ae_slices[i].page = NULL;
113b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
114b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
115b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
116b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
117b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic char *qat_uclo_get_string(struct icp_qat_uof_strtable *str_table,
118b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int str_offset)
119b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
120b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if ((!str_table->table_len) || (str_offset > str_table->table_len))
121b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return NULL;
122b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return (char *)(((unsigned long)(str_table->strings)) + str_offset);
123b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
124b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
125b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_check_format(struct icp_qat_uof_filehdr *hdr)
126b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
127b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int maj = hdr->maj_ver & 0xff;
128b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int min = hdr->min_ver & 0xff;
129b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
130b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (hdr->file_id != ICP_QAT_UOF_FID) {
131b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: Invalid header 0x%x\n", hdr->file_id);
132b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
133b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
134b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (min != ICP_QAT_UOF_MINVER || maj != ICP_QAT_UOF_MAJVER) {
135689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: bad UOF version, major 0x%x, minor 0x%x\n",
136b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       maj, min);
137b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
138b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
139b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
140b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
141b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
142b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_wr_sram_by_words(struct icp_qat_fw_loader_handle *handle,
143b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      unsigned int addr, unsigned int *val,
144b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      unsigned int num_in_bytes)
145b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
146b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int outval;
147b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char *ptr = (unsigned char *)val;
148b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
149b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (num_in_bytes) {
150b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&outval, ptr, 4);
151b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		SRAM_WRITE(handle, addr, outval);
152b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		num_in_bytes -= 4;
153b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ptr += 4;
154b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		addr += 4;
155b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
156b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
157b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
158b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_wr_umem_by_words(struct icp_qat_fw_loader_handle *handle,
159b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      unsigned char ae, unsigned int addr,
160b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      unsigned int *val,
161b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      unsigned int num_in_bytes)
162b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
163b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int outval;
164b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char *ptr = (unsigned char *)val;
165b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
166b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	addr >>= 0x2; /* convert to uword address */
167b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
168b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (num_in_bytes) {
169b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&outval, ptr, 4);
170b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_umem(handle, ae, addr++, 1, &outval);
171b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		num_in_bytes -= 4;
172b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ptr += 4;
173b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
174b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
175b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
176b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_batch_wr_umem(struct icp_qat_fw_loader_handle *handle,
177b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   unsigned char ae,
178b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   struct icp_qat_uof_batch_init
179b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   *umem_init_header)
180b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
181b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *umem_init;
182b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
183b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!umem_init_header)
184b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return;
185b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	umem_init = umem_init_header->next;
186b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (umem_init) {
187b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		unsigned int addr, *value, size;
188d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
189b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae = umem_init->ae;
190b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		addr = umem_init->addr;
191b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		value = umem_init->value;
192b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		size = umem_init->size;
193b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_wr_umem_by_words(handle, ae, addr, value, size);
194b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		umem_init = umem_init->next;
195b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
196b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
197b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
198b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void
199b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
200b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 struct icp_qat_uof_batch_init **base)
201b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
202b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *umem_init;
203b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
204b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	umem_init = *base;
205b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (umem_init) {
206b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		struct icp_qat_uof_batch_init *pre;
207d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
208b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pre = umem_init;
209b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		umem_init = umem_init->next;
210b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(pre);
211b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
212b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	*base = NULL;
213b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
214b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
215b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_parse_num(char *str, unsigned int *num)
216b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
2179a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	char buf[16] = {0};
218b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned long ae = 0;
219b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
220b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
221b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	strncpy(buf, str, 15);
222b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < 16; i++) {
223b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!isdigit(buf[i])) {
224b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			buf[i] = '\0';
225b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
226b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
227b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
228b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if ((kstrtoul(buf, 10, &ae)))
229b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
230b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
231b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	*num = (unsigned int)ae;
232b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
233b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
234b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
235b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_fetch_initmem_ae(struct icp_qat_fw_loader_handle *handle,
236b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     struct icp_qat_uof_initmem *init_mem,
237b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     unsigned int size_range, unsigned int *ae)
238b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
239b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
240b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	char *str;
241b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
242b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if ((init_mem->addr + init_mem->num_in_bytes) > (size_range << 0x2)) {
243b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: initmem is out of range");
244b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
245b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
246b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (init_mem->scope != ICP_QAT_UOF_LOCAL_SCOPE) {
247b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: Memory scope for init_mem error\n");
248b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
249b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
25045cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	str = qat_uclo_get_string(&obj_handle->str_table, init_mem->sym_name);
251b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!str) {
252689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: AE name assigned in UOF init table is NULL\n");
253b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
254b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
255b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_parse_num(str, ae)) {
256b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: Parse num for AE number failed\n");
257b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
258b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
259b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (*ae >= ICP_QAT_UCLO_MAX_AE) {
260b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: ae %d out of range\n", *ae);
261b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
262b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
263b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
264b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
265b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
266b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle
267b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   *handle, struct icp_qat_uof_initmem
268b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   *init_mem, unsigned int ae,
269b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   struct icp_qat_uof_batch_init
270b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   **init_tab_base)
271b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
272b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *init_header, *tail;
273b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *mem_init, *tail_old;
274b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_memvar_attr *mem_val_attr;
275b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i, flag = 0;
276b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
277b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	mem_val_attr =
278b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
279b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(struct icp_qat_uof_initmem));
280b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
281b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	init_header = *init_tab_base;
282b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!init_header) {
283b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header = kzalloc(sizeof(*init_header), GFP_KERNEL);
284b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!init_header)
285b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -ENOMEM;
286b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header->size = 1;
287b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*init_tab_base = init_header;
288b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		flag = 1;
289b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
290b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	tail_old = init_header;
291b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (tail_old->next)
292b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail_old = tail_old->next;
293b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	tail = tail_old;
294b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < init_mem->val_attr_num; i++) {
295b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init = kzalloc(sizeof(*mem_init), GFP_KERNEL);
296b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!mem_init)
297b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
298b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->ae = ae;
299b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->addr = init_mem->addr + mem_val_attr->offset_in_byte;
300b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->value = &mem_val_attr->value;
301b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->size = 4;
302b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->next = NULL;
303b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail->next = mem_init;
304b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail = mem_init;
305b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header->size += qat_hal_get_ins_num();
306b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_val_attr++;
307b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
308b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
309b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
310b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (tail_old) {
311b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init = tail_old->next;
312b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(tail_old);
313b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail_old = mem_init;
314b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
315b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (flag)
316b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(*init_tab_base);
317b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -ENOMEM;
318b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
319b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
320b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_lmem_seg(struct icp_qat_fw_loader_handle *handle,
321b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  struct icp_qat_uof_initmem *init_mem)
322b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
323b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
324b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae;
325b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
326b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_fetch_initmem_ae(handle, init_mem,
327b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      ICP_QAT_UCLO_MAX_LMEM_REG, &ae))
328b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
329b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
33045cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk					    &obj_handle->lm_init_tab[ae]))
331b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
332b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
333b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
334b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
335b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle,
336b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  struct icp_qat_uof_initmem *init_mem)
337b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
338b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
339b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae, ustore_size, uaddr, i;
340b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
341b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ustore_size = obj_handle->ustore_phy_size;
342b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_fetch_initmem_ae(handle, init_mem, ustore_size, &ae))
343b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
344b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
34545cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk					    &obj_handle->umem_init_tab[ae]))
346b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
347b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* set the highest ustore address referenced */
348b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uaddr = (init_mem->addr + init_mem->num_in_bytes) >> 0x2;
349b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->ae_data[ae].slice_num; i++) {
350b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (obj_handle->ae_data[ae].ae_slices[i].
351b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    encap_image->uwords_num < uaddr)
352b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_handle->ae_data[ae].ae_slices[i].
353b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			encap_image->uwords_num = uaddr;
354b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
355b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
356b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
357b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
358b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000
359b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle,
360b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   struct icp_qat_uof_initmem *init_mem)
361b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
362b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
363b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_memvar_attr *mem_val_attr;
364b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
365b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	mem_val_attr =
366b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
367b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(struct icp_qat_uof_initmem));
368b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
369b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	switch (init_mem->region) {
370b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_SRAM_REGION:
371b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if ((init_mem->addr + init_mem->num_in_bytes) >
372b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    ICP_DH895XCC_PESRAM_BAR_SIZE) {
373b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: initmem on SRAM is out of range");
374b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
375b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
376b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < init_mem->val_attr_num; i++) {
377b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_wr_sram_by_words(handle,
378b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  init_mem->addr +
379b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  mem_val_attr->offset_in_byte,
380b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  &mem_val_attr->value, 4);
381b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			mem_val_attr++;
382b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
383b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
384b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_LMEM_REGION:
385b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_lmem_seg(handle, init_mem))
386b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
387b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
388b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_UMEM_REGION:
389b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_umem_seg(handle, init_mem))
390b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
391b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
392b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	default:
393b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: initmem region error. region type=0x%x\n",
394b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       init_mem->region);
395b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
396b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
397b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
398b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
399b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
400b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_ustore(struct icp_qat_fw_loader_handle *handle,
401b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				struct icp_qat_uclo_encapme *image)
402b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
403b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
404b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_encap_page *page;
405b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *uof_image;
406b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae;
407b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ustore_size;
408b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int patt_pos;
409b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
410b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t *fill_data;
411b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
412b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uof_image = image->img_ptr;
413d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk	fill_data = kcalloc(ICP_QAT_UCLO_MAX_USTORE, sizeof(uint64_t),
414b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    GFP_KERNEL);
415b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!fill_data)
4169a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		return -ENOMEM;
417b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < ICP_QAT_UCLO_MAX_USTORE; i++)
418b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&fill_data[i], &uof_image->fill_pattern,
419b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       sizeof(uint64_t));
420b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page = image->page;
421b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
4229a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
42345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae, (unsigned long *)&uof_image->ae_assigned))
424b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
425b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ustore_size = obj_handle->ae_data[ae].eff_ustore_size;
426b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		patt_pos = page->beg_addr_p + page->micro_words_num;
427b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
428b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae, 0,
429b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  page->beg_addr_p, &fill_data[0]);
430b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae, patt_pos,
431b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  ustore_size - patt_pos + 1,
432b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  &fill_data[page->beg_addr_p]);
433b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
434b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(fill_data);
435b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
436b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
437b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
438b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_memory(struct icp_qat_fw_loader_handle *handle)
439b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
4409a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	int i, ae;
441b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
442b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_initmem *initmem = obj_handle->init_mem_tab.init_mem;
443b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
444b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->init_mem_tab.entry_num; i++) {
445b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (initmem->num_in_bytes) {
446b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_ae_memory(handle, initmem))
447b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
448b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
449b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		initmem = (struct icp_qat_uof_initmem *)((unsigned long)(
450b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(unsigned long)initmem +
451b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_initmem)) +
452b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(sizeof(struct icp_qat_uof_memvar_attr) *
453b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			initmem->val_attr_num));
454b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
4554f74c3989b14338544b65360ca4f8587c63d7fd9Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
456b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_hal_batch_wr_lm(handle, ae,
457b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					obj_handle->lm_init_tab[ae])) {
458b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: fail to batch init lmem for AE %d\n", ae);
459b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
460b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
461b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_cleanup_batch_init_list(handle,
462b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 &obj_handle->lm_init_tab[ae]);
463b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_batch_wr_umem(handle, ae,
464b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				       obj_handle->umem_init_tab[ae]);
465b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_cleanup_batch_init_list(handle,
466b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 &obj_handle->
467b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 umem_init_tab[ae]);
468b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
4699a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	return 0;
470b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
471b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
472b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void *qat_uclo_find_chunk(struct icp_qat_uof_objhdr *obj_hdr,
473b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 char *chunk_id, void *cur)
474b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
475b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
476b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr =
477b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    (struct icp_qat_uof_chunkhdr *)
478b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    ((unsigned long)obj_hdr + sizeof(struct icp_qat_uof_objhdr));
479b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
480b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_hdr->num_chunks; i++) {
481b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if ((cur < (void *)&chunk_hdr[i]) &&
48245cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		    !strncmp(chunk_hdr[i].chunk_id, chunk_id,
48345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			     ICP_QAT_UOF_OBJID_LEN)) {
484b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return &chunk_hdr[i];
485b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
486b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
487b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
488b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
489b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
490b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int qat_uclo_calc_checksum(unsigned int reg, int ch)
491b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
492b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
493b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int topbit = 1 << 0xF;
494b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int inbyte = (unsigned int)((reg >> 0x18) ^ ch);
495b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
496b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	reg ^= inbyte << 0x8;
497b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < 0x8; i++) {
498b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (reg & topbit)
499b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			reg = (reg << 1) ^ 0x1021;
500b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		else
501b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			reg <<= 1;
502b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
503b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return reg & 0xFFFF;
504b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
505b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
506b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int qat_uclo_calc_str_checksum(char *ptr, int num)
507b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
508b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int chksum = 0;
509b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
510b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ptr)
511b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		while (num--)
512b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chksum = qat_uclo_calc_checksum(chksum, *ptr++);
513b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return chksum;
514b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
515b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
516b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic struct icp_qat_uclo_objhdr *
517b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_chunk(char *buf, struct icp_qat_uof_filehdr *file_hdr,
518b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		   char *chunk_id)
519b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
520b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_filechunkhdr *file_chunk;
521b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhdr *obj_hdr;
5229a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	char *chunk;
523b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
524b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
525b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	file_chunk = (struct icp_qat_uof_filechunkhdr *)
526b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(buf + sizeof(struct icp_qat_uof_filehdr));
527b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < file_hdr->num_chunks; i++) {
52845cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!strncmp(file_chunk->chunk_id, chunk_id,
52945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			     ICP_QAT_UOF_OBJID_LEN)) {
530b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chunk = buf + file_chunk->offset;
531b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (file_chunk->checksum != qat_uclo_calc_str_checksum(
5329a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk				chunk, file_chunk->size))
533b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
534b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr = kzalloc(sizeof(*obj_hdr), GFP_KERNEL);
535b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!obj_hdr)
536b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
537b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->file_buff = chunk;
538b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->checksum = file_chunk->checksum;
539b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->size = file_chunk->size;
540b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return obj_hdr;
541b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
542b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		file_chunk++;
543b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
544b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
545b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
546b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
547b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int
548b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_check_image_compat(struct icp_qat_uof_encap_obj *encap_uof_obj,
549b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    struct icp_qat_uof_image *image)
550b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
551b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *uc_var_tab, *imp_var_tab, *imp_expr_tab;
552b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *neigh_reg_tab;
553b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_page *code_page;
554b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
555b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_page = (struct icp_qat_uof_code_page *)
556b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			((char *)image + sizeof(struct icp_qat_uof_image));
557b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uc_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
558b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		     code_page->uc_var_tab_offset);
559b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	imp_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
560b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		      code_page->imp_var_tab_offset);
561b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	imp_expr_tab = (struct icp_qat_uof_objtable *)
562b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       (encap_uof_obj->beg_uof +
563b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       code_page->imp_expr_tab_offset);
564b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (uc_var_tab->entry_num || imp_var_tab->entry_num ||
565b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    imp_expr_tab->entry_num) {
566b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain imported variable to be parsed");
567b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
568b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
569b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	neigh_reg_tab = (struct icp_qat_uof_objtable *)
570b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(encap_uof_obj->beg_uof +
571b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			code_page->neigh_reg_tab_offset);
572b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (neigh_reg_tab->entry_num) {
573b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain shared control store feature");
574b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
575b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
576b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (image->numpages > 1) {
577b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain multiple pages");
578b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
579b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
580b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_SHARED_USTORE_MODE(image->ae_mode)) {
581b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't use shared control store feature");
582b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
583b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
584b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (RELOADABLE_CTX_SHARED_MODE(image->ae_mode)) {
585b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't use reloadable feature");
586b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
587b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
588b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
589b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
590b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
5919a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Strukstatic void qat_uclo_map_image_page(struct icp_qat_uof_encap_obj
592b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     *encap_uof_obj,
593b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     struct icp_qat_uof_image *img,
594b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     struct icp_qat_uclo_encap_page *page)
595b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
596b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_page *code_page;
597b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_area *code_area;
598b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *uword_block_tab;
599b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_uword_block *uwblock;
600b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
601b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
602b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_page = (struct icp_qat_uof_code_page *)
603b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			((char *)img + sizeof(struct icp_qat_uof_image));
604b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->def_page = code_page->def_page;
605b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->page_region = code_page->page_region;
606b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->beg_addr_v = code_page->beg_addr_v;
607b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->beg_addr_p = code_page->beg_addr_p;
608b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_area = (struct icp_qat_uof_code_area *)(encap_uof_obj->beg_uof +
609b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						code_page->code_area_offset);
610b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->micro_words_num = code_area->micro_words_num;
611b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uword_block_tab = (struct icp_qat_uof_objtable *)
612b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			  (encap_uof_obj->beg_uof +
613b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			  code_area->uword_block_tab);
614b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->uwblock_num = uword_block_tab->entry_num;
615b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uwblock = (struct icp_qat_uof_uword_block *)((char *)uword_block_tab +
616b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
617b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->uwblock = (struct icp_qat_uclo_encap_uwblock *)uwblock;
618b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < uword_block_tab->entry_num; i++)
619b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page->uwblock[i].micro_words =
620b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(unsigned long)encap_uof_obj->beg_uof + uwblock[i].uword_offset;
621b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
622b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
623b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_map_uimage(struct icp_qat_uclo_objhandle *obj_handle,
624b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       struct icp_qat_uclo_encapme *ae_uimage,
625b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       int max_image)
626b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
6279a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	int i, j;
628b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr = NULL;
629b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *image;
630b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *ae_regtab;
631b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *init_reg_sym_tab;
632b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *sbreak_tab;
633b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_encap_obj *encap_uof_obj =
634b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					&obj_handle->encap_uof_obj;
635b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
6369a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (j = 0; j < max_image; j++) {
637b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
638b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						ICP_QAT_UOF_IMAG, chunk_hdr);
639b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!chunk_hdr)
640b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
641b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image = (struct icp_qat_uof_image *)(encap_uof_obj->beg_uof +
642b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						     chunk_hdr->offset);
643b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae_regtab = (struct icp_qat_uof_objtable *)
644b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   (image->reg_tab_offset +
645b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   obj_handle->obj_hdr->file_buff);
6469a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].ae_reg_num = ae_regtab->entry_num;
6479a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].ae_reg = (struct icp_qat_uof_ae_reg *)
648b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(((char *)ae_regtab) +
649b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
650b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_reg_sym_tab = (struct icp_qat_uof_objtable *)
651b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   (image->init_reg_sym_tab +
652b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   obj_handle->obj_hdr->file_buff);
6539a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].init_regsym_num = init_reg_sym_tab->entry_num;
6549a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].init_regsym = (struct icp_qat_uof_init_regsym *)
655b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(((char *)init_reg_sym_tab) +
656b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
657b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sbreak_tab = (struct icp_qat_uof_objtable *)
658b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(image->sbreak_tab + obj_handle->obj_hdr->file_buff);
6599a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].sbreak_num = sbreak_tab->entry_num;
6609a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].sbreak = (struct icp_qat_uof_sbreak *)
661b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      (((char *)sbreak_tab) +
662b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      sizeof(struct icp_qat_uof_objtable));
6639a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].img_ptr = image;
664b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_check_image_compat(encap_uof_obj, image))
665b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
6669a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].page =
667b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			kzalloc(sizeof(struct icp_qat_uclo_encap_page),
668b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				GFP_KERNEL);
6699a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		if (!ae_uimage[j].page)
670b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
6719a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		qat_uclo_map_image_page(encap_uof_obj, image,
6729a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk					ae_uimage[j].page);
673b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
6749a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	return j;
675b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
6769a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (i = 0; i < j; i++)
677b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(ae_uimage[i].page);
678b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
679b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
680b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
681b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_map_ae(struct icp_qat_fw_loader_handle *handle, int max_ae)
682b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
683b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i, ae;
684b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int mflag = 0;
685b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
686b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
687b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (ae = 0; ae <= max_ae; ae++) {
68845cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae,
68945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			      (unsigned long *)&handle->hal_handle->ae_mask))
690b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
691b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < obj_handle->uimage_num; i++) {
692b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!test_bit(ae, (unsigned long *)
69345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			&obj_handle->ae_uimage[i].img_ptr->ae_assigned))
694b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
695b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			mflag = 1;
696b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_ae_data(obj_handle, ae, i))
697b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
698b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
699b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
700b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!mflag) {
701b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: uimage uses AE not set");
702b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
703b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
704b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
705b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
706b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
707b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic struct icp_qat_uof_strtable *
708b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_str_table(struct icp_qat_uclo_objhdr *obj_hdr,
709b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       char *tab_name, struct icp_qat_uof_strtable *str_table)
710b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
711b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr;
712b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
713b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	chunk_hdr = qat_uclo_find_chunk((struct icp_qat_uof_objhdr *)
714b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					obj_hdr->file_buff, tab_name, NULL);
715b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (chunk_hdr) {
716b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		int hdr_size;
717d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
718b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&str_table->table_len, obj_hdr->file_buff +
719b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       chunk_hdr->offset, sizeof(str_table->table_len));
720b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		hdr_size = (char *)&str_table->strings - (char *)str_table;
721b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		str_table->strings = (unsigned long)obj_hdr->file_buff +
722b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					chunk_hdr->offset + hdr_size;
723b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return str_table;
724b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
725b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
726b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
727b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
728b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void
729b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_initmem_table(struct icp_qat_uof_encap_obj *encap_uof_obj,
730b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   struct icp_qat_uclo_init_mem_table *init_mem_tab)
731b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
732b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr;
733b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
734b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
735b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					ICP_QAT_UOF_IMEM, NULL);
736b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (chunk_hdr) {
737b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memmove(&init_mem_tab->entry_num, encap_uof_obj->beg_uof +
738b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chunk_hdr->offset, sizeof(unsigned int));
739b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_mem_tab->init_mem = (struct icp_qat_uof_initmem *)
740b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(encap_uof_obj->beg_uof + chunk_hdr->offset +
741b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(unsigned int));
742b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
743b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
744b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
745b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_check_uof_compat(struct icp_qat_uclo_objhandle *obj_handle)
746b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
747b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int maj_ver, prod_type = obj_handle->prod_type;
748b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
749b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!(prod_type & obj_handle->encap_uof_obj.obj_hdr->cpu_type)) {
750689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF type 0x%x not match with cur platform 0x%x\n",
751b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       obj_handle->encap_uof_obj.obj_hdr->cpu_type, prod_type);
752b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
753b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
754b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	maj_ver = obj_handle->prod_rev & 0xff;
755b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if ((obj_handle->encap_uof_obj.obj_hdr->max_cpu_ver < maj_ver) ||
756b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    (obj_handle->encap_uof_obj.obj_hdr->min_cpu_ver > maj_ver)) {
757689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF majVer 0x%x out of range\n", maj_ver);
758b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
759b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
760b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
761b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
762b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
763b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_reg(struct icp_qat_fw_loader_handle *handle,
764b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     unsigned char ae, unsigned char ctx_mask,
765b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     enum icp_qat_uof_regtype reg_type,
766b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     unsigned short reg_addr, unsigned int value)
767b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
768b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	switch (reg_type) {
769b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPA_ABS:
770b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPB_ABS:
771b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
772b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPA_REL:
773b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPB_REL:
774b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_gpr(handle, ae, ctx_mask, reg_type,
775b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					reg_addr, value);
776b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_ABS:
777b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_ABS:
778b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_RD_ABS:
779b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_RD_ABS:
780b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
781b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_REL:
782b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_REL:
783b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_RD_REL:
784b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_RD_REL:
785b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_rd_xfer(handle, ae, ctx_mask, reg_type,
786b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					    reg_addr, value);
787b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_WR_ABS:
788b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_WR_ABS:
789b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
790b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_WR_REL:
791b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_WR_REL:
792b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_wr_xfer(handle, ae, ctx_mask, reg_type,
793b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					    reg_addr, value);
794b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_NEIGH_REL:
795b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_nn(handle, ae, ctx_mask, reg_addr, value);
796b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	default:
797b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF uses not supported reg type 0x%x\n", reg_type);
798b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
799b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
800b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
801b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
802b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
803b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_reg_sym(struct icp_qat_fw_loader_handle *handle,
804b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int ae,
805b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 struct icp_qat_uclo_encapme *encap_ae)
806b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
807b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
808b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ctx_mask;
809b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_init_regsym *init_regsym;
810b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
811b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_CTX_MODE(encap_ae->img_ptr->ae_mode) ==
812b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    ICP_QAT_UCLO_MAX_CTX)
813b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0xff;
814b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	else
815b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0x55;
816b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
817b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < encap_ae->init_regsym_num; i++) {
818b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		unsigned int exp_res;
819d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
820b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_regsym = &encap_ae->init_regsym[i];
821b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		exp_res = init_regsym->value;
822b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		switch (init_regsym->init_type) {
823b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_REG:
824b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_init_reg(handle, ae, ctx_mask,
825b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (enum icp_qat_uof_regtype)
826b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  init_regsym->reg_type,
827b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned short)init_regsym->reg_addr,
828b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  exp_res);
829b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
830b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_REG_CTX:
831b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			/* check if ctx is appropriate for the ctxMode */
832b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!((1 << init_regsym->ctx) & ctx_mask)) {
833b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: invalid ctx num = 0x%x\n",
834b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				       init_regsym->ctx);
835b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
836b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
837b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_init_reg(handle, ae,
838b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned char)
839b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (1 << init_regsym->ctx),
840b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (enum icp_qat_uof_regtype)
841b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  init_regsym->reg_type,
842b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned short)init_regsym->reg_addr,
843b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  exp_res);
844b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
845b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_EXPR:
846b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: INIT_EXPR feature not supported\n");
847b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
848b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_EXPR_ENDIAN_SWAP:
849b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: INIT_EXPR_ENDIAN_SWAP feature not supported\n");
850b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
851b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		default:
852b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
853b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
854b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
855b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
856b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
857b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
858b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_globals(struct icp_qat_fw_loader_handle *handle)
859b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
860b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
861b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int s, ae;
862b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
863b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (obj_handle->global_inited)
864b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return 0;
865b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (obj_handle->init_mem_tab.entry_num) {
866b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_memory(handle)) {
867689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk			pr_err("QAT: initialize memory failed\n");
868b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
869b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
870b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
8719a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
872b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
873b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
874b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
875b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_reg_sym(handle, ae,
876b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  obj_handle->ae_data[ae].
877b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  ae_slices[s].encap_image))
878b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
879b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
880b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
881b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->global_inited = 1;
882b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
883b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
884b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
885b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_set_ae_mode(struct icp_qat_fw_loader_handle *handle)
886b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
887b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae, nn_mode, s;
888b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *uof_image;
889b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_aedata *ae_data;
890b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
891b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
8929a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
893b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!test_bit(ae,
89445cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			      (unsigned long *)&handle->hal_handle->ae_mask))
895b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
89645cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		ae_data = &obj_handle->ae_data[ae];
897df0088f50712f9540769c542d0b4d27acc4fc527Tadeusz Struk		for (s = 0; s < min_t(unsigned int, ae_data->slice_num,
898df0088f50712f9540769c542d0b4d27acc4fc527Tadeusz Struk				      ICP_QAT_UCLO_MAX_CTX); s++) {
89945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
900b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
901b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			uof_image = ae_data->ae_slices[s].encap_image->img_ptr;
902b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_ctx_mode(handle, ae,
903b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						    (char)ICP_QAT_CTX_MODE
904b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						    (uof_image->ae_mode))) {
905b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: qat_hal_set_ae_ctx_mode error\n");
906b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
907b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
908b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			nn_mode = ICP_QAT_NN_MODE(uof_image->ae_mode);
909b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_nn_mode(handle, ae, nn_mode)) {
910b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: qat_hal_set_ae_nn_mode error\n");
911b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
912b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
913b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM0,
914b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (char)ICP_QAT_LOC_MEM0_MODE
915b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (uof_image->ae_mode))) {
916689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk				pr_err("QAT: qat_hal_set_ae_lm_mode LMEM0 error\n");
917b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
918b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
919b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM1,
920b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (char)ICP_QAT_LOC_MEM1_MODE
921b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (uof_image->ae_mode))) {
922689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk				pr_err("QAT: qat_hal_set_ae_lm_mode LMEM1 error\n");
923b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
924b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
925b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
926b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
927b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
928b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
929b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
930b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_init_uword_num(struct icp_qat_fw_loader_handle *handle)
931b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
932b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
933b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_encapme *image;
934b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int a;
935b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
936b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (a = 0; a < obj_handle->uimage_num; a++) {
937b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image = &obj_handle->ae_uimage[a];
938b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image->uwords_num = image->page->beg_addr_p +
939b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					image->page->micro_words_num;
940b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
941b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
942b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
943b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_parse_uof_obj(struct icp_qat_fw_loader_handle *handle)
944b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
945b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
946b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae;
947b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
948d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk	obj_handle->uword_buf = kcalloc(UWORD_CPYBUF_SIZE, sizeof(uint64_t),
949b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					GFP_KERNEL);
950b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!obj_handle->uword_buf)
951b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -ENOMEM;
952b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->encap_uof_obj.beg_uof = obj_handle->obj_hdr->file_buff;
953b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->encap_uof_obj.obj_hdr = (struct icp_qat_uof_objhdr *)
954b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     obj_handle->obj_hdr->file_buff;
955b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->uword_in_bytes = 6;
956b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->prod_type = ICP_QAT_AC_C_CPU_TYPE;
957b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->prod_rev = PID_MAJOR_REV |
958b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(PID_MINOR_REV & handle->hal_handle->revision_id);
959b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_check_uof_compat(obj_handle)) {
960689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF incompatible\n");
961b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
962b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
963b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->ustore_phy_size = ICP_QAT_UCLO_MAX_USTORE;
96445cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	if (!obj_handle->obj_hdr->file_buff ||
96545cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	    !qat_uclo_map_str_table(obj_handle->obj_hdr, ICP_QAT_UOF_STRT,
96645cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk				    &obj_handle->str_table)) {
967689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF doesn't have effective images\n");
968b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_err;
969b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
970b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->uimage_num =
971b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_map_uimage(obj_handle, obj_handle->ae_uimage,
972b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				    ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX);
973b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!obj_handle->uimage_num)
974b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_err;
975b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_map_ae(handle, handle->hal_handle->ae_max_num)) {
976d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk		pr_err("QAT: Bad object\n");
977b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_check_uof_aemask_err;
978b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
979b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	qat_uclo_init_uword_num(handle);
98045cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	qat_uclo_map_initmem_table(&obj_handle->encap_uof_obj,
98145cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk				   &obj_handle->init_mem_tab);
982b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_set_ae_mode(handle))
983b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_check_uof_aemask_err;
984b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
985b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_check_uof_aemask_err:
986b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (ae = 0; ae < obj_handle->uimage_num; ae++)
987b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(obj_handle->ae_uimage[ae].page);
988b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
989b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->uword_buf);
990b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -EFAULT;
991b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
992b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
993b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukint qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle,
994b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			 void *addr_ptr, int mem_size)
995b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
996b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_filehdr *filehdr;
997b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *objhdl;
998b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
999b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	BUILD_BUG_ON(ICP_QAT_UCLO_MAX_AE >=
1000b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		     (sizeof(handle->hal_handle->ae_mask) * 8));
1001b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1002b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!handle || !addr_ptr || mem_size < 24)
1003b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
1004b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl = kzalloc(sizeof(*objhdl), GFP_KERNEL);
1005b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl)
1006b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -ENOMEM;
1007b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl->obj_buf = kmemdup(addr_ptr, mem_size, GFP_KERNEL);
1008b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl->obj_buf)
1009b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objbuf_err;
1010b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	filehdr = (struct icp_qat_uof_filehdr *)objhdl->obj_buf;
1011b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_check_format(filehdr))
1012b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objhdr_err;
1013b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl->obj_hdr = qat_uclo_map_chunk((char *)objhdl->obj_buf, filehdr,
1014b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     ICP_QAT_UOF_OBJS);
1015b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl->obj_hdr) {
1016b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: object file chunk is null\n");
1017b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objhdr_err;
1018b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1019b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = objhdl;
1020b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_parse_uof_obj(handle))
1021b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_overlay_obj_err;
1022b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
1023b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1024b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_overlay_obj_err:
1025b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = NULL;
1026b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl->obj_hdr);
1027b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_objhdr_err:
1028b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl->obj_buf);
1029b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_objbuf_err:
1030b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl);
1031b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -ENOMEM;
1032b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1033b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10348f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Strukvoid qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle)
1035b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1036b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
10379a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	unsigned int a;
1038b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10398f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk	if (!obj_handle)
10408f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk		return;
10418f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk
1042b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->uword_buf);
1043b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (a = 0; a < obj_handle->uimage_num; a++)
1044b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(obj_handle->ae_uimage[a].page);
1045b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10469a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (a = 0; a < handle->hal_handle->ae_max_num; a++)
1047b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_free_ae_data(&obj_handle->ae_data[a]);
1048b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10498f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk	kfree(obj_handle->obj_hdr);
1050b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->obj_buf);
1051b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle);
1052b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = NULL;
1053b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1054b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1055b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_fill_uwords(struct icp_qat_uclo_objhandle *obj_handle,
1056b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 struct icp_qat_uclo_encap_page *encap_page,
1057b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 uint64_t *uword, unsigned int addr_p,
1058b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int raddr, uint64_t fill)
1059b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1060b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t uwrd = 0;
1061b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
1062b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1063b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!encap_page) {
1064b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*uword = fill;
1065b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return;
1066b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1067b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < encap_page->uwblock_num; i++) {
1068b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (raddr >= encap_page->uwblock[i].start_addr &&
1069b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    raddr <= encap_page->uwblock[i].start_addr +
1070b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    encap_page->uwblock[i].words_num - 1) {
1071b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			raddr -= encap_page->uwblock[i].start_addr;
1072b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			raddr *= obj_handle->uword_in_bytes;
1073b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			memcpy(&uwrd, (void *)(((unsigned long)
1074b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       encap_page->uwblock[i].micro_words) + raddr),
1075b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       obj_handle->uword_in_bytes);
1076b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			uwrd = uwrd & 0xbffffffffffull;
1077b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
1078b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1079b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	*uword = uwrd;
1080b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (*uword == INVLD_UWORD)
1081b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*uword = fill;
1082b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1083b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1084341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Strukstatic void qat_uclo_wr_uimage_raw_page(struct icp_qat_fw_loader_handle *handle,
1085341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk					struct icp_qat_uclo_encap_page
1086341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk					*encap_page, unsigned int ae)
1087b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1088b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int uw_physical_addr, uw_relative_addr, i, words_num, cpylen;
1089b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1090b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t fill_pat;
1091b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1092b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* load the page starting at appropriate ustore address */
1093b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* get fill-pattern from an image -- they are all the same */
1094b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	memcpy(&fill_pat, obj_handle->ae_uimage[0].img_ptr->fill_pattern,
1095b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	       sizeof(uint64_t));
1096b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uw_physical_addr = encap_page->beg_addr_p;
1097b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uw_relative_addr = 0;
1098b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	words_num = encap_page->micro_words_num;
1099b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (words_num) {
1100b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (words_num < UWORD_CPYBUF_SIZE)
1101b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			cpylen = words_num;
1102b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		else
1103b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			cpylen = UWORD_CPYBUF_SIZE;
1104b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1105b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* load the buffer */
1106b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < cpylen; i++)
1107b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_fill_uwords(obj_handle, encap_page,
1108b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     &obj_handle->uword_buf[i],
1109b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     uw_physical_addr + i,
1110b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     uw_relative_addr + i, fill_pat);
1111b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1112b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* copy the buffer to ustore */
1113b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae,
1114b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  uw_physical_addr, cpylen,
1115b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  obj_handle->uword_buf);
1116b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1117b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		uw_physical_addr += cpylen;
1118b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		uw_relative_addr += cpylen;
1119b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		words_num -= cpylen;
1120b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1121b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1122b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
11239a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Strukstatic void qat_uclo_wr_uimage_page(struct icp_qat_fw_loader_handle *handle,
11249a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk				    struct icp_qat_uof_image *image)
1125b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1126b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1127b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ctx_mask, s;
1128b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_page *page;
1129b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae;
1130b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int ctx;
1131b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1132b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_CTX_MODE(image->ae_mode) == ICP_QAT_UCLO_MAX_CTX)
1133b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0xff;
1134b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	else
1135b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0x55;
1136b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* load the default page and set assigned CTX PC
1137b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	 * to the entrypoint address */
11389a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
113945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae, (unsigned long *)&image->ae_assigned))
1140b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1141b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* find the slice to which this image is assigned */
1142b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
1143b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (image->ctx_assigned & obj_handle->ae_data[ae].
1144b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    ae_slices[s].ctx_mask_assigned)
1145b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
1146b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
1147b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (s >= obj_handle->ae_data[ae].slice_num)
1148b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1149b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page = obj_handle->ae_data[ae].ae_slices[s].page;
1150b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!page->encap_page->def_page)
1151b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1152341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk		qat_uclo_wr_uimage_raw_page(handle, page->encap_page, ae);
1153b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1154b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page = obj_handle->ae_data[ae].ae_slices[s].page;
1155b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++)
1156b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_handle->ae_data[ae].ae_slices[s].cur_page[ctx] =
1157b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					(ctx_mask & (1 << ctx)) ? page : NULL;
1158b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_set_live_ctx(handle, (unsigned char)ae,
1159b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     image->ctx_assigned);
1160b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_set_pc(handle, (unsigned char)ae, image->ctx_assigned,
1161b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       image->entry_address);
1162b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1163b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1164b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1165b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukint qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle)
1166b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1167b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1168b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
1169b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1170b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_init_globals(handle))
1171b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
1172b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->uimage_num; i++) {
117345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!obj_handle->ae_uimage[i].img_ptr)
1174b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
117545cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (qat_uclo_init_ustore(handle, &obj_handle->ae_uimage[i]))
1176b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
11779a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		qat_uclo_wr_uimage_page(handle,
11789a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk					obj_handle->ae_uimage[i].img_ptr);
1179b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1180b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
1181b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1182