1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 HUAWEI TECHNOLOGIES CO., LTD.
5 #include <rte_bus_pci.h>
6 #include <rte_cryptodev.h>
7 #include <rte_cryptodev_pmd.h>
10 #include "virtio_cryptodev.h"
11 #include "virtqueue.h"
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;
20 * The set of PCI devices this driver supports
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 */ },
28 uint8_t cryptodev_virtio_driver_id;
31 * dev_ops for virtio, bare necessities for basic operation
33 static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
34 /* Device related operations */
35 .dev_configure = NULL,
39 .dev_infos_get = NULL,
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,
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
59 virtio_negotiate_features(struct virtio_crypto_hw *hw, uint64_t req_features)
61 uint64_t host_features;
63 PMD_INIT_FUNC_TRACE();
65 /* Prepare guest_features: feature that driver wants to support */
66 VIRTIO_CRYPTO_INIT_LOG_DBG("guest_features before negotiate = %" PRIx64,
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,
75 * Negotiate features: Subset of device feature bits are written back
78 hw->guest_features = req_features;
79 hw->guest_features = vtpci_cryptodev_negotiate_features(hw,
81 VIRTIO_CRYPTO_INIT_LOG_DBG("features after negotiate = %" PRIx64,
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.");
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 "
100 hw->req_guest_features = req_features;
105 /* reset device and renegotiate features if needed */
107 virtio_crypto_init_device(struct rte_cryptodev *cryptodev,
108 uint64_t req_features)
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;
114 PMD_INIT_FUNC_TRACE();
116 /* Reset the device although not necessary at startup */
117 vtpci_cryptodev_reset(hw);
119 /* Tell the host we've noticed this device. */
120 vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
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)
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 "
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;
144 VIRTIO_CRYPTO_INIT_LOG_DBG("hw->max_dataqueues=%d",
151 * This function is based on probe() function
152 * It returns 0 on success.
155 crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev,
156 struct rte_cryptodev_pmd_init_params *init_params)
158 struct rte_cryptodev *cryptodev;
159 struct virtio_crypto_hw *hw;
161 PMD_INIT_FUNC_TRACE();
163 cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device,
165 if (cryptodev == NULL)
168 cryptodev->driver_id = cryptodev_virtio_driver_id;
169 cryptodev->dev_ops = &virtio_crypto_dev_ops;
171 cryptodev->enqueue_burst = virtio_crypto_pkt_tx_burst;
172 cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst;
174 cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
175 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
177 hw = cryptodev->data->dev_private;
178 hw->dev_id = cryptodev->data->dev_id;
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);
184 /* pci device init */
185 if (vtpci_cryptodev_init(pci_dev, hw))
188 if (virtio_crypto_init_device(cryptodev,
189 VIRTIO_CRYPTO_PMD_GUEST_FEATURES) < 0)
196 crypto_virtio_pci_probe(
197 struct rte_pci_driver *pci_drv __rte_unused,
198 struct rte_pci_device *pci_dev)
200 struct rte_cryptodev_pmd_init_params init_params = {
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
206 char name[RTE_CRYPTODEV_NAME_MAX_LEN];
208 VIRTIO_CRYPTO_DRV_LOG_DBG("Found Crypto device at %02x:%02x.%x",
211 pci_dev->addr.function);
213 rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
215 return crypto_virtio_create(name, pci_dev, &init_params);
219 crypto_virtio_pci_remove(
220 struct rte_pci_device *pci_dev __rte_unused)
222 struct rte_cryptodev *cryptodev;
223 char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
228 rte_pci_device_name(&pci_dev->addr, cryptodev_name,
229 sizeof(cryptodev_name));
231 cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
232 if (cryptodev == NULL)
238 static struct rte_pci_driver rte_virtio_crypto_driver = {
239 .id_table = pci_id_virtio_crypto_map,
241 .probe = crypto_virtio_pci_probe,
242 .remove = crypto_virtio_pci_remove
245 static struct cryptodev_driver virtio_crypto_drv;
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);
252 RTE_INIT(virtio_crypto_init_log);
254 virtio_crypto_init_log(void)
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);
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,
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);
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);
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);