qat_uclo.c revision 689917211cb9d4ca6f90765eeb228ac2727f5dbc
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	}
25945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	if (!test_bit(*ae, (unsigned long *)&handle->hal_handle->ae_mask)) {
260b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: ae %d to be init is fused off\n", *ae);
261b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
262b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
263b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (*ae >= ICP_QAT_UCLO_MAX_AE) {
264b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: ae %d out of range\n", *ae);
265b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
266b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
267b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
268b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
269b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
270b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle
271b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   *handle, struct icp_qat_uof_initmem
272b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   *init_mem, unsigned int ae,
273b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   struct icp_qat_uof_batch_init
274b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					   **init_tab_base)
275b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
276b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *init_header, *tail;
277b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_batch_init *mem_init, *tail_old;
278b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_memvar_attr *mem_val_attr;
279b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i, flag = 0;
280b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
281b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	mem_val_attr =
282b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
283b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(struct icp_qat_uof_initmem));
284b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
285b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	init_header = *init_tab_base;
286b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!init_header) {
287b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header = kzalloc(sizeof(*init_header), GFP_KERNEL);
288b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!init_header)
289b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -ENOMEM;
290b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header->size = 1;
291b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*init_tab_base = init_header;
292b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		flag = 1;
293b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
294b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	tail_old = init_header;
295b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (tail_old->next)
296b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail_old = tail_old->next;
297b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	tail = tail_old;
298b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < init_mem->val_attr_num; i++) {
299b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init = kzalloc(sizeof(*mem_init), GFP_KERNEL);
300b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!mem_init)
301b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
302b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->ae = ae;
303b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->addr = init_mem->addr + mem_val_attr->offset_in_byte;
304b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->value = &mem_val_attr->value;
305b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->size = 4;
306b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init->next = NULL;
307b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail->next = mem_init;
308b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail = mem_init;
309b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_header->size += qat_hal_get_ins_num();
310b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_val_attr++;
311b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
312b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
313b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
314b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (tail_old) {
315b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		mem_init = tail_old->next;
316b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(tail_old);
317b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		tail_old = mem_init;
318b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
319b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (flag)
320b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(*init_tab_base);
321b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -ENOMEM;
322b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
323b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
324b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_lmem_seg(struct icp_qat_fw_loader_handle *handle,
325b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  struct icp_qat_uof_initmem *init_mem)
326b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
327b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
328b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae;
329b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
330b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_fetch_initmem_ae(handle, init_mem,
331b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      ICP_QAT_UCLO_MAX_LMEM_REG, &ae))
332b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
333b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
33445cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk					    &obj_handle->lm_init_tab[ae]))
335b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
336b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
337b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
338b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
339b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle,
340b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  struct icp_qat_uof_initmem *init_mem)
341b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
342b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
343b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae, ustore_size, uaddr, i;
344b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
345b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	ustore_size = obj_handle->ustore_phy_size;
346b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_fetch_initmem_ae(handle, init_mem, ustore_size, &ae))
347b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
348b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
34945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk					    &obj_handle->umem_init_tab[ae]))
350b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
351b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* set the highest ustore address referenced */
352b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uaddr = (init_mem->addr + init_mem->num_in_bytes) >> 0x2;
353b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->ae_data[ae].slice_num; i++) {
354b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (obj_handle->ae_data[ae].ae_slices[i].
355b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    encap_image->uwords_num < uaddr)
356b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_handle->ae_data[ae].ae_slices[i].
357b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			encap_image->uwords_num = uaddr;
358b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
359b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
360b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
361b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
362b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000
363b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle,
364b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   struct icp_qat_uof_initmem *init_mem)
365b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
366b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
367b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_memvar_attr *mem_val_attr;
368b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
369b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	mem_val_attr =
370b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
371b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(struct icp_qat_uof_initmem));
372b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
373b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	switch (init_mem->region) {
374b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_SRAM_REGION:
375b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if ((init_mem->addr + init_mem->num_in_bytes) >
376b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    ICP_DH895XCC_PESRAM_BAR_SIZE) {
377b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: initmem on SRAM is out of range");
378b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
379b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
380b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < init_mem->val_attr_num; i++) {
381b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_wr_sram_by_words(handle,
382b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  init_mem->addr +
383b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  mem_val_attr->offset_in_byte,
384b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  &mem_val_attr->value, 4);
385b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			mem_val_attr++;
386b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
387b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
388b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_LMEM_REGION:
389b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_lmem_seg(handle, init_mem))
390b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
391b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
392b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_QAT_UOF_UMEM_REGION:
393b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_umem_seg(handle, init_mem))
394b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
395b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		break;
396b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	default:
397b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: initmem region error. region type=0x%x\n",
398b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       init_mem->region);
399b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
400b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
401b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
402b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
403b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
404b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_ustore(struct icp_qat_fw_loader_handle *handle,
405b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				struct icp_qat_uclo_encapme *image)
406b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
407b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
408b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_encap_page *page;
409b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *uof_image;
410b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae;
411b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ustore_size;
412b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int patt_pos;
413b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
414b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t *fill_data;
415b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
416b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uof_image = image->img_ptr;
417d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk	fill_data = kcalloc(ICP_QAT_UCLO_MAX_USTORE, sizeof(uint64_t),
418b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    GFP_KERNEL);
419b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!fill_data)
4209a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		return -ENOMEM;
421b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < ICP_QAT_UCLO_MAX_USTORE; i++)
422b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&fill_data[i], &uof_image->fill_pattern,
423b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       sizeof(uint64_t));
424b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page = image->page;
425b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
4269a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
42745cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae, (unsigned long *)&uof_image->ae_assigned))
428b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
429b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ustore_size = obj_handle->ae_data[ae].eff_ustore_size;
430b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		patt_pos = page->beg_addr_p + page->micro_words_num;
431b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
432b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae, 0,
433b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  page->beg_addr_p, &fill_data[0]);
434b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae, patt_pos,
435b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  ustore_size - patt_pos + 1,
436b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  &fill_data[page->beg_addr_p]);
437b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
438b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(fill_data);
439b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
440b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
441b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
442b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_memory(struct icp_qat_fw_loader_handle *handle)
443b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
4449a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	int i, ae;
445b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
446b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_initmem *initmem = obj_handle->init_mem_tab.init_mem;
447b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
448b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->init_mem_tab.entry_num; i++) {
449b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (initmem->num_in_bytes) {
450b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_ae_memory(handle, initmem))
451b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
452b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
453b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		initmem = (struct icp_qat_uof_initmem *)((unsigned long)(
454b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(unsigned long)initmem +
455b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_initmem)) +
456b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(sizeof(struct icp_qat_uof_memvar_attr) *
457b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			initmem->val_attr_num));
458b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
459b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (ae = 0; ae < ICP_QAT_UCLO_MAX_AE; ae++) {
460b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_hal_batch_wr_lm(handle, ae,
461b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					obj_handle->lm_init_tab[ae])) {
462b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: fail to batch init lmem for AE %d\n", ae);
463b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
464b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
465b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_cleanup_batch_init_list(handle,
466b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 &obj_handle->lm_init_tab[ae]);
467b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_batch_wr_umem(handle, ae,
468b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				       obj_handle->umem_init_tab[ae]);
469b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_cleanup_batch_init_list(handle,
470b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 &obj_handle->
471b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						 umem_init_tab[ae]);
472b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
4739a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	return 0;
474b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
475b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
476b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void *qat_uclo_find_chunk(struct icp_qat_uof_objhdr *obj_hdr,
477b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 char *chunk_id, void *cur)
478b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
479b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
480b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr =
481b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    (struct icp_qat_uof_chunkhdr *)
482b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    ((unsigned long)obj_hdr + sizeof(struct icp_qat_uof_objhdr));
483b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
484b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_hdr->num_chunks; i++) {
485b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if ((cur < (void *)&chunk_hdr[i]) &&
48645cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		    !strncmp(chunk_hdr[i].chunk_id, chunk_id,
48745cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			     ICP_QAT_UOF_OBJID_LEN)) {
488b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return &chunk_hdr[i];
489b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
490b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
491b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
492b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
493b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
494b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int qat_uclo_calc_checksum(unsigned int reg, int ch)
495b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
496b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
497b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int topbit = 1 << 0xF;
498b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int inbyte = (unsigned int)((reg >> 0x18) ^ ch);
499b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
500b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	reg ^= inbyte << 0x8;
501b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < 0x8; i++) {
502b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (reg & topbit)
503b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			reg = (reg << 1) ^ 0x1021;
504b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		else
505b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			reg <<= 1;
506b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
507b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return reg & 0xFFFF;
508b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
509b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
510b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int qat_uclo_calc_str_checksum(char *ptr, int num)
511b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
512b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int chksum = 0;
513b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
514b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ptr)
515b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		while (num--)
516b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chksum = qat_uclo_calc_checksum(chksum, *ptr++);
517b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return chksum;
518b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
519b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
520b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic struct icp_qat_uclo_objhdr *
521b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_chunk(char *buf, struct icp_qat_uof_filehdr *file_hdr,
522b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		   char *chunk_id)
523b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
524b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_filechunkhdr *file_chunk;
525b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhdr *obj_hdr;
5269a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	char *chunk;
527b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
528b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
529b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	file_chunk = (struct icp_qat_uof_filechunkhdr *)
530b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(buf + sizeof(struct icp_qat_uof_filehdr));
531b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < file_hdr->num_chunks; i++) {
53245cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!strncmp(file_chunk->chunk_id, chunk_id,
53345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			     ICP_QAT_UOF_OBJID_LEN)) {
534b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chunk = buf + file_chunk->offset;
535b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (file_chunk->checksum != qat_uclo_calc_str_checksum(
5369a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk				chunk, file_chunk->size))
537b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
538b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr = kzalloc(sizeof(*obj_hdr), GFP_KERNEL);
539b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!obj_hdr)
540b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
541b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->file_buff = chunk;
542b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->checksum = file_chunk->checksum;
543b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_hdr->size = file_chunk->size;
544b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return obj_hdr;
545b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
546b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		file_chunk++;
547b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
548b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
549b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
550b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
551b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic unsigned int
552b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_check_image_compat(struct icp_qat_uof_encap_obj *encap_uof_obj,
553b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    struct icp_qat_uof_image *image)
554b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
555b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *uc_var_tab, *imp_var_tab, *imp_expr_tab;
556b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *neigh_reg_tab;
557b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_page *code_page;
558b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
559b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_page = (struct icp_qat_uof_code_page *)
560b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			((char *)image + sizeof(struct icp_qat_uof_image));
561b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uc_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
562b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		     code_page->uc_var_tab_offset);
563b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	imp_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
564b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		      code_page->imp_var_tab_offset);
565b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	imp_expr_tab = (struct icp_qat_uof_objtable *)
566b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       (encap_uof_obj->beg_uof +
567b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       code_page->imp_expr_tab_offset);
568b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (uc_var_tab->entry_num || imp_var_tab->entry_num ||
569b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    imp_expr_tab->entry_num) {
570b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain imported variable to be parsed");
571b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
572b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
573b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	neigh_reg_tab = (struct icp_qat_uof_objtable *)
574b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(encap_uof_obj->beg_uof +
575b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			code_page->neigh_reg_tab_offset);
576b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (neigh_reg_tab->entry_num) {
577b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain shared control store feature");
578b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
579b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
580b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (image->numpages > 1) {
581b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't contain multiple pages");
582b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
583b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
584b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_SHARED_USTORE_MODE(image->ae_mode)) {
585b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't use shared control store feature");
586b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
587b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
588b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (RELOADABLE_CTX_SHARED_MODE(image->ae_mode)) {
589b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF can't use reloadable feature");
590b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
591b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
592b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
593b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
594b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
5959a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Strukstatic void qat_uclo_map_image_page(struct icp_qat_uof_encap_obj
596b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     *encap_uof_obj,
597b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     struct icp_qat_uof_image *img,
598b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     struct icp_qat_uclo_encap_page *page)
599b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
600b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_page *code_page;
601b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_code_area *code_area;
602b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *uword_block_tab;
603b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_uword_block *uwblock;
604b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i;
605b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
606b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_page = (struct icp_qat_uof_code_page *)
607b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			((char *)img + sizeof(struct icp_qat_uof_image));
608b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->def_page = code_page->def_page;
609b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->page_region = code_page->page_region;
610b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->beg_addr_v = code_page->beg_addr_v;
611b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->beg_addr_p = code_page->beg_addr_p;
612b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	code_area = (struct icp_qat_uof_code_area *)(encap_uof_obj->beg_uof +
613b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						code_page->code_area_offset);
614b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->micro_words_num = code_area->micro_words_num;
615b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uword_block_tab = (struct icp_qat_uof_objtable *)
616b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			  (encap_uof_obj->beg_uof +
617b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			  code_area->uword_block_tab);
618b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->uwblock_num = uword_block_tab->entry_num;
619b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uwblock = (struct icp_qat_uof_uword_block *)((char *)uword_block_tab +
620b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
621b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	page->uwblock = (struct icp_qat_uclo_encap_uwblock *)uwblock;
622b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < uword_block_tab->entry_num; i++)
623b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page->uwblock[i].micro_words =
624b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(unsigned long)encap_uof_obj->beg_uof + uwblock[i].uword_offset;
625b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
626b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
627b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_map_uimage(struct icp_qat_uclo_objhandle *obj_handle,
628b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       struct icp_qat_uclo_encapme *ae_uimage,
629b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       int max_image)
630b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
6319a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	int i, j;
632b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr = NULL;
633b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *image;
634b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *ae_regtab;
635b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *init_reg_sym_tab;
636b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_objtable *sbreak_tab;
637b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_encap_obj *encap_uof_obj =
638b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					&obj_handle->encap_uof_obj;
639b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
6409a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (j = 0; j < max_image; j++) {
641b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
642b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						ICP_QAT_UOF_IMAG, chunk_hdr);
643b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!chunk_hdr)
644b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
645b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image = (struct icp_qat_uof_image *)(encap_uof_obj->beg_uof +
646b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						     chunk_hdr->offset);
647b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ae_regtab = (struct icp_qat_uof_objtable *)
648b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   (image->reg_tab_offset +
649b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   obj_handle->obj_hdr->file_buff);
6509a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].ae_reg_num = ae_regtab->entry_num;
6519a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].ae_reg = (struct icp_qat_uof_ae_reg *)
652b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(((char *)ae_regtab) +
653b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
654b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_reg_sym_tab = (struct icp_qat_uof_objtable *)
655b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   (image->init_reg_sym_tab +
656b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				   obj_handle->obj_hdr->file_buff);
6579a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].init_regsym_num = init_reg_sym_tab->entry_num;
6589a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].init_regsym = (struct icp_qat_uof_init_regsym *)
659b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(((char *)init_reg_sym_tab) +
660b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			sizeof(struct icp_qat_uof_objtable));
661b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sbreak_tab = (struct icp_qat_uof_objtable *)
662b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(image->sbreak_tab + obj_handle->obj_hdr->file_buff);
6639a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].sbreak_num = sbreak_tab->entry_num;
6649a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].sbreak = (struct icp_qat_uof_sbreak *)
665b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      (((char *)sbreak_tab) +
666b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				      sizeof(struct icp_qat_uof_objtable));
6679a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].img_ptr = image;
668b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_check_image_compat(encap_uof_obj, image))
669b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
6709a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		ae_uimage[j].page =
671b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			kzalloc(sizeof(struct icp_qat_uclo_encap_page),
672b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				GFP_KERNEL);
6739a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		if (!ae_uimage[j].page)
674b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			goto out_err;
6759a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		qat_uclo_map_image_page(encap_uof_obj, image,
6769a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk					ae_uimage[j].page);
677b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
6789a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	return j;
679b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
6809a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (i = 0; i < j; i++)
681b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(ae_uimage[i].page);
682b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
683b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
684b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
685b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_map_ae(struct icp_qat_fw_loader_handle *handle, int max_ae)
686b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
687b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int i, ae;
688b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int mflag = 0;
689b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
690b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
691b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (ae = 0; ae <= max_ae; ae++) {
69245cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae,
69345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			      (unsigned long *)&handle->hal_handle->ae_mask))
694b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
695b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < obj_handle->uimage_num; i++) {
696b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!test_bit(ae, (unsigned long *)
69745cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			&obj_handle->ae_uimage[i].img_ptr->ae_assigned))
698b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
699b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			mflag = 1;
700b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_ae_data(obj_handle, ae, i))
701b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
702b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
703b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
704b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!mflag) {
705b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: uimage uses AE not set");
706b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
707b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
708b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
709b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
710b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
711b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic struct icp_qat_uof_strtable *
712b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_str_table(struct icp_qat_uclo_objhdr *obj_hdr,
713b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       char *tab_name, struct icp_qat_uof_strtable *str_table)
714b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
715b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr;
716b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
717b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	chunk_hdr = qat_uclo_find_chunk((struct icp_qat_uof_objhdr *)
718b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					obj_hdr->file_buff, tab_name, NULL);
719b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (chunk_hdr) {
720b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		int hdr_size;
721d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
722b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memcpy(&str_table->table_len, obj_hdr->file_buff +
723b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       chunk_hdr->offset, sizeof(str_table->table_len));
724b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		hdr_size = (char *)&str_table->strings - (char *)str_table;
725b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		str_table->strings = (unsigned long)obj_hdr->file_buff +
726b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					chunk_hdr->offset + hdr_size;
727b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return str_table;
728b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
729b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return NULL;
730b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
731b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
732b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void
733b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukqat_uclo_map_initmem_table(struct icp_qat_uof_encap_obj *encap_uof_obj,
734b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			   struct icp_qat_uclo_init_mem_table *init_mem_tab)
735b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
736b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_chunkhdr *chunk_hdr;
737b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
738b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
739b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					ICP_QAT_UOF_IMEM, NULL);
740b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (chunk_hdr) {
741b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		memmove(&init_mem_tab->entry_num, encap_uof_obj->beg_uof +
742b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			chunk_hdr->offset, sizeof(unsigned int));
743b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_mem_tab->init_mem = (struct icp_qat_uof_initmem *)
744b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		(encap_uof_obj->beg_uof + chunk_hdr->offset +
745b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		sizeof(unsigned int));
746b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
747b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
748b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
749b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_check_uof_compat(struct icp_qat_uclo_objhandle *obj_handle)
750b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
751b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int maj_ver, prod_type = obj_handle->prod_type;
752b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
753b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!(prod_type & obj_handle->encap_uof_obj.obj_hdr->cpu_type)) {
754689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF type 0x%x not match with cur platform 0x%x\n",
755b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		       obj_handle->encap_uof_obj.obj_hdr->cpu_type, prod_type);
756b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
757b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
758b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	maj_ver = obj_handle->prod_rev & 0xff;
759b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if ((obj_handle->encap_uof_obj.obj_hdr->max_cpu_ver < maj_ver) ||
760b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    (obj_handle->encap_uof_obj.obj_hdr->min_cpu_ver > maj_ver)) {
761689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF majVer 0x%x out of range\n", maj_ver);
762b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
763b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
764b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
765b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
766b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
767b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_reg(struct icp_qat_fw_loader_handle *handle,
768b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     unsigned char ae, unsigned char ctx_mask,
769b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     enum icp_qat_uof_regtype reg_type,
770b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			     unsigned short reg_addr, unsigned int value)
771b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
772b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	switch (reg_type) {
773b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPA_ABS:
774b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPB_ABS:
775b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
776b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPA_REL:
777b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_GPB_REL:
778b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_gpr(handle, ae, ctx_mask, reg_type,
779b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					reg_addr, value);
780b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_ABS:
781b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_ABS:
782b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_RD_ABS:
783b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_RD_ABS:
784b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
785b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_REL:
786b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_REL:
787b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_RD_REL:
788b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_RD_REL:
789b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_rd_xfer(handle, ae, ctx_mask, reg_type,
790b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					    reg_addr, value);
791b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_WR_ABS:
792b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_WR_ABS:
793b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0;
794b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_SR_WR_REL:
795b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_DR_WR_REL:
796b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_wr_xfer(handle, ae, ctx_mask, reg_type,
797b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					    reg_addr, value);
798b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	case ICP_NEIGH_REL:
799b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return qat_hal_init_nn(handle, ae, ctx_mask, reg_addr, value);
800b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	default:
801b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: UOF uses not supported reg type 0x%x\n", reg_type);
802b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EFAULT;
803b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
804b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
805b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
806b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
807b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_reg_sym(struct icp_qat_fw_loader_handle *handle,
808b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int ae,
809b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 struct icp_qat_uclo_encapme *encap_ae)
810b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
811b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
812b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ctx_mask;
813b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_init_regsym *init_regsym;
814b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
815b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_CTX_MODE(encap_ae->img_ptr->ae_mode) ==
816b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	    ICP_QAT_UCLO_MAX_CTX)
817b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0xff;
818b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	else
819b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0x55;
820b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
821b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < encap_ae->init_regsym_num; i++) {
822b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		unsigned int exp_res;
823d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk
824b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		init_regsym = &encap_ae->init_regsym[i];
825b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		exp_res = init_regsym->value;
826b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		switch (init_regsym->init_type) {
827b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_REG:
828b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_init_reg(handle, ae, ctx_mask,
829b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (enum icp_qat_uof_regtype)
830b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  init_regsym->reg_type,
831b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned short)init_regsym->reg_addr,
832b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  exp_res);
833b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
834b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_REG_CTX:
835b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			/* check if ctx is appropriate for the ctxMode */
836b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!((1 << init_regsym->ctx) & ctx_mask)) {
837b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: invalid ctx num = 0x%x\n",
838b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				       init_regsym->ctx);
839b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
840b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
841b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_init_reg(handle, ae,
842b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned char)
843b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (1 << init_regsym->ctx),
844b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (enum icp_qat_uof_regtype)
845b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  init_regsym->reg_type,
846b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  (unsigned short)init_regsym->reg_addr,
847b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					  exp_res);
848b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
849b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_EXPR:
850b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: INIT_EXPR feature not supported\n");
851b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
852b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		case ICP_QAT_UOF_INIT_EXPR_ENDIAN_SWAP:
853b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			pr_err("QAT: INIT_EXPR_ENDIAN_SWAP feature not supported\n");
854b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
855b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		default:
856b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			break;
857b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
858b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
859b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
860b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
861b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
862b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_init_globals(struct icp_qat_fw_loader_handle *handle)
863b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
864b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
865b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int s, ae;
866b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
867b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (obj_handle->global_inited)
868b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return 0;
869b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (obj_handle->init_mem_tab.entry_num) {
870b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (qat_uclo_init_memory(handle)) {
871689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk			pr_err("QAT: initialize memory failed\n");
872b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
873b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
874b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
8759a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
876b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
877b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
878b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
879b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_uclo_init_reg_sym(handle, ae,
880b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  obj_handle->ae_data[ae].
881b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						  ae_slices[s].encap_image))
882b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EINVAL;
883b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
884b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
885b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->global_inited = 1;
886b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
887b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
888b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
889b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_set_ae_mode(struct icp_qat_fw_loader_handle *handle)
890b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
891b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae, nn_mode, s;
892b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_image *uof_image;
893b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_aedata *ae_data;
894b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
895b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
8969a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
897b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!test_bit(ae,
89845cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			      (unsigned long *)&handle->hal_handle->ae_mask))
899b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
90045cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		ae_data = &obj_handle->ae_data[ae];
901df0088f50712f9540769c542d0b4d27acc4fc527Tadeusz Struk		for (s = 0; s < min_t(unsigned int, ae_data->slice_num,
902df0088f50712f9540769c542d0b4d27acc4fc527Tadeusz Struk				      ICP_QAT_UCLO_MAX_CTX); s++) {
90345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk			if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
904b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				continue;
905b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			uof_image = ae_data->ae_slices[s].encap_image->img_ptr;
906b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_ctx_mode(handle, ae,
907b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						    (char)ICP_QAT_CTX_MODE
908b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						    (uof_image->ae_mode))) {
909b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: qat_hal_set_ae_ctx_mode error\n");
910b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
911b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
912b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			nn_mode = ICP_QAT_NN_MODE(uof_image->ae_mode);
913b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_nn_mode(handle, ae, nn_mode)) {
914b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				pr_err("QAT: qat_hal_set_ae_nn_mode error\n");
915b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
916b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
917b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM0,
918b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (char)ICP_QAT_LOC_MEM0_MODE
919b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (uof_image->ae_mode))) {
920689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk				pr_err("QAT: qat_hal_set_ae_lm_mode LMEM0 error\n");
921b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
922b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
923b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM1,
924b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (char)ICP_QAT_LOC_MEM1_MODE
925b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk						   (uof_image->ae_mode))) {
926689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk				pr_err("QAT: qat_hal_set_ae_lm_mode LMEM1 error\n");
927b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				return -EFAULT;
928b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			}
929b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
930b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
931b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
932b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
933b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
934b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_init_uword_num(struct icp_qat_fw_loader_handle *handle)
935b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
936b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
937b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_encapme *image;
938b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int a;
939b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
940b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (a = 0; a < obj_handle->uimage_num; a++) {
941b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image = &obj_handle->ae_uimage[a];
942b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		image->uwords_num = image->page->beg_addr_p +
943b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					image->page->micro_words_num;
944b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
945b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
946b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
947b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic int qat_uclo_parse_uof_obj(struct icp_qat_fw_loader_handle *handle)
948b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
949b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
950b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ae;
951b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
952d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk	obj_handle->uword_buf = kcalloc(UWORD_CPYBUF_SIZE, sizeof(uint64_t),
953b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					GFP_KERNEL);
954b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!obj_handle->uword_buf)
955b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -ENOMEM;
956b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->encap_uof_obj.beg_uof = obj_handle->obj_hdr->file_buff;
957b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->encap_uof_obj.obj_hdr = (struct icp_qat_uof_objhdr *)
958b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     obj_handle->obj_hdr->file_buff;
959b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->uword_in_bytes = 6;
960b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->prod_type = ICP_QAT_AC_C_CPU_TYPE;
961b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->prod_rev = PID_MAJOR_REV |
962b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			(PID_MINOR_REV & handle->hal_handle->revision_id);
963b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_check_uof_compat(obj_handle)) {
964689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF incompatible\n");
965b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
966b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
967b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->ustore_phy_size = ICP_QAT_UCLO_MAX_USTORE;
96845cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	if (!obj_handle->obj_hdr->file_buff ||
96945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	    !qat_uclo_map_str_table(obj_handle->obj_hdr, ICP_QAT_UOF_STRT,
97045cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk				    &obj_handle->str_table)) {
971689917211cb9d4ca6f90765eeb228ac2727f5dbcTadeusz Struk		pr_err("QAT: UOF doesn't have effective images\n");
972b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_err;
973b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
974b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	obj_handle->uimage_num =
975b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_map_uimage(obj_handle, obj_handle->ae_uimage,
976b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				    ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX);
977b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!obj_handle->uimage_num)
978b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_err;
979b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_map_ae(handle, handle->hal_handle->ae_max_num)) {
980d65071ecde1ed1b99d057a877e0e3d29748c3a4dTadeusz Struk		pr_err("QAT: Bad object\n");
981b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_check_uof_aemask_err;
982b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
983b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	qat_uclo_init_uword_num(handle);
98445cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk	qat_uclo_map_initmem_table(&obj_handle->encap_uof_obj,
98545cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk				   &obj_handle->init_mem_tab);
986b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_set_ae_mode(handle))
987b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_check_uof_aemask_err;
988b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
989b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_check_uof_aemask_err:
990b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (ae = 0; ae < obj_handle->uimage_num; ae++)
991b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(obj_handle->ae_uimage[ae].page);
992b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_err:
993b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->uword_buf);
994b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -EFAULT;
995b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
996b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
997b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukint qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle,
998b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			 void *addr_ptr, int mem_size)
999b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1000b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uof_filehdr *filehdr;
1001b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *objhdl;
1002b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1003b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	BUILD_BUG_ON(ICP_QAT_UCLO_MAX_AE >=
1004b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		     (sizeof(handle->hal_handle->ae_mask) * 8));
1005b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1006b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!handle || !addr_ptr || mem_size < 24)
1007b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
1008b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl = kzalloc(sizeof(*objhdl), GFP_KERNEL);
1009b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl)
1010b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -ENOMEM;
1011b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl->obj_buf = kmemdup(addr_ptr, mem_size, GFP_KERNEL);
1012b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl->obj_buf)
1013b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objbuf_err;
1014b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	filehdr = (struct icp_qat_uof_filehdr *)objhdl->obj_buf;
1015b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_check_format(filehdr))
1016b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objhdr_err;
1017b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	objhdl->obj_hdr = qat_uclo_map_chunk((char *)objhdl->obj_buf, filehdr,
1018b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     ICP_QAT_UOF_OBJS);
1019b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!objhdl->obj_hdr) {
1020b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		pr_err("QAT: object file chunk is null\n");
1021b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_objhdr_err;
1022b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1023b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = objhdl;
1024b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_parse_uof_obj(handle))
1025b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		goto out_overlay_obj_err;
1026b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
1027b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1028b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_overlay_obj_err:
1029b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = NULL;
1030b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl->obj_hdr);
1031b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_objhdr_err:
1032b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl->obj_buf);
1033b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukout_objbuf_err:
1034b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(objhdl);
1035b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return -ENOMEM;
1036b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1037b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10388f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Strukvoid qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle)
1039b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1040b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
10419a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	unsigned int a;
1042b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10438f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk	if (!obj_handle)
10448f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk		return;
10458f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk
1046b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->uword_buf);
1047b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (a = 0; a < obj_handle->uimage_num; a++)
1048b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		kfree(obj_handle->ae_uimage[a].page);
1049b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10509a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (a = 0; a < handle->hal_handle->ae_max_num; a++)
1051b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_uclo_free_ae_data(&obj_handle->ae_data[a]);
1052b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
10538f312d64b5eea5c1f807265c1010969a0cb4b876Tadeusz Struk	kfree(obj_handle->obj_hdr);
1054b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle->obj_buf);
1055b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	kfree(obj_handle);
1056b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	handle->obj_handle = NULL;
1057b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1058b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1059b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukstatic void qat_uclo_fill_uwords(struct icp_qat_uclo_objhandle *obj_handle,
1060b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 struct icp_qat_uclo_encap_page *encap_page,
1061b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 uint64_t *uword, unsigned int addr_p,
1062b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				 unsigned int raddr, uint64_t fill)
1063b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1064b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t uwrd = 0;
1065b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
1066b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1067b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (!encap_page) {
1068b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*uword = fill;
1069b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return;
1070b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1071b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < encap_page->uwblock_num; i++) {
1072b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (raddr >= encap_page->uwblock[i].start_addr &&
1073b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    raddr <= encap_page->uwblock[i].start_addr +
1074b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		    encap_page->uwblock[i].words_num - 1) {
1075b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			raddr -= encap_page->uwblock[i].start_addr;
1076b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			raddr *= obj_handle->uword_in_bytes;
1077b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			memcpy(&uwrd, (void *)(((unsigned long)
1078b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       encap_page->uwblock[i].micro_words) + raddr),
1079b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       obj_handle->uword_in_bytes);
1080b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			uwrd = uwrd & 0xbffffffffffull;
1081b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
1082b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1083b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	*uword = uwrd;
1084b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (*uword == INVLD_UWORD)
1085b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		*uword = fill;
1086b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1087b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1088341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Strukstatic void qat_uclo_wr_uimage_raw_page(struct icp_qat_fw_loader_handle *handle,
1089341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk					struct icp_qat_uclo_encap_page
1090341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk					*encap_page, unsigned int ae)
1091b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1092b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int uw_physical_addr, uw_relative_addr, i, words_num, cpylen;
1093b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1094b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uint64_t fill_pat;
1095b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1096b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* load the page starting at appropriate ustore address */
1097b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* get fill-pattern from an image -- they are all the same */
1098b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	memcpy(&fill_pat, obj_handle->ae_uimage[0].img_ptr->fill_pattern,
1099b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	       sizeof(uint64_t));
1100b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uw_physical_addr = encap_page->beg_addr_p;
1101b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	uw_relative_addr = 0;
1102b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	words_num = encap_page->micro_words_num;
1103b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	while (words_num) {
1104b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (words_num < UWORD_CPYBUF_SIZE)
1105b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			cpylen = words_num;
1106b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		else
1107b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			cpylen = UWORD_CPYBUF_SIZE;
1108b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1109b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* load the buffer */
1110b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (i = 0; i < cpylen; i++)
1111b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			qat_uclo_fill_uwords(obj_handle, encap_page,
1112b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     &obj_handle->uword_buf[i],
1113b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     uw_physical_addr + i,
1114b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					     uw_relative_addr + i, fill_pat);
1115b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1116b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* copy the buffer to ustore */
1117b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_wr_uwords(handle, (unsigned char)ae,
1118b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  uw_physical_addr, cpylen,
1119b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				  obj_handle->uword_buf);
1120b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1121b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		uw_physical_addr += cpylen;
1122b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		uw_relative_addr += cpylen;
1123b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		words_num -= cpylen;
1124b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1125b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1126b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
11279a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Strukstatic void qat_uclo_wr_uimage_page(struct icp_qat_fw_loader_handle *handle,
11289a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk				    struct icp_qat_uof_image *image)
1129b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1130b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1131b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int ctx_mask, s;
1132b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_page *page;
1133b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned char ae;
1134b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	int ctx;
1135b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1136b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (ICP_QAT_CTX_MODE(image->ae_mode) == ICP_QAT_UCLO_MAX_CTX)
1137b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0xff;
1138b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	else
1139b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		ctx_mask = 0x55;
1140b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	/* load the default page and set assigned CTX PC
1141b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	 * to the entrypoint address */
11429a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk	for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
114345cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!test_bit(ae, (unsigned long *)&image->ae_assigned))
1144b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1145b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		/* find the slice to which this image is assigned */
1146b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
1147b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			if (image->ctx_assigned & obj_handle->ae_data[ae].
1148b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			    ae_slices[s].ctx_mask_assigned)
1149b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				break;
1150b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		}
1151b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (s >= obj_handle->ae_data[ae].slice_num)
1152b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1153b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page = obj_handle->ae_data[ae].ae_slices[s].page;
1154b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		if (!page->encap_page->def_page)
1155b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			continue;
1156341b2a3541c21a2c60daf87bcd6d6e8c4f1aed62Tadeusz Struk		qat_uclo_wr_uimage_raw_page(handle, page->encap_page, ae);
1157b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1158b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		page = obj_handle->ae_data[ae].ae_slices[s].page;
1159b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++)
1160b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			obj_handle->ae_data[ae].ae_slices[s].cur_page[ctx] =
1161b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk					(ctx_mask & (1 << ctx)) ? page : NULL;
1162b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_set_live_ctx(handle, (unsigned char)ae,
1163b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk				     image->ctx_assigned);
1164b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		qat_hal_set_pc(handle, (unsigned char)ae, image->ctx_assigned,
1165b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			       image->entry_address);
1166b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1167b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1168b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1169b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Strukint qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle)
1170b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk{
1171b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
1172b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	unsigned int i;
1173b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk
1174b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	if (qat_uclo_init_globals(handle))
1175b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk		return -EINVAL;
1176b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	for (i = 0; i < obj_handle->uimage_num; i++) {
117745cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (!obj_handle->ae_uimage[i].img_ptr)
1178b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
117945cff2608007ab28047cadb33e85b58c40b447ceTadeusz Struk		if (qat_uclo_init_ustore(handle, &obj_handle->ae_uimage[i]))
1180b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk			return -EINVAL;
11819a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk		qat_uclo_wr_uimage_page(handle,
11829a147cb3232fd8dbd44ed4628c6c0d05033d4c61Tadeusz Struk					obj_handle->ae_uimage[i].img_ptr);
1183b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	}
1184b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk	return 0;
1185b4b7e67c917fa8e2171b2ee7717b44efd7a52c47Tadeusz Struk}
1186