xref: /dpdk/drivers/crypto/virtio/virtio_cryptodev.c (revision 25500d4b8076e9b84c0d69108c64418470d1f65c)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 HUAWEI TECHNOLOGIES CO., LTD.
3  */
4 #include <rte_pci.h>
5 #include <rte_bus_pci.h>
6 #include <rte_cryptodev.h>
7 #include <rte_cryptodev_pmd.h>
8 #include <rte_eal.h>
9 
10 #include "virtio_cryptodev.h"
11 #include "virtqueue.h"
12 
13 int virtio_crypto_logtype_init;
14 int virtio_crypto_logtype_session;
15 int virtio_crypto_logtype_rx;
16 int virtio_crypto_logtype_tx;
17 int virtio_crypto_logtype_driver;
18 
19 /*
20  * The set of PCI devices this driver supports
21  */
22 static const struct rte_pci_id pci_id_virtio_crypto_map[] = {
23 	{ RTE_PCI_DEVICE(VIRTIO_CRYPTO_PCI_VENDORID,
24 				VIRTIO_CRYPTO_PCI_DEVICEID) },
25 	{ .vendor_id = 0, /* sentinel */ },
26 };
27 
28 uint8_t cryptodev_virtio_driver_id;
29 
30 /*
31  * dev_ops for virtio, bare necessities for basic operation
32  */
33 static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
34 	/* Device related operations */
35 	.dev_configure			 = NULL,
36 	.dev_start			 = NULL,
37 	.dev_stop			 = NULL,
38 	.dev_close			 = NULL,
39 	.dev_infos_get			 = NULL,
40 
41 	.stats_get			 = NULL,
42 	.stats_reset			 = NULL,
43 
44 	.queue_pair_setup                = NULL,
45 	.queue_pair_release              = NULL,
46 	.queue_pair_start                = NULL,
47 	.queue_pair_stop                 = NULL,
48 	.queue_pair_count                = NULL,
49 
50 	/* Crypto related operations */
51 	.session_get_size	= NULL,
52 	.session_configure	= NULL,
53 	.session_clear		= NULL,
54 	.qp_attach_session = NULL,
55 	.qp_detach_session = NULL
56 };
57 
58 static int
59 virtio_negotiate_features(struct virtio_crypto_hw *hw, uint64_t req_features)
60 {
61 	uint64_t host_features;
62 
63 	PMD_INIT_FUNC_TRACE();
64 
65 	/* Prepare guest_features: feature that driver wants to support */
66 	VIRTIO_CRYPTO_INIT_LOG_DBG("guest_features before negotiate = %" PRIx64,
67 		req_features);
68 
69 	/* Read device(host) feature bits */
70 	host_features = VTPCI_OPS(hw)->get_features(hw);
71 	VIRTIO_CRYPTO_INIT_LOG_DBG("host_features before negotiate = %" PRIx64,
72 		host_features);
73 
74 	/*
75 	 * Negotiate features: Subset of device feature bits are written back
76 	 * guest feature bits.
77 	 */
78 	hw->guest_features = req_features;
79 	hw->guest_features = vtpci_cryptodev_negotiate_features(hw,
80 							host_features);
81 	VIRTIO_CRYPTO_INIT_LOG_DBG("features after negotiate = %" PRIx64,
82 		hw->guest_features);
83 
84 	if (hw->modern) {
85 		if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
86 			VIRTIO_CRYPTO_INIT_LOG_ERR(
87 				"VIRTIO_F_VERSION_1 features is not enabled.");
88 			return -1;
89 		}
90 		vtpci_cryptodev_set_status(hw,
91 			VIRTIO_CONFIG_STATUS_FEATURES_OK);
92 		if (!(vtpci_cryptodev_get_status(hw) &
93 			VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
94 			VIRTIO_CRYPTO_INIT_LOG_ERR("failed to set FEATURES_OK "
95 						"status!");
96 			return -1;
97 		}
98 	}
99 
100 	hw->req_guest_features = req_features;
101 
102 	return 0;
103 }
104 
105 /* reset device and renegotiate features if needed */
106 static int
107 virtio_crypto_init_device(struct rte_cryptodev *cryptodev,
108 	uint64_t req_features)
109 {
110 	struct virtio_crypto_hw *hw = cryptodev->data->dev_private;
111 	struct virtio_crypto_config local_config;
112 	struct virtio_crypto_config *config = &local_config;
113 
114 	PMD_INIT_FUNC_TRACE();
115 
116 	/* Reset the device although not necessary at startup */
117 	vtpci_cryptodev_reset(hw);
118 
119 	/* Tell the host we've noticed this device. */
120 	vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
121 
122 	/* Tell the host we've known how to drive the device. */
123 	vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
124 	if (virtio_negotiate_features(hw, req_features) < 0)
125 		return -1;
126 
127 	/* Get status of the device */
128 	vtpci_read_cryptodev_config(hw,
129 		offsetof(struct virtio_crypto_config, status),
130 		&config->status, sizeof(config->status));
131 	if (config->status != VIRTIO_CRYPTO_S_HW_READY) {
132 		VIRTIO_CRYPTO_DRV_LOG_ERR("accelerator hardware is "
133 				"not ready");
134 		return -1;
135 	}
136 
137 	/* Get number of data queues */
138 	vtpci_read_cryptodev_config(hw,
139 		offsetof(struct virtio_crypto_config, max_dataqueues),
140 		&config->max_dataqueues,
141 		sizeof(config->max_dataqueues));
142 	hw->max_dataqueues = config->max_dataqueues;
143 
144 	VIRTIO_CRYPTO_INIT_LOG_DBG("hw->max_dataqueues=%d",
145 		hw->max_dataqueues);
146 
147 	return 0;
148 }
149 
150 /*
151  * This function is based on probe() function
152  * It returns 0 on success.
153  */
154 static int
155 crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev,
156 		struct rte_cryptodev_pmd_init_params *init_params)
157 {
158 	struct rte_cryptodev *cryptodev;
159 	struct virtio_crypto_hw *hw;
160 
161 	PMD_INIT_FUNC_TRACE();
162 
163 	cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device,
164 					init_params);
165 	if (cryptodev == NULL)
166 		return -ENODEV;
167 
168 	cryptodev->driver_id = cryptodev_virtio_driver_id;
169 	cryptodev->dev_ops = &virtio_crypto_dev_ops;
170 
171 	cryptodev->enqueue_burst = virtio_crypto_pkt_tx_burst;
172 	cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst;
173 
174 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
175 		RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
176 
177 	hw = cryptodev->data->dev_private;
178 	hw->dev_id = cryptodev->data->dev_id;
179 
180 	VIRTIO_CRYPTO_INIT_LOG_DBG("dev %d vendorID=0x%x deviceID=0x%x",
181 		cryptodev->data->dev_id, pci_dev->id.vendor_id,
182 		pci_dev->id.device_id);
183 
184 	/* pci device init */
185 	if (vtpci_cryptodev_init(pci_dev, hw))
186 		return -1;
187 
188 	if (virtio_crypto_init_device(cryptodev,
189 			VIRTIO_CRYPTO_PMD_GUEST_FEATURES) < 0)
190 		return -1;
191 
192 	return 0;
193 }
194 
195 static int
196 crypto_virtio_pci_probe(
197 	struct rte_pci_driver *pci_drv __rte_unused,
198 	struct rte_pci_device *pci_dev)
199 {
200 	struct rte_cryptodev_pmd_init_params init_params = {
201 		.name = "",
202 		.socket_id = rte_socket_id(),
203 		.private_data_size = sizeof(struct virtio_crypto_hw),
204 		.max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS
205 	};
206 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
207 
208 	VIRTIO_CRYPTO_DRV_LOG_DBG("Found Crypto device at %02x:%02x.%x",
209 			pci_dev->addr.bus,
210 			pci_dev->addr.devid,
211 			pci_dev->addr.function);
212 
213 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
214 
215 	return crypto_virtio_create(name, pci_dev, &init_params);
216 }
217 
218 static int
219 crypto_virtio_pci_remove(
220 	struct rte_pci_device *pci_dev __rte_unused)
221 {
222 	struct rte_cryptodev *cryptodev;
223 	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
224 
225 	if (pci_dev == NULL)
226 		return -EINVAL;
227 
228 	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
229 			sizeof(cryptodev_name));
230 
231 	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
232 	if (cryptodev == NULL)
233 		return -ENODEV;
234 
235 	return 0;
236 }
237 
238 static struct rte_pci_driver rte_virtio_crypto_driver = {
239 	.id_table = pci_id_virtio_crypto_map,
240 	.drv_flags = 0,
241 	.probe = crypto_virtio_pci_probe,
242 	.remove = crypto_virtio_pci_remove
243 };
244 
245 static struct cryptodev_driver virtio_crypto_drv;
246 
247 RTE_PMD_REGISTER_PCI(CRYPTODEV_NAME_VIRTIO_PMD, rte_virtio_crypto_driver);
248 RTE_PMD_REGISTER_CRYPTO_DRIVER(virtio_crypto_drv,
249 	rte_virtio_crypto_driver.driver,
250 	cryptodev_virtio_driver_id);
251 
252 RTE_INIT(virtio_crypto_init_log);
253 static void
254 virtio_crypto_init_log(void)
255 {
256 	virtio_crypto_logtype_init = rte_log_register("pmd.crypto.virtio.init");
257 	if (virtio_crypto_logtype_init >= 0)
258 		rte_log_set_level(virtio_crypto_logtype_init, RTE_LOG_NOTICE);
259 
260 	virtio_crypto_logtype_session =
261 		rte_log_register("pmd.crypto.virtio.session");
262 	if (virtio_crypto_logtype_session >= 0)
263 		rte_log_set_level(virtio_crypto_logtype_session,
264 				RTE_LOG_NOTICE);
265 
266 	virtio_crypto_logtype_rx = rte_log_register("pmd.crypto.virtio.rx");
267 	if (virtio_crypto_logtype_rx >= 0)
268 		rte_log_set_level(virtio_crypto_logtype_rx, RTE_LOG_NOTICE);
269 
270 	virtio_crypto_logtype_tx = rte_log_register("pmd.crypto.virtio.tx");
271 	if (virtio_crypto_logtype_tx >= 0)
272 		rte_log_set_level(virtio_crypto_logtype_tx, RTE_LOG_NOTICE);
273 
274 	virtio_crypto_logtype_driver =
275 		rte_log_register("pmd.crypto.virtio.driver");
276 	if (virtio_crypto_logtype_driver >= 0)
277 		rte_log_set_level(virtio_crypto_logtype_driver, RTE_LOG_NOTICE);
278 }
279