1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47#include <linux/mutex.h>
48#include <linux/list.h>
49#include <linux/bitops.h>
50#include <linux/delay.h>
51#include "adf_accel_devices.h"
52#include "adf_cfg.h"
53#include "adf_common_drv.h"
54
55static LIST_HEAD(service_table);
56static DEFINE_MUTEX(service_lock);
57
58static void adf_service_add(struct service_hndl *service)
59{
60 mutex_lock(&service_lock);
61 list_add(&service->list, &service_table);
62 mutex_unlock(&service_lock);
63}
64
65int adf_service_register(struct service_hndl *service)
66{
67 memset(service->init_status, 0, sizeof(service->init_status));
68 memset(service->start_status, 0, sizeof(service->start_status));
69 adf_service_add(service);
70 return 0;
71}
72
73static void adf_service_remove(struct service_hndl *service)
74{
75 mutex_lock(&service_lock);
76 list_del(&service->list);
77 mutex_unlock(&service_lock);
78}
79
80int adf_service_unregister(struct service_hndl *service)
81{
82 int i;
83
84 for (i = 0; i < ARRAY_SIZE(service->init_status); i++) {
85 if (service->init_status[i] || service->start_status[i]) {
86 pr_err("QAT: Could not remove active service\n");
87 return -EFAULT;
88 }
89 }
90 adf_service_remove(service);
91 return 0;
92}
93
94
95
96
97
98
99
100
101
102
103int adf_dev_init(struct adf_accel_dev *accel_dev)
104{
105 struct service_hndl *service;
106 struct list_head *list_itr;
107 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
108
109 if (!hw_data) {
110 dev_err(&GET_DEV(accel_dev),
111 "Failed to init device - hw_data not set\n");
112 return -EFAULT;
113 }
114
115 if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
116 dev_err(&GET_DEV(accel_dev), "Device not configured\n");
117 return -EFAULT;
118 }
119
120 if (adf_init_etr_data(accel_dev)) {
121 dev_err(&GET_DEV(accel_dev), "Failed initialize etr\n");
122 return -EFAULT;
123 }
124
125 if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) {
126 dev_err(&GET_DEV(accel_dev), "Failed initialize admin comms\n");
127 return -EFAULT;
128 }
129
130 if (hw_data->init_arb && hw_data->init_arb(accel_dev)) {
131 dev_err(&GET_DEV(accel_dev), "Failed initialize hw arbiter\n");
132 return -EFAULT;
133 }
134
135 hw_data->enable_ints(accel_dev);
136
137 if (adf_ae_init(accel_dev)) {
138 dev_err(&GET_DEV(accel_dev),
139 "Failed to initialise Acceleration Engine\n");
140 return -EFAULT;
141 }
142 set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
143
144 if (adf_ae_fw_load(accel_dev)) {
145 dev_err(&GET_DEV(accel_dev),
146 "Failed to load acceleration FW\n");
147 return -EFAULT;
148 }
149 set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
150
151 if (hw_data->alloc_irq(accel_dev)) {
152 dev_err(&GET_DEV(accel_dev), "Failed to allocate interrupts\n");
153 return -EFAULT;
154 }
155 set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
156
157
158
159
160
161
162 list_for_each(list_itr, &service_table) {
163 service = list_entry(list_itr, struct service_hndl, list);
164 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
165 dev_err(&GET_DEV(accel_dev),
166 "Failed to initialise service %s\n",
167 service->name);
168 return -EFAULT;
169 }
170 set_bit(accel_dev->accel_id, service->init_status);
171 }
172
173 hw_data->enable_error_correction(accel_dev);
174 hw_data->enable_vf2pf_comms(accel_dev);
175
176 return 0;
177}
178EXPORT_SYMBOL_GPL(adf_dev_init);
179
180
181
182
183
184
185
186
187
188
189
190int adf_dev_start(struct adf_accel_dev *accel_dev)
191{
192 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
193 struct service_hndl *service;
194 struct list_head *list_itr;
195
196 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
197
198 if (adf_ae_start(accel_dev)) {
199 dev_err(&GET_DEV(accel_dev), "AE Start Failed\n");
200 return -EFAULT;
201 }
202 set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
203
204 if (hw_data->send_admin_init(accel_dev)) {
205 dev_err(&GET_DEV(accel_dev), "Failed to send init message\n");
206 return -EFAULT;
207 }
208
209 list_for_each(list_itr, &service_table) {
210 service = list_entry(list_itr, struct service_hndl, list);
211 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
212 dev_err(&GET_DEV(accel_dev),
213 "Failed to start service %s\n",
214 service->name);
215 return -EFAULT;
216 }
217 set_bit(accel_dev->accel_id, service->start_status);
218 }
219
220 clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
221 set_bit(ADF_STATUS_STARTED, &accel_dev->status);
222
223 if (!list_empty(&accel_dev->crypto_list) &&
224 (qat_algs_register() || qat_asym_algs_register())) {
225 dev_err(&GET_DEV(accel_dev),
226 "Failed to register crypto algs\n");
227 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
228 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
229 return -EFAULT;
230 }
231 return 0;
232}
233EXPORT_SYMBOL_GPL(adf_dev_start);
234
235
236
237
238
239
240
241
242
243
244
245void adf_dev_stop(struct adf_accel_dev *accel_dev)
246{
247 struct service_hndl *service;
248 struct list_head *list_itr;
249 bool wait = false;
250 int ret;
251
252 if (!adf_dev_started(accel_dev) &&
253 !test_bit(ADF_STATUS_STARTING, &accel_dev->status))
254 return;
255
256 clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
257 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
258
259 if (!list_empty(&accel_dev->crypto_list)) {
260 qat_algs_unregister();
261 qat_asym_algs_unregister();
262 }
263
264 list_for_each(list_itr, &service_table) {
265 service = list_entry(list_itr, struct service_hndl, list);
266 if (!test_bit(accel_dev->accel_id, service->start_status))
267 continue;
268 ret = service->event_hld(accel_dev, ADF_EVENT_STOP);
269 if (!ret) {
270 clear_bit(accel_dev->accel_id, service->start_status);
271 } else if (ret == -EAGAIN) {
272 wait = true;
273 clear_bit(accel_dev->accel_id, service->start_status);
274 }
275 }
276
277 if (wait)
278 msleep(100);
279
280 if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) {
281 if (adf_ae_stop(accel_dev))
282 dev_err(&GET_DEV(accel_dev), "failed to stop AE\n");
283 else
284 clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
285 }
286}
287EXPORT_SYMBOL_GPL(adf_dev_stop);
288
289
290
291
292
293
294
295
296void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
297{
298 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
299 struct service_hndl *service;
300 struct list_head *list_itr;
301
302 if (!hw_data) {
303 dev_err(&GET_DEV(accel_dev),
304 "QAT: Failed to shutdown device - hw_data not set\n");
305 return;
306 }
307
308 if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
309 adf_ae_fw_release(accel_dev);
310 clear_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
311 }
312
313 if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
314 if (adf_ae_shutdown(accel_dev))
315 dev_err(&GET_DEV(accel_dev),
316 "Failed to shutdown Accel Engine\n");
317 else
318 clear_bit(ADF_STATUS_AE_INITIALISED,
319 &accel_dev->status);
320 }
321
322 list_for_each(list_itr, &service_table) {
323 service = list_entry(list_itr, struct service_hndl, list);
324 if (!test_bit(accel_dev->accel_id, service->init_status))
325 continue;
326 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
327 dev_err(&GET_DEV(accel_dev),
328 "Failed to shutdown service %s\n",
329 service->name);
330 else
331 clear_bit(accel_dev->accel_id, service->init_status);
332 }
333
334 hw_data->disable_iov(accel_dev);
335
336 if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
337 hw_data->free_irq(accel_dev);
338 clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
339 }
340
341
342 if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
343 adf_cfg_del_all(accel_dev);
344
345 if (hw_data->exit_arb)
346 hw_data->exit_arb(accel_dev);
347
348 if (hw_data->exit_admin_comms)
349 hw_data->exit_admin_comms(accel_dev);
350
351 adf_cleanup_etr_data(accel_dev);
352 adf_dev_restore(accel_dev);
353}
354EXPORT_SYMBOL_GPL(adf_dev_shutdown);
355
356int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
357{
358 struct service_hndl *service;
359 struct list_head *list_itr;
360
361 list_for_each(list_itr, &service_table) {
362 service = list_entry(list_itr, struct service_hndl, list);
363 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
364 dev_err(&GET_DEV(accel_dev),
365 "Failed to restart service %s.\n",
366 service->name);
367 }
368 return 0;
369}
370
371int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
372{
373 struct service_hndl *service;
374 struct list_head *list_itr;
375
376 list_for_each(list_itr, &service_table) {
377 service = list_entry(list_itr, struct service_hndl, list);
378 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
379 dev_err(&GET_DEV(accel_dev),
380 "Failed to restart service %s.\n",
381 service->name);
382 }
383 return 0;
384}
385