26 #include "spdk/nvmf_transport.h"
27 #include "spdk/util.h"
28 #include "spdk/thread.h"
29 #include <spdk/nvme_spec.h>
44 #define HOTPLUG_TIMEOUT_IN_MICROS (5 * 1000 * 1000)
46 #define NVMF_DOCA_DEFAULT_MAX_QUEUE_DEPTH 512
47 #define NVMF_DOCA_DEFAULT_MAX_QPAIRS_PER_CTRLR 128
48 #define NVMF_DOCA_DEFAULT_IN_CAPSULE_DATA_SIZE 4096
49 #define NVMF_DOCA_DEFAULT_MAX_IO_SIZE 131072
50 #define NVMF_DOCA_DEFAULT_IO_UINT_SIZE 128
51 #define NVMF_DOCA_DEFAULT_AQ_DEPTH 256
52 #define NVMF_DOCA_DEFAULT_NUM_SHARED_BUFFER 1
53 #define NVMF_DOCA_DEFAULT_BUFFER_CACHE_SIZE 0
54 #define NVMF_DOCA_DIF_INSERT_OR_STRIP false
55 #define NVMF_DOCA_DEFAULT_ABORT_TIMEOUT_SEC 1
57 #define NVMF_ADMIN_QUEUE_ID 0
58 #define ADMIN_QP_POLL_RATE_LIMIT 1000
63 #ifndef TAILQ_FOREACH_SAFE
64 #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
65 for ((var) = ((head)->tqh_first); (var) && ((tvar) = ((var)->field.tqe_next), 1); (var) = (tvar))
76 union spdk_nvme_cap_register
cap;
79 union spdk_nvme_vs_register
vs;
84 union spdk_nvme_cc_register
cc;
87 union spdk_nvme_csts_register
csts;
91 union spdk_nvme_aqa_register
aqa;
117 bool stopping_all_io_cqs;
132 struct spdk_nvmf_transport_poll_group
pg;
148 struct spdk_nvme_transport_id
trid;
173 uint32_t num_of_listeners;
177 #define NVME_PAGE_SIZE 4096
183 struct doca_buf *dst,
184 struct doca_buf *
src,
189 struct doca_buf *dst,
190 struct doca_buf *
src,
200 struct doca_dev *emulation_manager,
201 struct doca_mmap **mmap_out);
218 opts->transport_specific =
NULL;
233 if (transport->last_selected_pg ==
NULL) {
234 transport->last_selected_pg = TAILQ_FIRST(&transport->poll_groups);
236 transport->last_selected_pg = TAILQ_NEXT(transport->last_selected_pg, link);
239 if (transport->last_selected_pg ==
NULL) {
240 transport->last_selected_pg = TAILQ_FIRST(&transport->poll_groups);
243 poll_group = transport->last_selected_pg;
255 struct doca_devemu_pci_dev *pci_dev)
261 TAILQ_FOREACH(pci_dev_pg, &doca_poll_group->pci_dev_pg_list, link)
281 if (doca_emulation_manager->
dpa !=
NULL) {
296 free(doca_emulation_manager);
325 goto destroy_pci_type;
331 goto destroy_pci_type;
337 goto destroy_pci_type;
343 goto destroy_pci_type;
350 goto destroy_pci_type;
356 goto destroy_pci_type;
362 goto destroy_pci_type;
368 goto destroy_pci_type;
380 goto destroy_pci_type;
403 goto destroy_pci_type;
412 region_config->
size);
415 goto destroy_pci_type;
424 region_config->
size);
426 DOCA_LOG_ERR(
"Unable to set MSI-X pending bit array region at index %d: %s",
429 goto destroy_pci_type;
438 region_config->
size);
441 goto destroy_pci_type;
448 goto destroy_pci_type;
451 uint8_t data[128] = {};
500 doca_emulation_manager =
502 if (doca_emulation_manager ==
NULL) {
503 DOCA_LOG_INFO(
"Failed to allocate memory for emultaion manager context");
542 *ret_emulation_manager = doca_emulation_manager;
556 spdk_poller_unregister(&admin_pg->
poller);
584 TAILQ_INIT(&admin_pg->pci_dev_admins);
586 admin_pg->
thread = spdk_get_thread();
587 assert(admin_pg->
thread == spdk_thread_get_app_thread());
607 struct doca_devinfo **dev_list;
609 uint8_t is_hotplug_manager;
614 if (doca_transport ==
NULL) {
615 DOCA_LOG_INFO(
"Failed to allocate memory for doca_transport");
619 TAILQ_INIT(&doca_transport->poll_groups);
620 TAILQ_INIT(&doca_transport->emulation_managers);
621 doca_transport->last_selected_pg =
NULL;
629 for (uint32_t idx = 0; idx < nb_devs; idx++) {
638 TAILQ_INSERT_TAIL(&doca_transport->emulation_managers, doca_emulation_manager, link);
644 if (TAILQ_EMPTY(&doca_transport->emulation_managers)) {
661 doca_transport->num_of_listeners = 0;
671 free(doca_transport);
701 spdk_nvmf_transport_destroy_done_cb cb_fn,
713 TAILQ_FOREACH_SAFE(doca_emulation_manager, &doca_transport->emulation_managers, link, temp)
715 TAILQ_REMOVE(&doca_transport->emulation_managers, doca_emulation_manager, link);
719 free(doca_transport);
732 TAILQ_FOREACH(pci_dev_admin, &
doca_transport->admin_pg.pci_dev_admins, link)
735 return pci_dev_admin;
770 struct doca_dev_rep **ret_device_rep)
775 struct doca_devinfo_rep **devinfo_list_rep;
777 struct doca_dev_rep *device_rep;
778 uint32_t nb_devs_rep;
781 TAILQ_FOREACH(doca_emulation_manager, &doca_transport->emulation_managers, link)
791 for (uint32_t idx = 0; idx < nb_devs_rep; idx++) {
800 *ret_device_rep = device_rep;
801 *ret_emulation_manager = doca_emulation_manager;
808 DOCA_LOG_ERR(
"Could not find an emulation manager and a fuction with the requested VUID");
829 DOCA_LOG_INFO(
"Destroying poll group %p PCI dev poll group %p", doca_poll_group, pci_dev_pg);
830 TAILQ_REMOVE(&doca_poll_group->pci_dev_pg_list, pci_dev_pg, link);
845 struct doca_ctx *
ctx,
856 switch (next_state) {
872 DOCA_LOG_DBG(
"Devemu device has entered into stopping state. Unexpected!, destroy datapath resources!");
914 TAILQ_REMOVE(&admin_qp->io_sqs, sq, pci_dev_admin_link);
917 if (delete_io_sq_ctx ==
NULL) {
924 free(delete_io_sq_ctx);
926 request->request.rsp->nvme_cpl.cid =
request->request.cmd->nvme_cmd.cid;
940 struct spdk_thread *thread;
944 thread = sq->
io->
poll_group->poll_group->pg.group->thread;
984 TAILQ_REMOVE(&admin_qp->io_cqs, io, pci_dev_admin_link);
987 if (delete_io_cq_ctx ==
NULL) {
994 free(delete_io_cq_ctx);
996 request->request.rsp->nvme_cpl.cid =
request->request.cmd->nvme_cmd.cid;
1010 struct spdk_thread *thread;
1012 if (admin_qp->stopping_all_io_cqs)
1017 thread = io->
poll_group->poll_group->pg.group->thread;
1021 admin_qp->stopping_all_io_cqs =
true;
1028 if (pci_dev_pg !=
NULL) {
1031 DOCA_LOG_ERR(
"Failed to destroy PCI device poll group: Failed to destroy mmap - %s",
1036 DOCA_LOG_INFO(
"Destroyed PCI dev poll group %p", pci_dev_pg);
1037 memset(pci_dev_pg, 0,
sizeof(*pci_dev_pg));
1059 if (pci_dev_pg ==
NULL) {
1060 DOCA_LOG_ERR(
"Failed to allocate doca device poll group");
1064 pci_dev_pg->poll_group = doca_poll_group;
1067 TAILQ_INIT(&pci_dev_pg->io_cqs);
1077 *ret_pci_dev_pg = pci_dev_pg;
1106 if (!TAILQ_EMPTY(&admin_qp->io_cqs)) {
1110 admin_qp->stopping_all_io_cqs =
false;
1126 spdk_thread_exec_msg(pci_dev_admin->
doca_transport->admin_pg.thread,
1143 if (!TAILQ_EMPTY(&admin_qp->io_sqs)) {
1185 pci_dev_admin->
admin_qp = admin_qp;
1199 struct spdk_thread *admin_thread = pci_dev_admin->
doca_transport->admin_pg.thread;
1202 if (admin_qp ==
NULL) {
1203 DOCA_LOG_ERR(
"Failed to create admin QP: Out of memory");
1207 TAILQ_INIT(&admin_qp->io_cqs);
1208 TAILQ_INIT(&admin_qp->io_sqs);
1216 TAILQ_INSERT_TAIL(&doca_poll_group->pci_dev_pg_list, pci_dev_pg, link);
1221 .nvme_dev = pci_dev_admin->
pci_dev,
1224 .cq_depth =
ctx->admin_cq_size,
1226 .host_cq_address =
ctx->admin_cq_address,
1227 .enable_msix =
true,
1237 struct nvmf_doca_io *emulated_cq = calloc(1,
sizeof(*emulated_cq));
1238 if (emulated_cq ==
NULL) {
1239 DOCA_LOG_ERR(
"Failed to create io: Failed to allocate IO struct");
1240 TAILQ_REMOVE(&doca_poll_group->pci_dev_pg_list, pci_dev_pg, link);
1249 TAILQ_REMOVE(&doca_poll_group->pci_dev_pg_list, pci_dev_pg, link);
1260 DOCA_LOG_ERR(
"Failed to create io: Failed to allocate SQ struct");
1263 TAILQ_REMOVE(&doca_poll_group->pci_dev_pg_list, pci_dev_pg, link);
1272 .nvme_dev = pci_dev_admin->
pci_dev,
1273 .sq_depth =
ctx->admin_sq_size,
1275 .host_sq_address =
ctx->admin_sq_address,
1277 .transport = doca_poll_group->
pg.transport,
1281 ctx->admin_qp_out = admin_qp;
1299 if (registers->
cc.bits.shn == SPDK_NVME_SHN_NORMAL || registers->
cc.bits.shn == SPDK_NVME_SHN_ABRUPT) {
1300 registers->
csts.bits.shst = SPDK_NVME_SHST_COMPLETE;
1302 if (registers->
cc.bits.en == 0) {
1303 registers->
csts.bits.rdy = 0;
1307 offsetof(
struct spdk_nvme_registers,
1313 "Failed to complete controller reset/shutdown: Failed to modify stateful region - %s",
1319 if (pci_dev_admin->
is_flr) {
1321 pci_dev_admin->
is_flr =
false;
1340 spdk_thread_exec_msg(pci_dev_admin->
admin_qp_pg->
pg.group->thread,
1363 pci_dev_admin->
is_flr =
true;
1383 DOCA_LOG_INFO(
"Emulated device's hotplug state has changed");
1470 DOCA_LOG_ERR(
"Failed to create admin QP: Out of memory");
1480 .admin_cq_address = registers->
acq,
1481 .admin_sq_address = registers->
asq,
1482 .admin_cq_size = registers->
aqa.bits.acqs + 1,
1483 .admin_sq_size = registers->
aqa.bits.asqs + 1,
1493 if (registers->
cc.bits.shn == SPDK_NVME_SHN_NORMAL || registers->
cc.bits.shn == SPDK_NVME_SHN_ABRUPT) {
1499 if (registers->
cc.bits.en == 0) {
1514 struct doca_devemu_pci_dev_event_bar_stateful_region_driver_write *event,
1519 struct doca_devemu_pci_dev *pci_dev =
1539 uint64_t region_idx;
1542 uint64_t max_region_size = 0;
1546 user_data.
ptr = (
void *)config;
1555 DOCA_LOG_ERR(
"Unable to register to emulated PCI device stateful region write event: %s",
1560 max_region_size = max_region_size > config->
size ? max_region_size : config->
size;
1563 user_data.
ptr = (
void *)pci_dev_admin;
1573 DOCA_LOG_ERR(
"Unable to allocate buffer for storing stateful region values: out of memory");
1594 user_data.
ptr = (
void *)pci_dev_admin;
1597 doca_emulation_manager->
dpa);
1633 DOCA_LOG_ERR(
"Unable to register to emulated PCI device stateful region write event: %s",
1655 struct doca_dev *emulation_manager,
1656 struct doca_mmap **mmap_out)
1660 struct doca_mmap *
mmap;
1734 DOCA_LOG_ERR(
"Failed to destroy PCI device context: Failed to close representor - %s",
1739 free(pci_dev_admin);
1743 const struct spdk_nvme_transport_id *trid,
1749 struct doca_dev_rep *dev_rep;
1754 (
char *)trid->traddr,
1755 &doca_emulation_manager,
1758 DOCA_LOG_ERR(
"Could not find an emulation manager and a function with the given address: %s",
1764 if (pci_dev_admin ==
NULL) {
1765 DOCA_LOG_ERR(
"Failed to allocate PCI device context's memory: errno %d", err);
1775 memcpy(&pci_dev_admin->
trid,
trid,
sizeof(pci_dev_admin->
trid));
1796 *pci_dev_admin_out = pci_dev_admin;
1798 return EXIT_SUCCESS;
1803 size_t timeout_in_micros)
1805 static const size_t sleep_in_micros = 10;
1806 static const size_t sleep_in_nanos = sleep_in_micros * 1000;
1808 struct timespec timespec = {
1810 .tv_nsec = sleep_in_nanos,
1815 size_t elapsed_time_in_micros = 0;
1817 if (elapsed_time_in_micros >= timeout_in_micros) {
1818 DOCA_LOG_ERR(
"Failed to wait for hotplug state to change: Timed out");
1822 nanosleep(×pec,
NULL);
1823 elapsed_time_in_micros += sleep_in_micros;
1826 DOCA_LOG_ERR(
"Failed to wait for hotplug state to change: Failed to get hotplug state %s",
1847 const struct spdk_nvme_transport_id *trid,
1848 struct spdk_nvmf_listen_opts *listen_opts)
1868 TAILQ_INSERT_TAIL(&
doca_transport->admin_pg.pci_dev_admins, pci_dev_admin, link);
1877 goto destroy_pci_dev_admin;
1879 DOCA_LOG_INFO(
"Hotplug initiated waiting for host to notice new device");
1885 DOCA_LOG_ERR(
"Failed to start listen: Could not transition device to POWER_ON state - %s",
1891 return EXIT_SUCCESS;
1895 destroy_pci_dev_admin:
1896 TAILQ_REMOVE(&
doca_transport->admin_pg.pci_dev_admins, pci_dev_admin, link);
1920 if (pci_dev_admin ==
NULL) {
1921 DOCA_LOG_ERR(
"Failed to stop listen: Could not find a PCI device (listener) with the requested VUID");
1928 DOCA_LOG_ERR(
"The QP and its resources must be freed before stopping the listeners %s", __func__);
1934 DOCA_LOG_INFO(
"Hotplug initiated waiting for host to notice new device");
1939 DOCA_LOG_ERR(
"Failed to stop listen: Could not transition device to POWER_OFF state - %s",
1946 TAILQ_REMOVE(&
doca_transport->admin_pg.pci_dev_admins, pci_dev_admin, link);
1961 const struct spdk_nvmf_subsystem *
subsystem,
1962 const struct spdk_nvme_transport_id *
trid)
1970 if (pci_dev_admin ==
NULL) {
1974 pci_dev_admin->
subsystem = (
struct spdk_nvmf_subsystem *)subsystem;
1976 return EXIT_SUCCESS;
1989 struct spdk_nvmf_poll_group *group)
2000 if (doca_pg ==
NULL) {
2001 DOCA_LOG_ERR(
"Failed to allocate memory for doca poll group");
2022 TAILQ_INIT(&doca_pg->pci_dev_pg_list);
2024 TAILQ_INSERT_TAIL(&doca_transport->poll_groups, doca_pg, link);
2026 return &doca_pg->
pg;
2048 TAILQ_REMOVE(&doca_transport->poll_groups, doca_pg, link);
2086 struct spdk_thread *admin_thread = pci_dev_admin->
doca_transport->admin_pg.thread;
2088 void *create_admin_qp_ctx = sq->
ctx;
2108 struct spdk_thread *admin_thread = pci_dev_admin->
doca_transport->admin_pg.thread;
2111 if (new_request ==
NULL) {
2118 new_request->
request.cmd->prop_set_cmd.opcode = SPDK_NVME_OPC_FABRIC;
2119 new_request->
request.cmd->prop_set_cmd.cid = 0;
2120 new_request->
request.cmd->prop_set_cmd.attrib.size = 0;
2121 new_request->
request.cmd->prop_set_cmd.ofst =
offsetof(
struct spdk_nvme_registers, cc);
2122 new_request->
request.cmd->prop_set_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_PROPERTY_SET;
2123 new_request->
request.length = 4;
2127 offsetof(
struct spdk_nvme_registers, cc),
2136 int temp_iovcnt = (int)new_request->
request.iovcnt;
2138 new_request->
request.cmd->prop_set_cmd.value.u32.low = registers->cc.raw;
2139 spdk_iov_one(new_request->
request.iov, &temp_iovcnt, ®isters->cc, new_request->
request.length);
2142 new_request->
cb_arg = doca_sq;
2144 spdk_nvmf_request_exec_fabrics(&new_request->
request);
2182 doca_request =
ctx->request;
2183 doca_request->
request.rsp->nvme_cpl.status.sc = SPDK_NVME_SC_SUCCESS;
2184 doca_request->
request.rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC;
2203 struct spdk_nvmf_fabric_connect_data *data;
2205 struct spdk_thread *admin_thread = pci_dev_admin->
doca_transport->admin_pg.thread;
2208 if (doca_request ==
NULL) {
2215 doca_request->
request.cmd->connect_cmd.opcode = SPDK_NVME_OPC_FABRIC;
2216 doca_request->
request.cmd->connect_cmd.cid = 0;
2217 doca_request->
request.cmd->connect_cmd.fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT;
2218 doca_request->
request.cmd->connect_cmd.recfmt = 0;
2220 doca_request->
request.cmd->connect_cmd.qid = sq->
sq_id;
2221 doca_request->
request.length =
sizeof(
struct spdk_nvmf_fabric_connect_data);
2223 data = calloc(1, doca_request->
request.length);
2232 if (pci_dev_admin->
ctlr_id == 0) {
2236 data->cntlid = pci_dev_admin->
ctlr_id;
2239 snprintf((
char *)data->subnqn,
2240 sizeof(data->subnqn),
2242 spdk_nvmf_subsystem_get_nqn(pci_dev_admin->
subsystem));
2245 doca_request->
cb_arg = sq;
2247 doca_request->
request.data = data;
2248 spdk_nvmf_request_exec_fabrics(&doca_request->
request);
2406 #define IDENTIFY_CMD_DATA_BUFFER_SIZE 4096
2407 #define FEAT_CMD_LBA_RANGE_SIZE 4096
2408 #define FEAT_CMD_AUTONOMOUS_POWER_STATE_TRANSITION_SIZE 256
2409 #define FEAT_CMD_TIMESTAMP_SIZE 8
2410 #define FEAT_CMD_HOST_BEHAVIOR_SUPPORT_SIZE 512
2411 #define FEAT_CMD_HOST_IDENTIFIER_EXT_SIZE 16
2412 #define FEAT_CMD_HOST_IDENTIFIER_SIZE 8
2425 void *data_out_address;
2428 uint32_t remaining_length;
2446 request->
request.iov[idx].iov_base = data_out_address;
2447 request->
request.iov[idx].iov_len = remaining_length;
2450 length -= remaining_length;
2455 if (request->
request.cmd->nvme_cmd.opc == SPDK_NVME_OPC_WRITE) {
2471 uint64_t prp1, prp2;
2472 uint32_t remaining_length, number_of_pages;
2476 prp1 = request->
request.cmd->nvme_cmd.dptr.prp.prp1;
2477 prp2 = request->
request.cmd->nvme_cmd.dptr.prp.prp2;
2481 remaining_length = spdk_min(
length, remaining_length);
2483 void *data_out_address;
2488 request->
request.iov[0].iov_base = data_out_address;
2489 request->
request.iov[0].iov_len = remaining_length;
2492 length -= remaining_length;
2498 if (request->
request.cmd->nvme_cmd.opc == SPDK_NVME_OPC_WRITE) {
2510 request->
request.iov[1].iov_base = data_out_address;
2515 if (request->
request.cmd->nvme_cmd.opc == SPDK_NVME_OPC_WRITE) {
2528 user_data.
ptr = request;
2536 number_of_pages *
sizeof(*prp_list),
2551 if (request->
request.cmd->nvme_cmd.psdt == SPDK_NVME_PSDT_PRP) {
2556 void *data_out_address;
2557 uintptr_t host_data_out_io_address = request->
request.cmd->nvme_cmd.dptr.prp.prp1;
2562 spdk_iov_one(request->
request.iov, (
int *)&request->
request.iovcnt, data_out_address, request->
request.length);
2563 request->
request.data = data_out_address;
2577 user_data.
ptr = request;
2594 request->
request.rsp->nvme_cpl.cid = request->
request.cmd->nvme_cmd.cid;
2595 request->
request.rsp->nvme_cpl.status.sc = 1;
2612 user_data.
ptr = request;
2615 if (request->
request.cmd->nvme_cmd.opc == SPDK_NVME_OPC_IDENTIFY) {
2616 struct spdk_nvme_ctrlr_data *cdata = (
struct spdk_nvme_ctrlr_data *)request->
request.data;
2619 cdata->sgls.supported = SPDK_NVME_SGLS_NOT_SUPPORTED;
2641 user_data.
ptr = request;
2650 request->
request.iov[idx].iov_len,
2669 spdk_nvmf_request_exec(&request->
request);
2696 spdk_nvmf_request_exec(&request->
request);
2710 spdk_nvmf_request_exec(&request->
request);
2726 user_data.
ptr = request;
2760 user_data.
ptr = request;
2769 request->
request.iov[idx].iov_len,
2782 spdk_nvmf_request_exec(&request->
request);
2806 if (request->
request.rsp->nvme_cpl.status.sc == 1) {
2809 TAILQ_INSERT_TAIL(&admin_qp->io_cqs,
ctx->io_cq, pci_dev_admin_link);
2814 request->
request.rsp->nvme_cpl.cid = request->
request.cmd->nvme_cmd.cid;
2828 TAILQ_FOREACH(io_sq, &admin_qp->io_sqs, pci_dev_admin_link)
2830 if (io_sq->
sq_id == io_sq_id) {
2861 TAILQ_FOREACH(io_cq, &admin_qp->io_cqs, pci_dev_admin_link)
2863 if (io_cq->
cq.
cq_id == io_cq_id) {
2880 TAILQ_REMOVE(&pci_dev_pg->io_cqs, io, pci_dev_pg_link);
2888 if (pci_dev_pg->
admin_qp ==
NULL && TAILQ_EMPTY(&pci_dev_pg->io_cqs)) {
2889 DOCA_LOG_INFO(
"Destroying PCI dev poll group %p", pci_dev_pg);
2890 TAILQ_REMOVE(&pci_dev_pg->poll_group->pci_dev_pg_list, pci_dev_pg, link);
2910 struct spdk_nvme_cmd *cmd = &request->
request.cmd->nvme_cmd;
2911 uint16_t qsize = cmd->cdw10_bits.create_io_q.qsize + 1;
2915 if (pci_dev_pg ==
NULL) {
2919 request->
request.rsp->nvme_cpl.status.sc = 1;
2920 goto respond_to_admin;
2922 TAILQ_INSERT_TAIL(&poll_group->pci_dev_pg_list, pci_dev_pg, link);
2926 .
pe = pci_dev_pg->poll_group->pe,
2928 .nvme_dev = pci_dev_admin->
pci_dev,
2930 .cq_id = cmd->cdw10_bits.create_io_q.qid,
2933 .host_cq_address = cmd->dptr.prp.prp1,
2934 .msix_idx = cmd->cdw11_bits.create_io_cq.iv,
2935 .enable_msix = cmd->cdw11_bits.create_io_cq.ien,
2948 request->
request.rsp->nvme_cpl.status.sc = 1;
2949 goto respond_to_admin;
2954 TAILQ_INSERT_TAIL(&pci_dev_pg->io_cqs, io_cq, pci_dev_pg_link);
2957 struct spdk_thread *admin_qp_thread = pci_dev_admin->
admin_qp_pg->
pg.group->thread;
2969 struct nvmf_doca_io *io_cq = calloc(1,
sizeof(*io_cq));
2970 if (io_cq ==
NULL) {
2979 if (create_io_cq_ctx ==
NULL) {
2992 struct spdk_thread *thread = poll_group->
pg.group->thread;
3006 uint32_t io_cq_id = request->
request.cmd->nvme_cmd.cdw10_bits.delete_io_q.qid;
3008 if (io_cq ==
NULL) {
3009 DOCA_LOG_ERR(
"Failed to delete IO CQ: IO CQ with ID %u does not exist", io_cq_id);
3015 if (delete_io_cq_ctx ==
NULL) {
3023 io_cq->
ctx = delete_io_cq_ctx;
3025 struct spdk_thread *thread = io_cq->
poll_group->poll_group->pg.group->thread;
3042 if (request->
request.rsp->nvme_cpl.status.sc == 1) {
3045 TAILQ_INSERT_TAIL(&admin_qp->io_sqs, io_sq, pci_dev_admin_link);
3050 request->
request.rsp->nvme_cpl.cid = request->
request.cmd->nvme_cmd.cid;
3063 struct spdk_nvme_cmd *cmd = &request->
request.cmd->nvme_cmd;
3066 uint32_t qsize = cmd->cdw10_bits.create_io_q.qsize + 1;
3069 .
pe = pci_dev_pg->poll_group->pe,
3071 .nvme_dev = pci_dev_admin->
pci_dev,
3074 .host_sq_address = cmd->dptr.prp.prp1,
3075 .sq_id = cmd->cdw10_bits.create_io_q.qid,
3076 .transport = pci_dev_pg->poll_group->pg.transport,
3091 uint32_t io_cq_id = request->
request.cmd->nvme_cmd.cdw10_bits.create_io_q.qid;
3093 if (io_cq ==
NULL) {
3094 DOCA_LOG_ERR(
"Failed to create IO SQ: IO CQ with ID %u not found", io_cq_id);
3100 struct spdk_thread *thread = pci_dev_pg->poll_group->pg.group->thread;
3101 struct nvmf_doca_sq *io_sq = calloc(1,
sizeof(*io_sq));
3102 if (io_sq ==
NULL) {
3109 if (create_io_sq_ctx ==
NULL) {
3134 uint32_t io_sq_id = request->
request.cmd->nvme_cmd.cdw10_bits.delete_io_q.qid;
3137 if (io_sq ==
NULL) {
3138 DOCA_LOG_ERR(
"Failed to delete IO SQ: IO SQ with ID %u does not exist", io_sq_id);
3144 if (delete_io_sq_ctx ==
NULL) {
3152 io_sq->
ctx = delete_io_sq_ctx;
3154 struct spdk_thread *thread = io_sq->
io->
poll_group->poll_group->pg.group->thread;
3168 struct spdk_nvme_cmd *cmd = (
struct spdk_nvme_cmd *)&sqe->
data[0];
3170 request->
request.cmd->nvme_cmd = *cmd;
3171 request->sqe_idx = sqe_idx;
3172 request->doca_sq = sq;
3174 request->request.xfer = spdk_nvme_opc_get_data_transfer(request->request.cmd->nvme_cmd.opc);
3176 DOCA_LOG_DBG(
"Received admin command: opcode %u", request->request.cmd->nvme_cmd.opc);
3177 switch (request->request.cmd->nvme_cmd.opc) {
3178 case SPDK_NVME_OPC_CREATE_IO_CQ:
3181 case SPDK_NVME_OPC_DELETE_IO_CQ:
3184 case SPDK_NVME_OPC_CREATE_IO_SQ:
3187 case SPDK_NVME_OPC_DELETE_IO_SQ:
3190 case SPDK_NVME_OPC_ASYNC_EVENT_REQUEST:
3191 request->request.length = 0;
3192 request->request.xfer = SPDK_NVME_DATA_NONE;
3194 case SPDK_NVME_OPC_IDENTIFY:
3197 case SPDK_NVME_OPC_GET_LOG_PAGE:
3198 uint32_t num_dword =
3199 ((((uint32_t)cmd->cdw11_bits.get_log_page.numdu << 16) | cmd->cdw10_bits.get_log_page.numdl) +
3201 if (num_dword > UINT32_MAX / 4) {
3202 DOCA_LOG_ERR(
"NUMD exceeds maximum size: num of DW %u", num_dword);
3205 request->request.length = num_dword * 4;
3207 case SPDK_NVME_OPC_GET_FEATURES:
3208 case SPDK_NVME_OPC_SET_FEATURES:
3209 uint8_t fid = cmd->cdw10_bits.set_features.fid;
3212 case SPDK_NVME_FEAT_LBA_RANGE_TYPE:
3215 case SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION:
3218 case SPDK_NVME_FEAT_TIMESTAMP:
3221 case SPDK_NVME_FEAT_HOST_BEHAVIOR_SUPPORT:
3224 case SPDK_NVME_FEAT_HOST_IDENTIFIER:
3225 if (cmd->cdw11_bits.feat_host_identifier.bits.exhid) {
3231 case SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
3232 case SPDK_NVME_FEAT_NUMBER_OF_QUEUES:
3233 case SPDK_NVME_FEAT_ARBITRATION:
3234 case SPDK_NVME_FEAT_POWER_MANAGEMENT:
3235 case SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD:
3236 case SPDK_NVME_FEAT_ERROR_RECOVERY:
3237 case SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE:
3238 case SPDK_NVME_FEAT_INTERRUPT_COALESCING:
3239 case SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
3240 case SPDK_NVME_FEAT_WRITE_ATOMICITY:
3241 case SPDK_NVME_FEAT_HOST_MEM_BUFFER:
3242 case SPDK_NVME_FEAT_KEEP_ALIVE_TIMER:
3243 case SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT:
3244 case SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG:
3245 case SPDK_NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG:
3246 case SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG:
3247 case SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW:
3248 case SPDK_NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES:
3249 case SPDK_NVME_FEAT_SANITIZE_CONFIG:
3250 case SPDK_NVME_FEAT_ENDURANCE_GROUP_EVENT:
3251 case SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER:
3252 case SPDK_NVME_FEAT_HOST_RESERVE_MASK:
3253 case SPDK_NVME_FEAT_HOST_RESERVE_PERSIST:
3254 request->request.length = 0;
3255 request->request.xfer = SPDK_NVME_DATA_NONE;
3258 DOCA_LOG_ERR(
"Received unsupported feautre: opcode %u", fid);
3263 DOCA_LOG_ERR(
"Received unsupported command: opcode %u", cmd->opc);
3268 switch (request->request.xfer) {
3269 case SPDK_NVME_DATA_NONE:
3276 case SPDK_NVME_DATA_HOST_TO_CONTROLLER:
3284 case SPDK_NVME_DATA_CONTROLLER_TO_HOST:
3292 case SPDK_NVME_DATA_BIDIRECTIONAL:
3293 DOCA_LOG_ERR(
"Command with bidirectional data not support");
3301 #define LBA_SIZE 512
3313 struct spdk_nvme_cmd *cmd = (
struct spdk_nvme_cmd *)&sqe->
data[0];
3316 request->
request.cmd = (
union nvmf_h2c_msg *)cmd;
3317 request->doca_sq = sq;
3318 request->sqe_idx = sqe_idx;
3319 request->request.xfer = spdk_nvme_opc_get_data_transfer(request->request.cmd->nvme_cmd.opc);
3321 DOCA_LOG_DBG(
"Received NVMe command: opcode %u", request->request.cmd->nvme_cmd.opc);
3322 switch (request->request.cmd->nvme_cmd.opc) {
3323 case SPDK_NVME_OPC_FLUSH:
3325 case SPDK_NVME_OPC_WRITE:
3326 case SPDK_NVME_OPC_READ:
3327 request->request.length = (request->request.cmd->nvme_cmd.cdw12_bits.copy.nr + 1) *
LBA_SIZE;
3330 DOCA_LOG_ERR(
"Received unsupported NVM command: opcode %u", cmd->opc);
3336 switch (request->request.xfer) {
3337 case SPDK_NVME_DATA_NONE:
3344 case SPDK_NVME_DATA_HOST_TO_CONTROLLER:
3352 case SPDK_NVME_DATA_CONTROLLER_TO_HOST:
3360 case SPDK_NVME_DATA_BIDIRECTIONAL:
3361 DOCA_LOG_ERR(
"Command with bidirectional data not support");
3410 struct doca_buf *dst,
3411 struct doca_buf *
src,
3434 struct doca_buf *dst,
3435 struct doca_buf *
src,
3444 if (
request->num_of_buffers == 0)
3453 .type = SPDK_NVME_TRANSPORT_CUSTOM,
struct rte_eth_dev_info dev_info
static void nvmf_doca_on_io_sq_stop(struct nvmf_doca_sq *sq)
static void execute_spdk_request(struct nvmf_doca_request *request, void *arg)
static void nvmf_doca_poll_group_create_io_cq_done(void *args)
#define IDENTIFY_CMD_DATA_BUFFER_SIZE
static struct spdk_nvmf_transport_poll_group * nvmf_doca_poll_group_create(struct spdk_nvmf_transport *transport, struct spdk_nvmf_poll_group *group)
#define NVMF_DOCA_DEFAULT_NUM_SHARED_BUFFER
static void nvmf_doca_on_post_cqe_complete(struct nvmf_doca_cq *cq, union doca_data user_data)
static void nvmf_doca_destroy_pci_dev_poll_group(struct nvmf_doca_pci_dev_poll_group *pci_dev_pg)
static void copy_dpu_data_to_host(struct nvmf_doca_request *request, void *arg)
static void nvmf_doca_on_copy_nvm_data_complete(struct nvmf_doca_sq *sq, struct doca_buf *dst, struct doca_buf *src, union doca_data user_data)
static doca_error_t nvmf_doca_create_emulation_manager(struct doca_devinfo *dev_info, struct nvmf_doca_emulation_manager **ret_emulation_manager)
static void flr_event_handler_cb(struct doca_devemu_pci_dev *pci_dev, union doca_data user_data)
static void enable_nvmf_controller_cb(struct nvmf_doca_request *request, void *cb_arg)
#define FEAT_CMD_LBA_RANGE_SIZE
static void buffers_ready_copy_data_host_to_dpu(struct nvmf_doca_request *request)
static void nvmf_doca_pci_dev_admin_reset_continue(struct nvmf_doca_pci_dev_admin *pci_dev_admin)
static int nvmf_doca_listen_associate(struct spdk_nvmf_transport *transport, const struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid)
static void begin_nvme_cmd_data_dpu_to_host(struct nvmf_doca_request *request)
#define ADMIN_QP_POLL_RATE_LIMIT
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
static void nvmf_doca_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group)
static doca_error_t register_handlers_set_datapath_and_start(struct nvmf_doca_emulation_manager *doca_emulation_manager, struct nvmf_doca_pci_dev_admin *pci_dev_admin)
static struct spdk_nvmf_transport_poll_group * nvmf_doca_get_optimal_poll_group(struct spdk_nvmf_qpair *qpair)
#define NVMF_DOCA_DEFAULT_AQ_DEPTH
#define NVMF_DOCA_DEFAULT_MAX_QPAIRS_PER_CTRLR
#define NVMF_DOCA_DEFAULT_BUFFER_CACHE_SIZE
static int nvmf_doca_req_free(struct spdk_nvmf_request *req)
static struct nvmf_doca_io * admin_qp_find_io_cq_by_id(struct nvmf_doca_admin_qp *admin_qp, uint32_t io_cq_id)
static void post_cqe_from_response(struct nvmf_doca_request *request, void *arg)
static doca_error_t nvmf_doca_create_pci_dev_poll_group(struct nvmf_doca_pci_dev_admin *pci_dev_admin, struct nvmf_doca_admin_qp *admin_qp, struct nvmf_doca_poll_group *doca_poll_group, struct nvmf_doca_pci_dev_poll_group **ret_pci_dev_pg)
static void nvmf_doca_poll_group_create_io_sq(void *args)
static void begin_nvme_cmd_data_host_to_dpu(struct nvmf_doca_request *request)
static void nvmf_doca_on_fetch_sqe_complete(struct nvmf_doca_sq *sq, struct nvmf_doca_sqe *sqe, uint16_t sqe_idx)
static int nvmf_doca_pci_dev_admin_create(struct nvmf_doca_transport *doca_transport, const struct spdk_nvme_transport_id *trid, struct nvmf_doca_pci_dev_admin **pci_dev_admin_out)
static void handle_create_io_cq(struct nvmf_doca_sq *sq, struct nvmf_doca_request *request)
#define FEAT_CMD_TIMESTAMP_SIZE
static void begin_nvme_admin_cmd_data_dpu_to_host(struct nvmf_doca_request *request)
static void hotplug_state_change_handler_cb(struct doca_devemu_pci_dev *pci_dev, union doca_data user_data)
#define NVMF_DOCA_DEFAULT_ABORT_TIMEOUT_SEC
static void nvmf_doca_admin_qp_stop_all_io_cqs(struct nvmf_doca_admin_qp *admin_qp)
static int nvmf_doca_poll_group_poll(struct spdk_nvmf_transport_poll_group *group)
static doca_error_t nvmf_doca_pci_type_create_and_start(struct nvmf_doca_emulation_manager *doca_emulation_manager)
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_doca
static void nvmf_doca_pci_dev_poll_group_stop_io_sq(void *ctx)
static void nvmf_doca_destroy_admin_qp_continue(struct nvmf_doca_pci_dev_admin *pci_dev_admin)
static int nvmf_doca_req_complete(struct spdk_nvmf_request *req)
static void nvmf_doca_admin_qp_stop_all_io_sqs(struct nvmf_doca_admin_qp *admin_qp)
static struct spdk_nvmf_transport * nvmf_doca_create(struct spdk_nvmf_transport_opts *opts)
static void stateful_region_write_event_handler_cb(struct doca_devemu_pci_dev_event_bar_stateful_region_driver_write *event, union doca_data user_data)
static void nvmf_doca_connect_spdk_qp_done(struct nvmf_doca_request *request, void *cb_arg)
#define NVMF_DOCA_DEFAULT_IN_CAPSULE_DATA_SIZE
#define HOTPLUG_TIMEOUT_IN_MICROS
static void begin_nvme_cmd_data_none(struct nvmf_doca_request *request)
static doca_error_t check_for_duplicate(struct nvmf_doca_transport *doca_transport, const char *vuid)
static struct nvmf_doca_sq * admin_qp_find_io_sq_by_id(struct nvmf_doca_admin_qp *admin_qp, uint32_t io_sq_id)
static void nvmf_doca_pci_dev_poll_group_stop_io_cq(void *ctx)
#define NVMF_DOCA_DIF_INSERT_OR_STRIP
static void copy_prp_list_data(struct nvmf_doca_request *request, void *arg)
struct doca_dpa_app * nvmf_doca_transport_app
static void nvmf_doca_on_admin_cq_stop(struct nvmf_doca_io *io)
static void nvme_cmd_map_prps(struct nvmf_doca_request *request)
static void nvmf_doca_on_post_nvm_cqe_complete(struct nvmf_doca_cq *cq, union doca_data user_data)
static struct nvmf_doca_pci_dev_admin * nvmf_doca_transport_find_pci_dev_admin(struct nvmf_doca_transport *doca_transport, const char *vuid)
#define FEAT_CMD_HOST_IDENTIFIER_SIZE
static void nvmf_doca_close_qpair(struct spdk_nvmf_qpair *qpair, spdk_nvmf_transport_qpair_fini_cb cb_fn, void *cb_arg)
static doca_error_t find_emulation_manager_and_function_by_vuid(struct nvmf_doca_transport *doca_transport, const char *vuid, struct nvmf_doca_emulation_manager **ret_emulation_manager, struct doca_dev_rep **ret_device_rep)
static void nvmf_doca_on_initialization_error(void *cb_arg)
static struct nvmf_doca_poll_group * choose_poll_group(struct nvmf_doca_transport *transport)
static void handle_delete_io_cq(struct nvmf_doca_sq *sq, struct nvmf_doca_request *request)
static int nvmf_doca_connect_spdk_qp(struct nvmf_doca_sq *sq)
static void nvmf_doca_dump_opts(struct spdk_nvmf_transport *transport, struct spdk_json_write_ctx *w)
static void handle_create_io_sq(struct nvmf_doca_sq *sq, struct nvmf_doca_request *request)
static void nvmf_doca_set_property(struct nvmf_doca_sq *doca_sq)
#define FEAT_CMD_HOST_BEHAVIOR_SUPPORT_SIZE
static doca_error_t devemu_hotplug_transition_wait(struct nvmf_doca_pci_dev_admin *pci_dev_admin, enum doca_devemu_pci_hotplug_state new_state, size_t timeout_in_micros)
#define NVMF_DOCA_DEFAULT_IO_UINT_SIZE
#define NVMF_ADMIN_QUEUE_ID
static void nvmf_doca_poll_group_create_io_cq(void *args)
static int nvmf_doca_poll_group_remove(struct spdk_nvmf_transport_poll_group *group, struct spdk_nvmf_qpair *qpair)
static void post_error_cqe_from_response(struct nvmf_doca_request *request)
static int nvmf_doca_admin_poll_group_poll(void *arg)
static void buffers_ready_copy_data_dpu_to_host(struct nvmf_doca_request *request)
static doca_error_t register_to_stateful_region_write_events(struct doca_devemu_pci_dev *pci_dev, struct nvmf_doca_pci_dev_admin *pci_dev_admin)
static doca_error_t nvmf_doca_destroy_emulation_manager(struct nvmf_doca_emulation_manager *doca_emulation_manager)
static doca_error_t nvmf_doca_create_host_mmap(struct doca_devemu_pci_dev *pci_dev, struct doca_dev *emulation_manager, struct doca_mmap **mmap_out)
@ NVMF_DOCA_LISTENER_INITIALIZING
@ NVMF_DOCA_LISTENER_INITIALIZED
@ NVMF_DOCA_LISTENER_INITIALIZATION_ERROR
@ NVMF_DOCA_LISTENER_UNINITIALIZED
@ NVMF_DOCA_LISTENER_RESETTING
static void handle_controller_register_events(struct doca_devemu_pci_dev *pci_dev, const struct bar_region_config *config)
static void nvmf_doca_destroy_admin_qp(void *cb_arg)
static void nvmf_doca_poll_group_create_io_sq_done(void *args)
static void nvmf_doca_on_copy_data_complete(struct nvmf_doca_sq *sq, struct doca_buf *dst, struct doca_buf *src, union doca_data user_data)
static void nvmf_doca_admin_poll_group_destroy(struct nvmf_doca_admin_poll_group *admin_pg)
static doca_error_t nvmf_doca_admin_poll_group_create(struct nvmf_doca_admin_poll_group *admin_pg)
static void nvmf_doca_pci_dev_admin_destroy(struct nvmf_doca_pci_dev_admin *pci_dev_admin)
static void nvmf_doca_on_admin_sq_stop(struct nvmf_doca_sq *sq)
static void nvmf_doca_opts_init(struct spdk_nvmf_transport_opts *opts)
static void nvmf_doca_create_admin_qp(void *cb_arg)
static void nvmf_doca_pci_dev_poll_group_stop_io_sq_done(void *ctx)
static void nvmf_doca_pci_dev_admin_reset(struct nvmf_doca_pci_dev_admin *pci_dev_admin)
#define FEAT_CMD_HOST_IDENTIFIER_EXT_SIZE
static void handle_delete_io_sq(struct nvmf_doca_sq *sq, struct nvmf_doca_request *request)
static int nvmf_doca_listen(struct spdk_nvmf_transport *transport, const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *listen_opts)
static int nvmf_doca_destroy(struct spdk_nvmf_transport *transport, spdk_nvmf_transport_destroy_done_cb cb_fn, void *cb_arg)
static void init_dpu_host_buffers(struct nvmf_doca_request *request)
static void nvmf_doca_stop_listen(struct spdk_nvmf_transport *transport, const struct spdk_nvme_transport_id *trid)
static void nvmf_doca_on_io_cq_stop(struct nvmf_doca_io *io)
#define NVMF_DOCA_DEFAULT_MAX_QUEUE_DEPTH
static struct nvmf_doca_pci_dev_poll_group * get_pci_dev_poll_group(struct nvmf_doca_poll_group *doca_poll_group, struct doca_devemu_pci_dev *pci_dev)
static void devemu_state_changed_cb(const union doca_data user_data, struct doca_ctx *ctx, enum doca_ctx_states prev_state, enum doca_ctx_states next_state)
static void begin_nvme_admin_cmd_data_host_to_dpu(struct nvmf_doca_request *request)
static void copy_nvme_dpu_data_to_host(struct nvmf_doca_request *request, void *arg)
static void nvmf_doca_create_admin_qp_done(void *cb_arg)
#define NVMF_DOCA_DEFAULT_MAX_IO_SIZE
DOCA_LOG_REGISTER(NVME_EMULATION_DOCA_TRANSPORT)
static void nvmf_doca_pci_dev_poll_group_stop_io_cq_done(void *ctx)
static void nvmf_doca_destroy_admin_qp_done(void *cb_arg)
SPDK_NVMF_TRANSPORT_REGISTER(doca, &spdk_nvmf_transport_doca)
static int nvmf_doca_poll_group_add(struct spdk_nvmf_transport_poll_group *group, struct spdk_nvmf_qpair *qpair)
static void nvmf_doca_on_fetch_nvm_sqe_complete(struct nvmf_doca_sq *sq, struct nvmf_doca_sqe *sqe, uint16_t sqe_idx)
static int nvmf_doca_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid)
#define FEAT_CMD_AUTONOMOUS_POWER_STATE_TRANSITION_SIZE
static uint64_t *restrict src
if(bitoffset % 64+bitlength > 64) result|
static enum doca_flow_port_operation_state current_state
DOCA_STABLE doca_error_t doca_buf_dec_refcount(struct doca_buf *buf, uint16_t *refcount)
Decrease the object reference count by 1, if 0 reached, return the element back to the inventory.
DOCA_STABLE doca_error_t doca_buf_get_head(const struct doca_buf *buf, void **head)
Get the buffer's head.
DOCA_STABLE doca_error_t doca_ctx_start(struct doca_ctx *ctx)
Finalizes all configurations, and starts the DOCA CTX.
DOCA_EXPERIMENTAL doca_error_t doca_ctx_set_datapath_on_dpa(struct doca_ctx *ctx, struct doca_dpa *dpa_dev)
This function binds the DOCA context to a dpa device.
DOCA_STABLE doca_error_t doca_ctx_set_state_changed_cb(struct doca_ctx *ctx, doca_ctx_state_changed_callback_t cb)
Set state changed callback.
DOCA_STABLE doca_error_t doca_ctx_set_user_data(struct doca_ctx *ctx, union doca_data user_data)
set user data to context
DOCA_STABLE doca_error_t doca_ctx_stop(struct doca_ctx *ctx)
Stops the context allowing reconfiguration.
doca_ctx_states
This enum defines the states of a context.
DOCA_STABLE doca_error_t doca_ctx_get_user_data(const struct doca_ctx *ctx, union doca_data *user_data)
get user data from context
@ DOCA_CTX_STATE_STARTING
@ DOCA_CTX_STATE_STOPPING
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_bar_stateful_region_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, uint64_t size)
Set a stateful BAR region configuration for a BAR layout in a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_start(struct doca_devemu_pci_type *pci_type)
Start a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_create_rep_list(struct doca_devemu_pci_type *pci_type, struct doca_devinfo_rep ***dev_list_rep, uint32_t *nb_devs_rep)
Create list of available representor devices for a given DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_memory_bar_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint8_t log_sz, enum doca_devemu_pci_bar_mem_type memory_type, uint8_t prefetchable)
Set a memory BAR layout configuration for DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_stop(struct doca_devemu_pci_type *pci_type)
Stop a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_class_code(struct doca_devemu_pci_type *pci_type, uint32_t class_code)
Set the PCI Class Code of a DOCA devemu PCI type to identify generic operation.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_revision_id(struct doca_devemu_pci_type *pci_type, uint8_t revision_id)
Set the PCI Revision ID of a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_device_id(struct doca_devemu_pci_type *pci_type, uint16_t device_id)
Set the PCI Device ID of a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_bar_db_region_by_offset_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, uint64_t size, uint8_t log_db_size, uint8_t log_stride_size)
Set a doorbell BAR region configuration for a BAR layout in a DOCA devemu PCI type....
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_create(const char *name, struct doca_devemu_pci_type **pci_type)
Create a stopped DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_vendor_id(struct doca_devemu_pci_type *pci_type, uint16_t vendor_id)
Set the PCI Vendor ID of a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_bar_db_region_by_data_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, uint64_t size, uint8_t log_db_size, uint16_t db_id_msbyte, uint16_t db_id_lsbyte)
Set a doorbell BAR region configuration for a BAR layout in a DOCA devemu PCI type....
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_num_msix(struct doca_devemu_pci_type *pci_type, uint16_t num_msix)
Set the size of the MSI-X Table from MSI-X Capability Registers (1 based) of a DOCA devemu PCI type....
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_subsystem_id(struct doca_devemu_pci_type *pci_type, uint16_t subsystem_id)
Set the PCI Subsystem ID of a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_destroy(struct doca_devemu_pci_type *pci_type)
Destroy a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_modify_bar_stateful_region_default_values(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, void *default_values, uint64_t size)
Modify default registers values for a configured stateful region in a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_subsystem_vendor_id(struct doca_devemu_pci_type *pci_type, uint16_t subsystem_vid)
Set the PCI Subsystem Vendor ID of a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_bar_msix_pba_region_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, uint64_t size)
Set a MSI-X PBA BAR region configuration for a BAR layout in a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_dev(struct doca_devemu_pci_type *pci_type, struct doca_dev *dev)
Set the DOCA device for a specific DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_type_set_bar_msix_table_region_conf(struct doca_devemu_pci_type *pci_type, uint8_t id, uint64_t start_addr, uint64_t size)
Set a MSI-X table BAR region configuration for a BAR layout in a DOCA devemu PCI type.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_event_flr_register(struct doca_devemu_pci_dev *pci_dev, doca_devemu_pci_dev_event_flr_handler_cb_t handler, union doca_data user_data)
Register to PCI FLR (Function Level Reset) event.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_hotplug(struct doca_devemu_pci_dev *pci_dev)
Issue hotplug procedure of the DOCA devemu PCI device.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_destroy(struct doca_devemu_pci_dev *pci_dev)
Free a DOCA devemu PCI device.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_get_hotplug_state(struct doca_devemu_pci_dev *pci_dev, enum doca_devemu_pci_hotplug_state *state)
Get the hotplug state of the DOCA devemu PCI device.
DOCA_EXPERIMENTAL struct doca_devemu_pci_dev * doca_devemu_pci_dev_event_bar_stateful_region_driver_write_get_pci_dev(struct doca_devemu_pci_dev_event_bar_stateful_region_driver_write *event)
Get DOCA devemu PCI device from BAR stateful region driver write event.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_create(struct doca_devemu_pci_type *pci_type, struct doca_dev_rep *dev_rep, struct doca_pe *progress_engine, struct doca_devemu_pci_dev **pci_dev)
Allocate DOCA devemu PCI device.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_query_bar_stateful_region_values(struct doca_devemu_pci_dev *pci_dev, uint8_t id, uint64_t offset, void *out_values, uint64_t size)
Query registers values of the stateful region in a DOCA devemu PCI device.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_event_bar_stateful_region_driver_write_register(struct doca_devemu_pci_dev *pci_dev, doca_devemu_pci_dev_event_bar_stateful_region_driver_write_handler_cb_t handler, uint8_t bar_id, uint64_t bar_region_start_addr, union doca_data user_data)
Register to BAR stateful region driver write event.
doca_devemu_pci_hotplug_state
DOCA devemu pci hotplug state.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_event_hotplug_state_change_register(struct doca_devemu_pci_dev *pci_dev, doca_devemu_pci_dev_event_hotplug_state_change_handler_cb_t handler, union doca_data user_data)
Register to hotplug state changes.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_mmap_create(struct doca_devemu_pci_dev *pci_dev, struct doca_mmap **mmap)
Allocates zero size memory map object with default/unset attributes associated with a DOCA devemu PCI...
DOCA_EXPERIMENTAL struct doca_ctx * doca_devemu_pci_dev_as_ctx(struct doca_devemu_pci_dev *pci_dev)
Convert DOCA devemu PCI device instance into DOCA context.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_hotunplug(struct doca_devemu_pci_dev *pci_dev)
Issue hot unplug procedure of the DOCA devemu PCI device.
DOCA_EXPERIMENTAL doca_error_t doca_devemu_pci_dev_modify_bar_stateful_region_values(struct doca_devemu_pci_dev *pci_dev, uint8_t id, uint64_t offset, void *values, uint64_t size)
Modify registers values for stateful region in a DOCA devemu PCI device.
@ DOCA_DEVEMU_PCI_HP_STATE_POWER_OFF
@ DOCA_DEVEMU_PCI_HP_STATE_POWER_ON
DOCA_STABLE doca_error_t doca_dev_rep_open(struct doca_devinfo_rep *devinfo, struct doca_dev_rep **dev_rep)
Initialize representor device for use.
DOCA_STABLE doca_error_t doca_devinfo_cap_is_hotplug_manager_supported(const struct doca_devinfo *devinfo, uint8_t *is_hotplug_manager)
Get the hotplug manager capability of a DOCA devinfo.
DOCA_STABLE doca_error_t doca_devinfo_rep_destroy_list(struct doca_devinfo_rep **dev_list_rep)
Destroy list of representor device info structures.
DOCA_STABLE doca_error_t doca_devinfo_create_list(struct doca_devinfo ***dev_list, uint32_t *nb_devs)
Creates list of all available local devices.
DOCA_STABLE doca_error_t doca_dev_rep_close(struct doca_dev_rep *dev)
Destroy allocated representor device instance.
DOCA_STABLE doca_error_t doca_devinfo_rep_get_vuid(const struct doca_devinfo_rep *devinfo_rep, char *rep_vuid, uint32_t size)
Get the Vendor Unique ID of a representor DOCA devinfo.
#define DOCA_DEVINFO_REP_VUID_SIZE
Buffer size to hold VUID. Including a null terminator.
DOCA_STABLE doca_error_t doca_devinfo_destroy_list(struct doca_devinfo **dev_list)
Destroy list of local device info structures.
DOCA_STABLE doca_error_t doca_dev_open(struct doca_devinfo *devinfo, struct doca_dev **dev)
Initialize local device for use.
DOCA_EXPERIMENTAL doca_error_t doca_dpa_stop(struct doca_dpa *dpa)
Stop a DPA context.
DOCA_EXPERIMENTAL doca_error_t doca_dpa_create(struct doca_dev *dev, struct doca_dpa **dpa)
Create a DOCA DPA Context.
DOCA_EXPERIMENTAL doca_error_t doca_dpa_destroy(struct doca_dpa *dpa)
Destroy a DOCA DPA context.
DOCA_EXPERIMENTAL doca_error_t doca_dpa_start(struct doca_dpa *dpa)
Start a DPA context.
DOCA_EXPERIMENTAL doca_error_t doca_dpa_set_app(struct doca_dpa *dpa, struct doca_dpa_app *app)
Set program app for DPA context.
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
@ DOCA_ERROR_INITIALIZATION
@ DOCA_ERROR_NOT_PERMITTED
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
#define DOCA_LOG_TRC(format,...)
Generates a TRACE application log message.
#define DOCA_LOG_DBG(format,...)
Generates a DEBUG application log message.
DOCA_STABLE doca_error_t doca_mmap_set_memrange(struct doca_mmap *mmap, void *addr, size_t len)
Set the memory range of DOCA memory map.
DOCA_STABLE doca_error_t doca_mmap_set_max_num_devices(struct doca_mmap *mmap, uint32_t max_num_devices)
Set a new max number of devices to add to a DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_destroy(struct doca_mmap *mmap)
Destroy DOCA Memory Map structure.
DOCA_STABLE doca_error_t doca_mmap_set_permissions(struct doca_mmap *mmap, uint32_t access_mask)
Set access flags of the registered memory.
DOCA_STABLE doca_error_t doca_mmap_start(struct doca_mmap *mmap)
Start DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_add_dev(struct doca_mmap *mmap, struct doca_dev *dev)
Register DOCA memory map on a given device.
DOCA_STABLE doca_error_t doca_pe_destroy(struct doca_pe *pe)
Destroy doca progress engine.
DOCA_STABLE uint8_t doca_pe_progress(struct doca_pe *pe)
Run the progress engine.
DOCA_STABLE doca_error_t doca_pe_create(struct doca_pe **pe)
Creates DOCA progress engine.
@ DOCA_ACCESS_FLAG_LOCAL_READ_WRITE
void cleanup_pci_resources(struct doca_devemu_pci_type *pci_type, struct doca_dev *dev)
const char * hotplug_state_to_string(enum doca_devemu_pci_hotplug_state hotplug_state)
#define PCI_TYPE_NUM_BAR_MSIX_PBA_REGIONS
#define PCI_TYPE_SUBSYSTEM_VENDOR_ID
#define PCI_TYPE_NUM_BAR_MSIX_TABLE_REGIONS
static const struct bar_memory_layout_config layout_configs[PCI_TYPE_NUM_BAR_MEMORY_LAYOUT]
#define PCI_TYPE_NUM_BAR_MEMORY_LAYOUT
static const struct bar_db_region_config db_configs[PCI_TYPE_NUM_BAR_DB_REGIONS]
#define PCI_TYPE_SUBSYSTEM_ID
#define PCI_TYPE_VENDOR_ID
#define PCI_TYPE_DEVICE_ID
static const struct bar_region_config msix_pba_configs[PCI_TYPE_NUM_BAR_MSIX_PBA_REGIONS]
#define PCI_TYPE_NUM_BAR_DB_REGIONS
#define PCI_TYPE_NUM_BAR_STATEFUL_REGIONS
#define PCI_TYPE_REVISION_ID
static const struct bar_region_config msix_table_configs[PCI_TYPE_NUM_BAR_MSIX_TABLE_REGIONS]
#define PCI_TYPE_CLASS_CODE
static const struct bar_region_config stateful_configs[PCI_TYPE_NUM_BAR_STATEFUL_REGIONS]
#define PCI_TYPE_NUM_MSIX
struct doca_buf * nvmf_doca_sq_get_dpu_buffer(struct nvmf_doca_sq *sq)
struct doca_buf * nvmf_doca_sq_get_host_buffer(struct nvmf_doca_sq *sq, uintptr_t host_io_address)
void nvmf_doca_request_free(struct nvmf_doca_request *request)
void nvmf_doca_io_add_sq(struct nvmf_doca_io *io, const struct nvmf_doca_io_add_sq_attr *attr, struct nvmf_doca_sq *sq)
void nvmf_doca_request_complete(struct nvmf_doca_request *request)
void nvmf_doca_sq_copy_data(struct nvmf_doca_sq *sq, struct doca_buf *dst_buffer, struct doca_buf *src_buffer, size_t length, union doca_data user_data)
struct nvmf_doca_request * nvmf_doca_request_get(struct nvmf_doca_sq *sq)
void nvmf_doca_io_destroy(struct nvmf_doca_io *io)
doca_error_t nvmf_doca_io_create(const struct nvmf_doca_io_create_attr *attr, struct nvmf_doca_io *io)
void nvmf_doca_sq_stop(struct nvmf_doca_sq *sq)
void nvmf_doca_io_stop(struct nvmf_doca_io *io)
void nvmf_doca_io_post_cqe(struct nvmf_doca_io *io, const struct nvmf_doca_cqe *cqe, union doca_data user_data)
void nvmf_doca_io_rm_sq(struct nvmf_doca_sq *sq)
__UINTPTR_TYPE__ uintptr_t
struct bar_region_config region
uint8_t log_db_stride_size
enum doca_devemu_pci_bar_mem_type memory_type
struct spdk_poller * poller
struct spdk_thread * thread
struct nvmf_doca_sq * admin_sq
struct nvmf_doca_io * admin_cq
uint64_t admin_sq_address
uint64_t admin_cq_address
struct nvmf_doca_admin_qp * admin_qp_out
struct nvmf_doca_pci_dev_admin * pci_dev_admin
struct nvmf_doca_poll_group * doca_poll_group
struct doca_devemu_pci_type * pci_type
struct doca_dev * emulation_manager
struct nvmf_doca_pci_dev_poll_group * poll_group
struct nvmf_doca_pci_dev_admin * pci_dev_admin
union spdk_nvme_csts_register csts
union spdk_nvme_cc_register cc
union spdk_nvme_aqa_register aqa
union spdk_nvme_cap_register cap
union spdk_nvme_vs_register vs
struct nvmf_doca_poll_group * admin_qp_pg
struct nvmf_doca_transport * doca_transport
struct spdk_nvmf_ctrlr * ctrlr
struct nvmf_doca_emulation_manager * emulation_manager
void * stateful_region_values
enum nvmf_doca_listener_state state
struct nvmf_doca_admin_qp * admin_qp
struct doca_dev_rep * dev_rep
struct spdk_nvmf_subsystem * subsystem
struct spdk_nvme_transport_id trid
struct doca_devemu_pci_dev * pci_dev
struct nvmf_doca_pci_dev_admin * pci_dev_admin
struct nvmf_doca_admin_qp * admin_qp
struct doca_mmap * host_mmap
struct nvmf_doca_poll_group * poll_group
struct nvmf_doca_io * io_cq
struct nvmf_doca_request * request
struct nvmf_doca_pci_dev_admin * pci_dev_admin
struct nvmf_doca_io * io_cq
struct nvmf_doca_request * request
struct nvmf_doca_pci_dev_poll_group * pci_dev_pg
struct nvmf_doca_sq * io_sq
struct nvmf_doca_request * request
struct nvmf_doca_request * request
size_t admin_qp_poll_rate_limiter
struct spdk_nvmf_transport_poll_group pg
struct doca_pe * admin_qp_pe
struct doca_buf * prp_dpu_buf
struct doca_buf * dpu_buffer[NVMF_REQ_MAX_BUFFERS]
struct spdk_nvmf_request request
struct doca_buf * host_buffer[NVMF_REQ_MAX_BUFFERS]
struct nvmf_doca_sq * doca_sq
struct doca_buf * prp_host_buf
TAILQ_HEAD(, nvmf_doca_request) request_pool
struct spdk_nvmf_qpair spdk_qp
struct nvmf_doca_queue queue
uint8_t data[NVMF_DOCA_SQE_SIZE]
struct spdk_nvmf_transport transport
Convenience type for representing opaque data.
struct upf_accel_ctx * ctx