Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/crypto/intel/qat/qat_common/adf_admin.c
29278 views
1
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2
/* Copyright(c) 2014 - 2020 Intel Corporation */
3
#include <linux/types.h>
4
#include <linux/mutex.h>
5
#include <linux/slab.h>
6
#include <linux/iopoll.h>
7
#include <linux/pci.h>
8
#include <linux/dma-mapping.h>
9
#include "adf_accel_devices.h"
10
#include "adf_admin.h"
11
#include "adf_common_drv.h"
12
#include "adf_cfg.h"
13
#include "adf_heartbeat.h"
14
#include "icp_qat_fw_init_admin.h"
15
16
#define ADF_ADMIN_MAILBOX_STRIDE 0x1000
17
#define ADF_ADMINMSG_LEN 32
18
#define ADF_CONST_TABLE_SIZE 1024
19
#define ADF_ADMIN_POLL_DELAY_US 20
20
#define ADF_ADMIN_POLL_TIMEOUT_US (5 * USEC_PER_SEC)
21
#define ADF_ONE_AE 1
22
23
static const u8 const_tab[1024] __aligned(1024) = {
24
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
30
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
31
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
33
0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
34
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
35
0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
36
0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
37
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
38
0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
39
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
47
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
49
0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
51
0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
52
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
55
0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
56
0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
57
0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
59
0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
60
0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
61
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62
0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
63
0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
64
0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
65
0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
66
0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
67
0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68
0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
69
0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
70
0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
71
0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
72
0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
73
0x7e, 0x21, 0x79, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
76
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x18,
77
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00,
79
0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80
0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x00,
81
0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02,
82
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
83
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
84
0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25,
85
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
86
0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00,
87
0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88
0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00,
89
0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
90
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91
0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
92
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00,
94
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
95
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
103
104
struct adf_admin_comms {
105
dma_addr_t phy_addr;
106
dma_addr_t const_tbl_addr;
107
void *virt_addr;
108
void *virt_tbl_addr;
109
void __iomem *mailbox_addr;
110
struct mutex lock; /* protects adf_admin_comms struct */
111
};
112
113
static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae,
114
void *in, void *out)
115
{
116
int ret;
117
u32 status;
118
struct adf_admin_comms *admin = accel_dev->admin;
119
int offset = ae * ADF_ADMINMSG_LEN * 2;
120
void __iomem *mailbox = admin->mailbox_addr;
121
int mb_offset = ae * ADF_ADMIN_MAILBOX_STRIDE;
122
struct icp_qat_fw_init_admin_req *request = in;
123
124
mutex_lock(&admin->lock);
125
126
if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
127
mutex_unlock(&admin->lock);
128
return -EAGAIN;
129
}
130
131
memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
132
ADF_CSR_WR(mailbox, mb_offset, 1);
133
134
ret = read_poll_timeout(ADF_CSR_RD, status, status == 0,
135
ADF_ADMIN_POLL_DELAY_US,
136
ADF_ADMIN_POLL_TIMEOUT_US, true,
137
mailbox, mb_offset);
138
if (ret < 0) {
139
/* Response timeout */
140
dev_err(&GET_DEV(accel_dev),
141
"Failed to send admin msg %d to accelerator %d\n",
142
request->cmd_id, ae);
143
} else {
144
/* Response received from admin message, we can now
145
* make response data available in "out" parameter.
146
*/
147
memcpy(out, admin->virt_addr + offset +
148
ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
149
}
150
151
mutex_unlock(&admin->lock);
152
return ret;
153
}
154
155
static int adf_send_admin(struct adf_accel_dev *accel_dev,
156
struct icp_qat_fw_init_admin_req *req,
157
struct icp_qat_fw_init_admin_resp *resp,
158
const unsigned long ae_mask)
159
{
160
u32 ae;
161
162
for_each_set_bit(ae, &ae_mask, ICP_QAT_HW_AE_DELIMITER)
163
if (adf_put_admin_msg_sync(accel_dev, ae, req, resp) ||
164
resp->status)
165
return -EFAULT;
166
167
return 0;
168
}
169
170
static int adf_init_ae(struct adf_accel_dev *accel_dev)
171
{
172
struct icp_qat_fw_init_admin_req req;
173
struct icp_qat_fw_init_admin_resp resp;
174
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
175
u32 ae_mask = hw_device->ae_mask;
176
177
memset(&req, 0, sizeof(req));
178
memset(&resp, 0, sizeof(resp));
179
req.cmd_id = ICP_QAT_FW_INIT_AE;
180
181
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
182
}
183
184
static int adf_set_fw_constants(struct adf_accel_dev *accel_dev)
185
{
186
struct icp_qat_fw_init_admin_req req;
187
struct icp_qat_fw_init_admin_resp resp;
188
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
189
u32 ae_mask = hw_device->admin_ae_mask ?: hw_device->ae_mask;
190
191
memset(&req, 0, sizeof(req));
192
memset(&resp, 0, sizeof(resp));
193
req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG;
194
195
req.init_cfg_sz = ADF_CONST_TABLE_SIZE;
196
req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
197
198
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
199
}
200
201
int adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp)
202
{
203
struct icp_qat_fw_init_admin_req req = { };
204
struct icp_qat_fw_init_admin_resp resp;
205
unsigned int ae_mask = ADF_ONE_AE;
206
int ret;
207
208
req.cmd_id = ICP_QAT_FW_TIMER_GET;
209
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
210
if (ret)
211
return ret;
212
213
*timestamp = resp.timestamp;
214
return 0;
215
}
216
217
static int adf_set_chaining(struct adf_accel_dev *accel_dev)
218
{
219
u32 ae_mask = GET_HW_DATA(accel_dev)->ae_mask;
220
struct icp_qat_fw_init_admin_resp resp = { };
221
struct icp_qat_fw_init_admin_req req = { };
222
223
req.cmd_id = ICP_QAT_FW_DC_CHAIN_INIT;
224
225
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
226
}
227
228
static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev,
229
u32 *capabilities)
230
{
231
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
232
struct icp_qat_fw_init_admin_resp resp;
233
struct icp_qat_fw_init_admin_req req;
234
unsigned long ae_mask;
235
unsigned long ae;
236
int ret;
237
238
/* Target only service accelerator engines */
239
ae_mask = hw_device->ae_mask & ~hw_device->admin_ae_mask;
240
241
memset(&req, 0, sizeof(req));
242
memset(&resp, 0, sizeof(resp));
243
req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET;
244
245
*capabilities = 0;
246
for_each_set_bit(ae, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) {
247
ret = adf_send_admin(accel_dev, &req, &resp, 1ULL << ae);
248
if (ret)
249
return ret;
250
251
*capabilities |= resp.extended_features;
252
}
253
254
return 0;
255
}
256
257
int adf_get_ae_fw_counters(struct adf_accel_dev *accel_dev, u16 ae, u64 *reqs, u64 *resps)
258
{
259
struct icp_qat_fw_init_admin_resp resp = { };
260
struct icp_qat_fw_init_admin_req req = { };
261
int ret;
262
263
req.cmd_id = ICP_QAT_FW_COUNTERS_GET;
264
265
ret = adf_put_admin_msg_sync(accel_dev, ae, &req, &resp);
266
if (ret || resp.status)
267
return -EFAULT;
268
269
*reqs = resp.req_rec_count;
270
*resps = resp.resp_sent_count;
271
272
return 0;
273
}
274
275
int adf_send_admin_tim_sync(struct adf_accel_dev *accel_dev, u32 cnt)
276
{
277
u32 ae_mask = accel_dev->hw_device->ae_mask;
278
struct icp_qat_fw_init_admin_req req = { };
279
struct icp_qat_fw_init_admin_resp resp = { };
280
281
req.cmd_id = ICP_QAT_FW_SYNC;
282
req.int_timer_ticks = cnt;
283
284
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
285
}
286
287
int adf_send_admin_hb_timer(struct adf_accel_dev *accel_dev, uint32_t ticks)
288
{
289
u32 ae_mask = accel_dev->hw_device->ae_mask;
290
struct icp_qat_fw_init_admin_req req = { };
291
struct icp_qat_fw_init_admin_resp resp;
292
293
req.cmd_id = ICP_QAT_FW_HEARTBEAT_TIMER_SET;
294
req.init_cfg_ptr = accel_dev->heartbeat->dma.phy_addr;
295
req.heartbeat_ticks = ticks;
296
297
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
298
}
299
300
static bool is_dcc_enabled(struct adf_accel_dev *accel_dev)
301
{
302
char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
303
int ret;
304
305
ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
306
ADF_SERVICES_ENABLED, services);
307
if (ret)
308
return false;
309
310
return !strcmp(services, "dcc");
311
}
312
313
static int adf_get_fw_capabilities(struct adf_accel_dev *accel_dev, u16 *caps)
314
{
315
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
316
struct icp_qat_fw_init_admin_resp resp = { };
317
struct icp_qat_fw_init_admin_req req = { };
318
int ret;
319
320
if (!ae_mask)
321
return 0;
322
323
req.cmd_id = ICP_QAT_FW_CAPABILITIES_GET;
324
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
325
if (ret)
326
return ret;
327
328
*caps = resp.fw_capabilities;
329
330
return 0;
331
}
332
333
int adf_send_admin_rl_init(struct adf_accel_dev *accel_dev,
334
struct icp_qat_fw_init_admin_slice_cnt *slices)
335
{
336
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
337
struct icp_qat_fw_init_admin_resp resp = { };
338
struct icp_qat_fw_init_admin_req req = { };
339
int ret;
340
341
req.cmd_id = ICP_QAT_FW_RL_INIT;
342
343
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
344
if (ret)
345
return ret;
346
347
memcpy(slices, &resp.slices, sizeof(*slices));
348
349
return 0;
350
}
351
352
int adf_send_admin_rl_add_update(struct adf_accel_dev *accel_dev,
353
struct icp_qat_fw_init_admin_req *req)
354
{
355
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
356
struct icp_qat_fw_init_admin_resp resp = { };
357
358
/*
359
* req struct filled in rl implementation. Used commands
360
* ICP_QAT_FW_RL_ADD for a new SLA
361
* ICP_QAT_FW_RL_UPDATE for update SLA
362
*/
363
return adf_send_admin(accel_dev, req, &resp, ae_mask);
364
}
365
366
int adf_send_admin_rl_delete(struct adf_accel_dev *accel_dev, u16 node_id,
367
u8 node_type)
368
{
369
u32 ae_mask = accel_dev->hw_device->admin_ae_mask;
370
struct icp_qat_fw_init_admin_resp resp = { };
371
struct icp_qat_fw_init_admin_req req = { };
372
373
req.cmd_id = ICP_QAT_FW_RL_REMOVE;
374
req.node_id = node_id;
375
req.node_type = node_type;
376
377
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
378
}
379
380
/**
381
* adf_send_admin_init() - Function sends init message to FW
382
* @accel_dev: Pointer to acceleration device.
383
*
384
* Function sends admin init message to the FW
385
*
386
* Return: 0 on success, error code otherwise.
387
*/
388
int adf_send_admin_init(struct adf_accel_dev *accel_dev)
389
{
390
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
391
u32 dc_capabilities = 0;
392
int ret;
393
394
ret = adf_set_fw_constants(accel_dev);
395
if (ret)
396
return ret;
397
398
if (is_dcc_enabled(accel_dev)) {
399
ret = adf_set_chaining(accel_dev);
400
if (ret)
401
return ret;
402
}
403
404
ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities);
405
if (ret) {
406
dev_err(&GET_DEV(accel_dev), "Cannot get dc capabilities\n");
407
return ret;
408
}
409
accel_dev->hw_device->extended_dc_capabilities = dc_capabilities;
410
411
adf_get_fw_capabilities(accel_dev, &hw_data->fw_capabilities);
412
413
return adf_init_ae(accel_dev);
414
}
415
EXPORT_SYMBOL_GPL(adf_send_admin_init);
416
417
/**
418
* adf_init_admin_pm() - Function sends PM init message to FW
419
* @accel_dev: Pointer to acceleration device.
420
* @idle_delay: QAT HW idle time before power gating is initiated.
421
* 000 - 64us
422
* 001 - 128us
423
* 010 - 256us
424
* 011 - 512us
425
* 100 - 1ms
426
* 101 - 2ms
427
* 110 - 4ms
428
* 111 - 8ms
429
*
430
* Function sends to the FW the admin init message for the PM state
431
* configuration.
432
*
433
* Return: 0 on success, error code otherwise.
434
*/
435
int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay)
436
{
437
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
438
struct icp_qat_fw_init_admin_resp resp = {0};
439
struct icp_qat_fw_init_admin_req req = {0};
440
u32 ae_mask = hw_data->admin_ae_mask;
441
442
if (!accel_dev->admin) {
443
dev_err(&GET_DEV(accel_dev), "adf_admin is not available\n");
444
return -EFAULT;
445
}
446
447
req.cmd_id = ICP_QAT_FW_PM_STATE_CONFIG;
448
req.idle_filter = idle_delay;
449
450
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
451
}
452
EXPORT_SYMBOL_GPL(adf_init_admin_pm);
453
454
int adf_get_pm_info(struct adf_accel_dev *accel_dev, dma_addr_t p_state_addr,
455
size_t buff_size)
456
{
457
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
458
struct icp_qat_fw_init_admin_req req = { };
459
struct icp_qat_fw_init_admin_resp resp;
460
u32 ae_mask = hw_data->admin_ae_mask;
461
int ret;
462
463
/* Query pm info via init/admin cmd */
464
if (!accel_dev->admin) {
465
dev_err(&GET_DEV(accel_dev), "adf_admin is not available\n");
466
return -EFAULT;
467
}
468
469
req.cmd_id = ICP_QAT_FW_PM_INFO;
470
req.init_cfg_sz = buff_size;
471
req.init_cfg_ptr = p_state_addr;
472
473
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
474
if (ret)
475
dev_err(&GET_DEV(accel_dev),
476
"Failed to query power-management info\n");
477
478
return ret;
479
}
480
481
int adf_get_cnv_stats(struct adf_accel_dev *accel_dev, u16 ae, u16 *err_cnt,
482
u16 *latest_err)
483
{
484
struct icp_qat_fw_init_admin_req req = { };
485
struct icp_qat_fw_init_admin_resp resp;
486
int ret;
487
488
req.cmd_id = ICP_QAT_FW_CNV_STATS_GET;
489
490
ret = adf_put_admin_msg_sync(accel_dev, ae, &req, &resp);
491
if (ret)
492
return ret;
493
if (resp.status)
494
return -EPROTONOSUPPORT;
495
496
*err_cnt = resp.error_count;
497
*latest_err = resp.latest_error;
498
499
return ret;
500
}
501
502
int adf_send_admin_tl_start(struct adf_accel_dev *accel_dev,
503
dma_addr_t tl_dma_addr, size_t layout_sz, u8 *rp_indexes,
504
struct icp_qat_fw_init_admin_slice_cnt *slice_count)
505
{
506
u32 ae_mask = GET_HW_DATA(accel_dev)->admin_ae_mask;
507
struct icp_qat_fw_init_admin_resp resp = { };
508
struct icp_qat_fw_init_admin_req req = { };
509
int ret;
510
511
req.cmd_id = ICP_QAT_FW_TL_START;
512
req.init_cfg_ptr = tl_dma_addr;
513
req.init_cfg_sz = layout_sz;
514
515
if (rp_indexes)
516
memcpy(&req.rp_indexes, rp_indexes, sizeof(req.rp_indexes));
517
518
ret = adf_send_admin(accel_dev, &req, &resp, ae_mask);
519
if (ret)
520
return ret;
521
522
memcpy(slice_count, &resp.slices, sizeof(*slice_count));
523
524
return 0;
525
}
526
527
int adf_send_admin_tl_stop(struct adf_accel_dev *accel_dev)
528
{
529
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
530
struct icp_qat_fw_init_admin_resp resp = { };
531
struct icp_qat_fw_init_admin_req req = { };
532
u32 ae_mask = hw_data->admin_ae_mask;
533
534
req.cmd_id = ICP_QAT_FW_TL_STOP;
535
536
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
537
}
538
539
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
540
{
541
struct adf_admin_comms *admin;
542
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
543
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
544
struct admin_info admin_csrs_info;
545
u32 mailbox_offset, adminmsg_u, adminmsg_l;
546
void __iomem *mailbox;
547
u64 reg_val;
548
549
admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
550
dev_to_node(&GET_DEV(accel_dev)));
551
if (!admin)
552
return -ENOMEM;
553
admin->virt_addr = dma_alloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
554
&admin->phy_addr, GFP_KERNEL);
555
if (!admin->virt_addr) {
556
dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
557
kfree(admin);
558
return -ENOMEM;
559
}
560
561
admin->virt_tbl_addr = dma_alloc_coherent(&GET_DEV(accel_dev),
562
PAGE_SIZE,
563
&admin->const_tbl_addr,
564
GFP_KERNEL);
565
if (!admin->virt_tbl_addr) {
566
dev_err(&GET_DEV(accel_dev), "Failed to allocate const_tbl\n");
567
dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
568
admin->virt_addr, admin->phy_addr);
569
kfree(admin);
570
return -ENOMEM;
571
}
572
573
memcpy(admin->virt_tbl_addr, const_tab, sizeof(const_tab));
574
hw_data->get_admin_info(&admin_csrs_info);
575
576
mailbox_offset = admin_csrs_info.mailbox_offset;
577
mailbox = pmisc_addr + mailbox_offset;
578
adminmsg_u = admin_csrs_info.admin_msg_ur;
579
adminmsg_l = admin_csrs_info.admin_msg_lr;
580
581
reg_val = (u64)admin->phy_addr;
582
ADF_CSR_WR(pmisc_addr, adminmsg_u, upper_32_bits(reg_val));
583
ADF_CSR_WR(pmisc_addr, adminmsg_l, lower_32_bits(reg_val));
584
585
mutex_init(&admin->lock);
586
admin->mailbox_addr = mailbox;
587
accel_dev->admin = admin;
588
return 0;
589
}
590
EXPORT_SYMBOL_GPL(adf_init_admin_comms);
591
592
void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
593
{
594
struct adf_admin_comms *admin = accel_dev->admin;
595
596
if (!admin)
597
return;
598
599
if (admin->virt_addr)
600
dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
601
admin->virt_addr, admin->phy_addr);
602
if (admin->virt_tbl_addr)
603
dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
604
admin->virt_tbl_addr, admin->const_tbl_addr);
605
606
mutex_destroy(&admin->lock);
607
kfree(admin);
608
accel_dev->admin = NULL;
609
}
610
EXPORT_SYMBOL_GPL(adf_exit_admin_comms);
611
612