4dfbc84c8c639c2f29957617396dcd7efd9192cd
[dpdk.git] / drivers / crypto / qat / qat_device.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #include "qat_device.h"
6 #include "adf_transport_access_macros.h"
7 #include "qat_qp.h"
8
9 /* Hardware device information per generation */
10 __extension__
11 struct qat_gen_hw_data qp_gen_config[] =  {
12         [QAT_GEN1] = {
13                 .dev_gen = QAT_GEN1,
14                 .qp_hw_data = qat_gen1_qps,
15         },
16         [QAT_GEN2] = {
17                 .dev_gen = QAT_GEN2,
18                 .qp_hw_data = qat_gen1_qps,
19                 /* gen2 has same ring layout as gen1 */
20         },
21 };
22
23
24 static struct qat_pci_device qat_pci_devices[QAT_MAX_PCI_DEVICES];
25 static int qat_nb_pci_devices;
26
27 int qat_dev_config(__rte_unused struct rte_cryptodev *dev,
28                 __rte_unused struct rte_cryptodev_config *config)
29 {
30         PMD_INIT_FUNC_TRACE();
31         return 0;
32 }
33
34 int qat_dev_start(__rte_unused struct rte_cryptodev *dev)
35 {
36         PMD_INIT_FUNC_TRACE();
37         return 0;
38 }
39
40 void qat_dev_stop(__rte_unused struct rte_cryptodev *dev)
41 {
42         PMD_INIT_FUNC_TRACE();
43 }
44
45 int qat_dev_close(struct rte_cryptodev *dev)
46 {
47         int i, ret;
48
49         PMD_INIT_FUNC_TRACE();
50
51         for (i = 0; i < dev->data->nb_queue_pairs; i++) {
52                 ret = qat_sym_qp_release(dev, i);
53                 if (ret < 0)
54                         return ret;
55         }
56
57         return 0;
58 }
59
60 void qat_sym_dev_info_get(struct rte_cryptodev *dev,
61                         struct rte_cryptodev_info *info)
62 {
63         struct qat_sym_dev_private *internals = dev->data->dev_private;
64         const struct qat_qp_hw_data *sym_hw_qps =
65                 qp_gen_config[internals->qat_dev->qat_dev_gen]
66                               .qp_hw_data[QAT_SERVICE_SYMMETRIC];
67
68         PMD_INIT_FUNC_TRACE();
69         if (info != NULL) {
70                 info->max_nb_queue_pairs =
71                         qat_qps_per_service(sym_hw_qps, QAT_SERVICE_SYMMETRIC);
72                 info->feature_flags = dev->feature_flags;
73                 info->capabilities = internals->qat_dev_capabilities;
74                 info->sym.max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS;
75                 info->driver_id = cryptodev_qat_driver_id;
76                 info->pci_dev = RTE_DEV_TO_PCI(dev->device);
77         }
78 }
79
80
81 static struct qat_pci_device *
82 qat_pci_get_dev(uint8_t dev_id)
83 {
84         return &qat_pci_devices[dev_id];
85 }
86
87 static struct qat_pci_device *
88 qat_pci_get_named_dev(const char *name)
89 {
90         struct qat_pci_device *dev;
91         unsigned int i;
92
93         if (name == NULL)
94                 return NULL;
95
96         for (i = 0; i < QAT_MAX_PCI_DEVICES; i++) {
97                 dev = &qat_pci_devices[i];
98
99                 if ((dev->attached == QAT_ATTACHED) &&
100                                 (strcmp(dev->name, name) == 0))
101                         return dev;
102         }
103
104         return NULL;
105 }
106
107 static uint8_t
108 qat_pci_find_free_device_index(void)
109 {
110         uint8_t dev_id;
111
112         for (dev_id = 0; dev_id < QAT_MAX_PCI_DEVICES; dev_id++) {
113                 if (qat_pci_devices[dev_id].attached == QAT_DETACHED)
114                         break;
115         }
116         return dev_id;
117 }
118
119 struct qat_pci_device *
120 qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev)
121 {
122         char name[QAT_DEV_NAME_MAX_LEN];
123
124         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
125
126         return qat_pci_get_named_dev(name);
127 }
128
129 struct qat_pci_device *
130 qat_pci_device_allocate(struct rte_pci_device *pci_dev)
131 {
132         struct qat_pci_device *qat_dev;
133         uint8_t qat_dev_id;
134         char name[QAT_DEV_NAME_MAX_LEN];
135
136         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
137         snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
138         if (qat_pci_get_named_dev(name) != NULL) {
139                 PMD_DRV_LOG(ERR, "QAT device with name %s already allocated!",
140                                 name);
141                 return NULL;
142         }
143
144         qat_dev_id = qat_pci_find_free_device_index();
145         if (qat_dev_id == QAT_MAX_PCI_DEVICES) {
146                 PMD_DRV_LOG(ERR, "Reached maximum number of QAT devices");
147                 return NULL;
148         }
149
150         qat_dev = qat_pci_get_dev(qat_dev_id);
151         memset(qat_dev, 0, sizeof(*qat_dev));
152         snprintf(qat_dev->name, QAT_DEV_NAME_MAX_LEN, "%s", name);
153         qat_dev->qat_dev_id = qat_dev_id;
154         qat_dev->pci_dev = pci_dev;
155         switch (qat_dev->pci_dev->id.device_id) {
156         case 0x0443:
157                 qat_dev->qat_dev_gen = QAT_GEN1;
158                 break;
159         case 0x37c9:
160         case 0x19e3:
161         case 0x6f55:
162                 qat_dev->qat_dev_gen = QAT_GEN2;
163                 break;
164         default:
165                 PMD_DRV_LOG(ERR, "Invalid dev_id, can't determine generation");
166                 return NULL;
167         }
168
169         rte_spinlock_init(&qat_dev->arb_csr_lock);
170
171         qat_dev->attached = QAT_ATTACHED;
172
173         qat_nb_pci_devices++;
174
175         PMD_DRV_LOG(DEBUG, "QAT device %d allocated, name %s, total QATs %d",
176                         qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
177
178         return qat_dev;
179 }
180
181 int
182 qat_pci_device_release(struct rte_pci_device *pci_dev)
183 {
184         struct qat_pci_device *qat_dev;
185         char name[QAT_DEV_NAME_MAX_LEN];
186
187         if (pci_dev == NULL)
188                 return -EINVAL;
189
190         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
191         snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
192         qat_dev = qat_pci_get_named_dev(name);
193         if (qat_dev != NULL) {
194
195                 /* Check that there are no service devs still on pci device */
196                 if (qat_dev->sym_dev != NULL)
197                         return -EBUSY;
198
199                 qat_dev->attached = QAT_DETACHED;
200                 qat_nb_pci_devices--;
201         }
202         PMD_DRV_LOG(DEBUG, "QAT device %s released, total QATs %d",
203                                 name, qat_nb_pci_devices);
204         return 0;
205 }