1 /*
2   This file is provided under a dual BSD/GPLv2 license.  When using or
3   redistributing this file, you may do so under either license.
4 
5   GPL LICENSE SUMMARY
6   Copyright(c) 2014 Intel Corporation.
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of version 2 of the GNU General Public License as
9   published by the Free Software Foundation.
10 
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   General Public License for more details.
15 
16   Contact Information:
17   qat-linux@intel.com
18 
19   BSD LICENSE
20   Copyright(c) 2014 Intel Corporation.
21   Redistribution and use in source and binary forms, with or without
22   modification, are permitted provided that the following conditions
23   are met:
24 
25     * Redistributions of source code must retain the above copyright
26       notice, this list of conditions and the following disclaimer.
27     * Redistributions in binary form must reproduce the above copyright
28       notice, this list of conditions and the following disclaimer in
29       the documentation and/or other materials provided with the
30       distribution.
31     * Neither the name of Intel Corporation nor the names of its
32       contributors may be used to endorse or promote products derived
33       from this software without specific prior written permission.
34 
35   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 */
47 #include <linux/types.h>
48 #include <linux/mutex.h>
49 #include <linux/slab.h>
50 #include <linux/delay.h>
51 #include <linux/pci.h>
52 #include <linux/dma-mapping.h>
53 #include "adf_accel_devices.h"
54 #include "adf_common_drv.h"
55 #include "icp_qat_fw_init_admin.h"
56 
57 /* Admin Messages Registers */
58 #define ADF_DH895XCC_ADMINMSGUR_OFFSET (0x3A000 + 0x574)
59 #define ADF_DH895XCC_ADMINMSGLR_OFFSET (0x3A000 + 0x578)
60 #define ADF_DH895XCC_MAILBOX_BASE_OFFSET 0x20970
61 #define ADF_DH895XCC_MAILBOX_STRIDE 0x1000
62 #define ADF_ADMINMSG_LEN 32
63 
64 static const u8 const_tab[1024] __aligned(1024) = {
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
78 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
90 0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
92 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
93 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
96 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
97 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
98 0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
100 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
101 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
104 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
105 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
106 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
107 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
108 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
110 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
111 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
112 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
113 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
114 0x7e, 0x21, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
144 
145 struct adf_admin_comms {
146 	dma_addr_t phy_addr;
147 	dma_addr_t const_tbl_addr;
148 	void *virt_addr;
149 	void *virt_tbl_addr;
150 	void __iomem *mailbox_addr;
151 	struct mutex lock;	/* protects adf_admin_comms struct */
152 };
153 
adf_put_admin_msg_sync(struct adf_accel_dev * accel_dev,u32 ae,void * in,void * out)154 static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae,
155 				  void *in, void *out)
156 {
157 	struct adf_admin_comms *admin = accel_dev->admin;
158 	int offset = ae * ADF_ADMINMSG_LEN * 2;
159 	void __iomem *mailbox = admin->mailbox_addr;
160 	int mb_offset = ae * ADF_DH895XCC_MAILBOX_STRIDE;
161 	int times, received;
162 
163 	mutex_lock(&admin->lock);
164 
165 	if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
166 		mutex_unlock(&admin->lock);
167 		return -EAGAIN;
168 	}
169 
170 	memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
171 	ADF_CSR_WR(mailbox, mb_offset, 1);
172 	received = 0;
173 	for (times = 0; times < 50; times++) {
174 		msleep(20);
175 		if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
176 			received = 1;
177 			break;
178 		}
179 	}
180 	if (received)
181 		memcpy(out, admin->virt_addr + offset +
182 		       ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
183 	else
184 		dev_err(&GET_DEV(accel_dev),
185 			"Failed to send admin msg to accelerator\n");
186 
187 	mutex_unlock(&admin->lock);
188 	return received ? 0 : -EFAULT;
189 }
190 
adf_send_admin_cmd(struct adf_accel_dev * accel_dev,int cmd)191 static int adf_send_admin_cmd(struct adf_accel_dev *accel_dev, int cmd)
192 {
193 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
194 	struct icp_qat_fw_init_admin_req req;
195 	struct icp_qat_fw_init_admin_resp resp;
196 	int i;
197 
198 	memset(&req, 0, sizeof(struct icp_qat_fw_init_admin_req));
199 	req.init_admin_cmd_id = cmd;
200 
201 	if (cmd == ICP_QAT_FW_CONSTANTS_CFG) {
202 		req.init_cfg_sz = 1024;
203 		req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
204 	}
205 	for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
206 		memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
207 		if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
208 		    resp.init_resp_hdr.status)
209 			return -EFAULT;
210 	}
211 	return 0;
212 }
213 
214 /**
215  * adf_send_admin_init() - Function sends init message to FW
216  * @accel_dev: Pointer to acceleration device.
217  *
218  * Function sends admin init message to the FW
219  *
220  * Return: 0 on success, error code otherwise.
221  */
adf_send_admin_init(struct adf_accel_dev * accel_dev)222 int adf_send_admin_init(struct adf_accel_dev *accel_dev)
223 {
224 	int ret = adf_send_admin_cmd(accel_dev, ICP_QAT_FW_INIT_ME);
225 
226 	if (ret)
227 		return ret;
228 	return adf_send_admin_cmd(accel_dev, ICP_QAT_FW_CONSTANTS_CFG);
229 }
230 EXPORT_SYMBOL_GPL(adf_send_admin_init);
231 
adf_init_admin_comms(struct adf_accel_dev * accel_dev)232 int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
233 {
234 	struct adf_admin_comms *admin;
235 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
236 	struct adf_bar *pmisc =
237 		&GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
238 	void __iomem *csr = pmisc->virt_addr;
239 	void __iomem *mailbox = (void __iomem *)((uintptr_t)csr +
240 				 ADF_DH895XCC_MAILBOX_BASE_OFFSET);
241 	u64 reg_val;
242 
243 	admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
244 			     dev_to_node(&GET_DEV(accel_dev)));
245 	if (!admin)
246 		return -ENOMEM;
247 	admin->virt_addr = dma_zalloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
248 					       &admin->phy_addr, GFP_KERNEL);
249 	if (!admin->virt_addr) {
250 		dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
251 		kfree(admin);
252 		return -ENOMEM;
253 	}
254 
255 	admin->virt_tbl_addr = dma_zalloc_coherent(&GET_DEV(accel_dev),
256 						   PAGE_SIZE,
257 						   &admin->const_tbl_addr,
258 						   GFP_KERNEL);
259 	if (!admin->virt_tbl_addr) {
260 		dev_err(&GET_DEV(accel_dev), "Failed to allocate const_tbl\n");
261 		dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
262 				  admin->virt_addr, admin->phy_addr);
263 		kfree(admin);
264 		return -ENOMEM;
265 	}
266 
267 	memcpy(admin->virt_tbl_addr, const_tab, sizeof(const_tab));
268 	reg_val = (u64)admin->phy_addr;
269 	ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGUR_OFFSET, reg_val >> 32);
270 	ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGLR_OFFSET, reg_val);
271 	mutex_init(&admin->lock);
272 	admin->mailbox_addr = mailbox;
273 	accel_dev->admin = admin;
274 	return 0;
275 }
276 EXPORT_SYMBOL_GPL(adf_init_admin_comms);
277 
adf_exit_admin_comms(struct adf_accel_dev * accel_dev)278 void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
279 {
280 	struct adf_admin_comms *admin = accel_dev->admin;
281 
282 	if (!admin)
283 		return;
284 
285 	if (admin->virt_addr)
286 		dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
287 				  admin->virt_addr, admin->phy_addr);
288 	if (admin->virt_tbl_addr)
289 		dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
290 				  admin->virt_tbl_addr, admin->const_tbl_addr);
291 
292 	mutex_destroy(&admin->lock);
293 	kfree(admin);
294 	accel_dev->admin = NULL;
295 }
296 EXPORT_SYMBOL_GPL(adf_exit_admin_comms);
297