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