1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #include <inttypes.h> 6 7 #include <rte_common.h> 8 #include <rte_debug.h> 9 #include <rte_dev.h> 10 #include <rte_eal.h> 11 #include <rte_ethdev_driver.h> 12 #include <rte_event_eth_rx_adapter.h> 13 #include <rte_kvargs.h> 14 #include <rte_lcore.h> 15 #include <rte_log.h> 16 #include <rte_malloc.h> 17 #include <rte_memory.h> 18 #include <rte_bus_vdev.h> 19 20 #include "ssovf_evdev.h" 21 22 int otx_logtype_ssovf; 23 24 RTE_INIT(otx_ssovf_init_log); 25 static void 26 otx_ssovf_init_log(void) 27 { 28 otx_logtype_ssovf = rte_log_register("pmd.event.octeontx"); 29 if (otx_logtype_ssovf >= 0) 30 rte_log_set_level(otx_logtype_ssovf, RTE_LOG_NOTICE); 31 } 32 33 /* SSOPF Mailbox messages */ 34 35 struct ssovf_mbox_dev_info { 36 uint64_t min_deq_timeout_ns; 37 uint64_t max_deq_timeout_ns; 38 uint32_t max_num_events; 39 }; 40 41 static int 42 ssovf_mbox_dev_info(struct ssovf_mbox_dev_info *info) 43 { 44 struct octeontx_mbox_hdr hdr = {0}; 45 uint16_t len = sizeof(struct ssovf_mbox_dev_info); 46 47 hdr.coproc = SSO_COPROC; 48 hdr.msg = SSO_GET_DEV_INFO; 49 hdr.vfid = 0; 50 51 memset(info, 0, len); 52 return octeontx_ssovf_mbox_send(&hdr, NULL, 0, info, len); 53 } 54 55 struct ssovf_mbox_getwork_wait { 56 uint64_t wait_ns; 57 }; 58 59 static int 60 ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns) 61 { 62 struct octeontx_mbox_hdr hdr = {0}; 63 struct ssovf_mbox_getwork_wait tmo_set; 64 uint16_t len = sizeof(struct ssovf_mbox_getwork_wait); 65 int ret; 66 67 hdr.coproc = SSO_COPROC; 68 hdr.msg = SSO_SET_GETWORK_WAIT; 69 hdr.vfid = 0; 70 71 tmo_set.wait_ns = timeout_ns; 72 ret = octeontx_ssovf_mbox_send(&hdr, &tmo_set, len, NULL, 0); 73 if (ret) 74 ssovf_log_err("Failed to set getwork timeout(%d)", ret); 75 76 return ret; 77 } 78 79 struct ssovf_mbox_grp_pri { 80 uint8_t wgt_left; /* Read only */ 81 uint8_t weight; 82 uint8_t affinity; 83 uint8_t priority; 84 }; 85 86 static int 87 ssovf_mbox_priority_set(uint8_t queue, uint8_t prio) 88 { 89 struct octeontx_mbox_hdr hdr = {0}; 90 struct ssovf_mbox_grp_pri grp; 91 uint16_t len = sizeof(struct ssovf_mbox_grp_pri); 92 int ret; 93 94 hdr.coproc = SSO_COPROC; 95 hdr.msg = SSO_GRP_SET_PRIORITY; 96 hdr.vfid = queue; 97 98 grp.weight = 0xff; 99 grp.affinity = 0xff; 100 grp.priority = prio / 32; /* Normalize to 0 to 7 */ 101 102 ret = octeontx_ssovf_mbox_send(&hdr, &grp, len, NULL, 0); 103 if (ret) 104 ssovf_log_err("Failed to set grp=%d prio=%d", queue, prio); 105 106 return ret; 107 } 108 109 struct ssovf_mbox_convert_ns_getworks_iter { 110 uint64_t wait_ns; 111 uint32_t getwork_iter;/* Get_work iterations for the given wait_ns */ 112 }; 113 114 static int 115 ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks) 116 { 117 struct octeontx_mbox_hdr hdr = {0}; 118 struct ssovf_mbox_convert_ns_getworks_iter ns2iter; 119 uint16_t len = sizeof(ns2iter); 120 int ret; 121 122 hdr.coproc = SSO_COPROC; 123 hdr.msg = SSO_CONVERT_NS_GETWORK_ITER; 124 hdr.vfid = 0; 125 126 memset(&ns2iter, 0, len); 127 ns2iter.wait_ns = ns; 128 ret = octeontx_ssovf_mbox_send(&hdr, &ns2iter, len, &ns2iter, len); 129 if (ret < 0 || (ret != len)) { 130 ssovf_log_err("Failed to get tmo ticks ns=%"PRId64"", ns); 131 return -EIO; 132 } 133 134 *tmo_ticks = ns2iter.getwork_iter; 135 return 0; 136 } 137 138 static void 139 ssovf_fastpath_fns_set(struct rte_eventdev *dev) 140 { 141 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 142 143 dev->enqueue = ssows_enq; 144 dev->enqueue_burst = ssows_enq_burst; 145 dev->enqueue_new_burst = ssows_enq_new_burst; 146 dev->enqueue_forward_burst = ssows_enq_fwd_burst; 147 dev->dequeue = ssows_deq; 148 dev->dequeue_burst = ssows_deq_burst; 149 150 if (edev->is_timeout_deq) { 151 dev->dequeue = ssows_deq_timeout; 152 dev->dequeue_burst = ssows_deq_timeout_burst; 153 } 154 } 155 156 static void 157 ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info) 158 { 159 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 160 161 dev_info->driver_name = RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD); 162 dev_info->min_dequeue_timeout_ns = edev->min_deq_timeout_ns; 163 dev_info->max_dequeue_timeout_ns = edev->max_deq_timeout_ns; 164 dev_info->max_event_queues = edev->max_event_queues; 165 dev_info->max_event_queue_flows = (1ULL << 20); 166 dev_info->max_event_queue_priority_levels = 8; 167 dev_info->max_event_priority_levels = 1; 168 dev_info->max_event_ports = edev->max_event_ports; 169 dev_info->max_event_port_dequeue_depth = 1; 170 dev_info->max_event_port_enqueue_depth = 1; 171 dev_info->max_num_events = edev->max_num_events; 172 dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_QUEUE_QOS | 173 RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED | 174 RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES| 175 RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK | 176 RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT | 177 RTE_EVENT_DEV_CAP_NONSEQ_MODE; 178 179 } 180 181 static int 182 ssovf_configure(const struct rte_eventdev *dev) 183 { 184 struct rte_event_dev_config *conf = &dev->data->dev_conf; 185 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 186 uint64_t deq_tmo_ns; 187 188 ssovf_func_trace(); 189 deq_tmo_ns = conf->dequeue_timeout_ns; 190 if (deq_tmo_ns == 0) 191 deq_tmo_ns = edev->min_deq_timeout_ns; 192 193 if (conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT) { 194 edev->is_timeout_deq = 1; 195 deq_tmo_ns = edev->min_deq_timeout_ns; 196 } 197 edev->nb_event_queues = conf->nb_event_queues; 198 edev->nb_event_ports = conf->nb_event_ports; 199 200 return ssovf_mbox_getwork_tmo_set(deq_tmo_ns); 201 } 202 203 static void 204 ssovf_queue_def_conf(struct rte_eventdev *dev, uint8_t queue_id, 205 struct rte_event_queue_conf *queue_conf) 206 { 207 RTE_SET_USED(dev); 208 RTE_SET_USED(queue_id); 209 210 queue_conf->nb_atomic_flows = (1ULL << 20); 211 queue_conf->nb_atomic_order_sequences = (1ULL << 20); 212 queue_conf->event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES; 213 queue_conf->priority = RTE_EVENT_DEV_PRIORITY_NORMAL; 214 } 215 216 static void 217 ssovf_queue_release(struct rte_eventdev *dev, uint8_t queue_id) 218 { 219 RTE_SET_USED(dev); 220 RTE_SET_USED(queue_id); 221 } 222 223 static int 224 ssovf_queue_setup(struct rte_eventdev *dev, uint8_t queue_id, 225 const struct rte_event_queue_conf *queue_conf) 226 { 227 RTE_SET_USED(dev); 228 ssovf_func_trace("queue=%d prio=%d", queue_id, queue_conf->priority); 229 230 return ssovf_mbox_priority_set(queue_id, queue_conf->priority); 231 } 232 233 static void 234 ssovf_port_def_conf(struct rte_eventdev *dev, uint8_t port_id, 235 struct rte_event_port_conf *port_conf) 236 { 237 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 238 239 RTE_SET_USED(port_id); 240 port_conf->new_event_threshold = edev->max_num_events; 241 port_conf->dequeue_depth = 1; 242 port_conf->enqueue_depth = 1; 243 port_conf->disable_implicit_release = 0; 244 } 245 246 static void 247 ssovf_port_release(void *port) 248 { 249 rte_free(port); 250 } 251 252 static int 253 ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id, 254 const struct rte_event_port_conf *port_conf) 255 { 256 struct ssows *ws; 257 uint32_t reg_off; 258 uint8_t q; 259 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 260 261 ssovf_func_trace("port=%d", port_id); 262 RTE_SET_USED(port_conf); 263 264 /* Free memory prior to re-allocation if needed */ 265 if (dev->data->ports[port_id] != NULL) { 266 ssovf_port_release(dev->data->ports[port_id]); 267 dev->data->ports[port_id] = NULL; 268 } 269 270 /* Allocate event port memory */ 271 ws = rte_zmalloc_socket("eventdev ssows", 272 sizeof(struct ssows), RTE_CACHE_LINE_SIZE, 273 dev->data->socket_id); 274 if (ws == NULL) { 275 ssovf_log_err("Failed to alloc memory for port=%d", port_id); 276 return -ENOMEM; 277 } 278 279 ws->base = octeontx_ssovf_bar(OCTEONTX_SSO_HWS, port_id, 0); 280 if (ws->base == NULL) { 281 rte_free(ws); 282 ssovf_log_err("Failed to get hws base addr port=%d", port_id); 283 return -EINVAL; 284 } 285 286 reg_off = SSOW_VHWS_OP_GET_WORK0; 287 reg_off |= 1 << 4; /* Index_ggrp_mask (Use maskset zero) */ 288 reg_off |= 1 << 16; /* Wait */ 289 ws->getwork = ws->base + reg_off; 290 ws->port = port_id; 291 292 for (q = 0; q < edev->nb_event_queues; q++) { 293 ws->grps[q] = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, q, 2); 294 if (ws->grps[q] == NULL) { 295 rte_free(ws); 296 ssovf_log_err("Failed to get grp%d base addr", q); 297 return -EINVAL; 298 } 299 } 300 301 dev->data->ports[port_id] = ws; 302 ssovf_log_dbg("port=%d ws=%p", port_id, ws); 303 return 0; 304 } 305 306 static int 307 ssovf_port_link(struct rte_eventdev *dev, void *port, const uint8_t queues[], 308 const uint8_t priorities[], uint16_t nb_links) 309 { 310 uint16_t link; 311 uint64_t val; 312 struct ssows *ws = port; 313 314 ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_links); 315 RTE_SET_USED(dev); 316 RTE_SET_USED(priorities); 317 318 for (link = 0; link < nb_links; link++) { 319 val = queues[link]; 320 val |= (1ULL << 24); /* Set membership */ 321 ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0)); 322 } 323 return (int)nb_links; 324 } 325 326 static int 327 ssovf_port_unlink(struct rte_eventdev *dev, void *port, uint8_t queues[], 328 uint16_t nb_unlinks) 329 { 330 uint16_t unlink; 331 uint64_t val; 332 struct ssows *ws = port; 333 334 ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_unlinks); 335 RTE_SET_USED(dev); 336 337 for (unlink = 0; unlink < nb_unlinks; unlink++) { 338 val = queues[unlink]; 339 val &= ~(1ULL << 24); /* Clear membership */ 340 ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0)); 341 } 342 return (int)nb_unlinks; 343 } 344 345 static int 346 ssovf_timeout_ticks(struct rte_eventdev *dev, uint64_t ns, uint64_t *tmo_ticks) 347 { 348 RTE_SET_USED(dev); 349 350 return ssovf_mbox_timeout_ticks(ns, tmo_ticks); 351 } 352 353 static void 354 ssows_dump(struct ssows *ws, FILE *f) 355 { 356 uint8_t *base = ws->base; 357 uint64_t val; 358 359 fprintf(f, "\t---------------port%d---------------\n", ws->port); 360 val = ssovf_read64(base + SSOW_VHWS_TAG); 361 fprintf(f, "\ttag=0x%x tt=%d head=%d tail=%d grp=%d index=%d tail=%d\n", 362 (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3, 363 (int)(val >> 34) & 0x1, (int)(val >> 35) & 0x1, 364 (int)(val >> 36) & 0x3ff, (int)(val >> 48) & 0x3ff, 365 (int)(val >> 63) & 0x1); 366 367 val = ssovf_read64(base + SSOW_VHWS_WQP); 368 fprintf(f, "\twqp=0x%"PRIx64"\n", val); 369 370 val = ssovf_read64(base + SSOW_VHWS_LINKS); 371 fprintf(f, "\tindex=%d valid=%d revlink=%d tail=%d head=%d grp=%d\n", 372 (int)(val & 0x3ff), (int)(val >> 10) & 0x1, 373 (int)(val >> 11) & 0x3ff, (int)(val >> 26) & 0x1, 374 (int)(val >> 27) & 0x1, (int)(val >> 28) & 0x3ff); 375 376 val = ssovf_read64(base + SSOW_VHWS_PENDTAG); 377 fprintf(f, "\tptag=0x%x ptt=%d pgwi=%d pdesc=%d pgw=%d pgww=%d ps=%d\n", 378 (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3, 379 (int)(val >> 56) & 0x1, (int)(val >> 58) & 0x1, 380 (int)(val >> 61) & 0x1, (int)(val >> 62) & 0x1, 381 (int)(val >> 63) & 0x1); 382 383 val = ssovf_read64(base + SSOW_VHWS_PENDWQP); 384 fprintf(f, "\tpwqp=0x%"PRIx64"\n", val); 385 } 386 387 static int 388 ssovf_eth_rx_adapter_caps_get(const struct rte_eventdev *dev, 389 const struct rte_eth_dev *eth_dev, uint32_t *caps) 390 { 391 int ret; 392 RTE_SET_USED(dev); 393 394 ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 395 if (ret) 396 *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP; 397 else 398 *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT; 399 400 return 0; 401 } 402 403 static int 404 ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev, 405 const struct rte_eth_dev *eth_dev, int32_t rx_queue_id, 406 const struct rte_event_eth_rx_adapter_queue_conf *queue_conf) 407 { 408 int ret = 0; 409 const struct octeontx_nic *nic = eth_dev->data->dev_private; 410 pki_mod_qos_t pki_qos; 411 RTE_SET_USED(dev); 412 413 ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 414 if (ret) 415 return -EINVAL; 416 417 if (rx_queue_id >= 0) 418 return -EINVAL; 419 420 if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL) 421 return -ENOTSUP; 422 423 memset(&pki_qos, 0, sizeof(pki_mod_qos_t)); 424 425 pki_qos.port_type = 0; 426 pki_qos.index = 0; 427 pki_qos.mmask.f_tag_type = 1; 428 pki_qos.mmask.f_port_add = 1; 429 pki_qos.mmask.f_grp_ok = 1; 430 pki_qos.mmask.f_grp_bad = 1; 431 pki_qos.mmask.f_grptag_ok = 1; 432 pki_qos.mmask.f_grptag_bad = 1; 433 434 pki_qos.tag_type = queue_conf->ev.sched_type; 435 pki_qos.qos_entry.port_add = 0; 436 pki_qos.qos_entry.ggrp_ok = queue_conf->ev.queue_id; 437 pki_qos.qos_entry.ggrp_bad = queue_conf->ev.queue_id; 438 pki_qos.qos_entry.grptag_bad = 0; 439 pki_qos.qos_entry.grptag_ok = 0; 440 441 ret = octeontx_pki_port_modify_qos(nic->port_id, &pki_qos); 442 if (ret < 0) 443 ssovf_log_err("failed to modify QOS, port=%d, q=%d", 444 nic->port_id, queue_conf->ev.queue_id); 445 446 return ret; 447 } 448 449 static int 450 ssovf_eth_rx_adapter_queue_del(const struct rte_eventdev *dev, 451 const struct rte_eth_dev *eth_dev, int32_t rx_queue_id) 452 { 453 int ret = 0; 454 const struct octeontx_nic *nic = eth_dev->data->dev_private; 455 pki_del_qos_t pki_qos; 456 RTE_SET_USED(dev); 457 RTE_SET_USED(rx_queue_id); 458 459 ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 460 if (ret) 461 return -EINVAL; 462 463 pki_qos.port_type = 0; 464 pki_qos.index = 0; 465 memset(&pki_qos, 0, sizeof(pki_del_qos_t)); 466 ret = octeontx_pki_port_delete_qos(nic->port_id, &pki_qos); 467 if (ret < 0) 468 ssovf_log_err("Failed to delete QOS port=%d, q=%d", 469 nic->port_id, queue_conf->ev.queue_id); 470 return ret; 471 } 472 473 static int 474 ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev, 475 const struct rte_eth_dev *eth_dev) 476 { 477 int ret; 478 const struct octeontx_nic *nic = eth_dev->data->dev_private; 479 RTE_SET_USED(dev); 480 481 ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 482 if (ret) 483 return 0; 484 octeontx_pki_port_start(nic->port_id); 485 return 0; 486 } 487 488 489 static int 490 ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev, 491 const struct rte_eth_dev *eth_dev) 492 { 493 int ret; 494 const struct octeontx_nic *nic = eth_dev->data->dev_private; 495 RTE_SET_USED(dev); 496 497 ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 498 if (ret) 499 return 0; 500 octeontx_pki_port_stop(nic->port_id); 501 return 0; 502 } 503 504 static void 505 ssovf_dump(struct rte_eventdev *dev, FILE *f) 506 { 507 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 508 uint8_t port; 509 510 /* Dump SSOWVF debug registers */ 511 for (port = 0; port < edev->nb_event_ports; port++) 512 ssows_dump(dev->data->ports[port], f); 513 } 514 515 static int 516 ssovf_start(struct rte_eventdev *dev) 517 { 518 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 519 struct ssows *ws; 520 uint8_t *base; 521 uint8_t i; 522 523 ssovf_func_trace(); 524 for (i = 0; i < edev->nb_event_ports; i++) { 525 ws = dev->data->ports[i]; 526 ssows_reset(ws); 527 ws->swtag_req = 0; 528 } 529 530 for (i = 0; i < edev->nb_event_queues; i++) { 531 /* Consume all the events through HWS0 */ 532 ssows_flush_events(dev->data->ports[0], i); 533 534 base = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); 535 base += SSO_VHGRP_QCTL; 536 ssovf_write64(1, base); /* Enable SSO group */ 537 } 538 539 ssovf_fastpath_fns_set(dev); 540 return 0; 541 } 542 543 static void 544 ssovf_stop(struct rte_eventdev *dev) 545 { 546 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 547 struct ssows *ws; 548 uint8_t *base; 549 uint8_t i; 550 551 ssovf_func_trace(); 552 for (i = 0; i < edev->nb_event_ports; i++) { 553 ws = dev->data->ports[i]; 554 ssows_reset(ws); 555 ws->swtag_req = 0; 556 } 557 558 for (i = 0; i < edev->nb_event_queues; i++) { 559 /* Consume all the events through HWS0 */ 560 ssows_flush_events(dev->data->ports[0], i); 561 562 base = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); 563 base += SSO_VHGRP_QCTL; 564 ssovf_write64(0, base); /* Disable SSO group */ 565 } 566 } 567 568 static int 569 ssovf_close(struct rte_eventdev *dev) 570 { 571 struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 572 uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; 573 uint8_t i; 574 575 for (i = 0; i < edev->nb_event_queues; i++) 576 all_queues[i] = i; 577 578 for (i = 0; i < edev->nb_event_ports; i++) 579 ssovf_port_unlink(dev, dev->data->ports[i], all_queues, 580 edev->nb_event_queues); 581 return 0; 582 } 583 584 static int 585 ssovf_selftest(const char *key __rte_unused, const char *value, 586 void *opaque) 587 { 588 int *flag = opaque; 589 *flag = !!atoi(value); 590 return 0; 591 } 592 593 /* Initialize and register event driver with DPDK Application */ 594 static const struct rte_eventdev_ops ssovf_ops = { 595 .dev_infos_get = ssovf_info_get, 596 .dev_configure = ssovf_configure, 597 .queue_def_conf = ssovf_queue_def_conf, 598 .queue_setup = ssovf_queue_setup, 599 .queue_release = ssovf_queue_release, 600 .port_def_conf = ssovf_port_def_conf, 601 .port_setup = ssovf_port_setup, 602 .port_release = ssovf_port_release, 603 .port_link = ssovf_port_link, 604 .port_unlink = ssovf_port_unlink, 605 .timeout_ticks = ssovf_timeout_ticks, 606 607 .eth_rx_adapter_caps_get = ssovf_eth_rx_adapter_caps_get, 608 .eth_rx_adapter_queue_add = ssovf_eth_rx_adapter_queue_add, 609 .eth_rx_adapter_queue_del = ssovf_eth_rx_adapter_queue_del, 610 .eth_rx_adapter_start = ssovf_eth_rx_adapter_start, 611 .eth_rx_adapter_stop = ssovf_eth_rx_adapter_stop, 612 613 .dev_selftest = test_eventdev_octeontx, 614 615 .dump = ssovf_dump, 616 .dev_start = ssovf_start, 617 .dev_stop = ssovf_stop, 618 .dev_close = ssovf_close 619 }; 620 621 static int 622 ssovf_vdev_probe(struct rte_vdev_device *vdev) 623 { 624 struct octeontx_ssovf_info oinfo; 625 struct ssovf_mbox_dev_info info; 626 struct ssovf_evdev *edev; 627 struct rte_eventdev *eventdev; 628 static int ssovf_init_once; 629 const char *name; 630 const char *params; 631 int ret; 632 int selftest = 0; 633 634 static const char *const args[] = { 635 SSOVF_SELFTEST_ARG, 636 NULL 637 }; 638 639 name = rte_vdev_device_name(vdev); 640 /* More than one instance is not supported */ 641 if (ssovf_init_once) { 642 ssovf_log_err("Request to create >1 %s instance", name); 643 return -EINVAL; 644 } 645 646 params = rte_vdev_device_args(vdev); 647 if (params != NULL && params[0] != '\0') { 648 struct rte_kvargs *kvlist = rte_kvargs_parse(params, args); 649 650 if (!kvlist) { 651 ssovf_log_info( 652 "Ignoring unsupported params supplied '%s'", 653 name); 654 } else { 655 int ret = rte_kvargs_process(kvlist, 656 SSOVF_SELFTEST_ARG, 657 ssovf_selftest, &selftest); 658 if (ret != 0) { 659 ssovf_log_err("%s: Error in selftest", name); 660 rte_kvargs_free(kvlist); 661 return ret; 662 } 663 } 664 665 rte_kvargs_free(kvlist); 666 } 667 668 eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev), 669 rte_socket_id()); 670 if (eventdev == NULL) { 671 ssovf_log_err("Failed to create eventdev vdev %s", name); 672 return -ENOMEM; 673 } 674 eventdev->dev_ops = &ssovf_ops; 675 676 /* For secondary processes, the primary has done all the work */ 677 if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 678 ssovf_fastpath_fns_set(eventdev); 679 return 0; 680 } 681 682 ret = octeontx_ssovf_info(&oinfo); 683 if (ret) { 684 ssovf_log_err("Failed to probe and validate ssovfs %d", ret); 685 goto error; 686 } 687 688 edev = ssovf_pmd_priv(eventdev); 689 edev->max_event_ports = oinfo.total_ssowvfs; 690 edev->max_event_queues = oinfo.total_ssovfs; 691 edev->is_timeout_deq = 0; 692 693 ret = ssovf_mbox_dev_info(&info); 694 if (ret < 0 || ret != sizeof(struct ssovf_mbox_dev_info)) { 695 ssovf_log_err("Failed to get mbox devinfo %d", ret); 696 goto error; 697 } 698 699 edev->min_deq_timeout_ns = info.min_deq_timeout_ns; 700 edev->max_deq_timeout_ns = info.max_deq_timeout_ns; 701 edev->max_num_events = info.max_num_events; 702 ssovf_log_dbg("min_deq_tmo=%"PRId64" max_deq_tmo=%"PRId64" max_evts=%d", 703 info.min_deq_timeout_ns, info.max_deq_timeout_ns, 704 info.max_num_events); 705 706 if (!edev->max_event_ports || !edev->max_event_queues) { 707 ssovf_log_err("Not enough eventdev resource queues=%d ports=%d", 708 edev->max_event_queues, edev->max_event_ports); 709 ret = -ENODEV; 710 goto error; 711 } 712 713 ssovf_log_info("Initializing %s domain=%d max_queues=%d max_ports=%d", 714 name, oinfo.domain, edev->max_event_queues, 715 edev->max_event_ports); 716 717 ssovf_init_once = 1; 718 if (selftest) 719 test_eventdev_octeontx(); 720 return 0; 721 722 error: 723 rte_event_pmd_vdev_uninit(name); 724 return ret; 725 } 726 727 static int 728 ssovf_vdev_remove(struct rte_vdev_device *vdev) 729 { 730 const char *name; 731 732 name = rte_vdev_device_name(vdev); 733 ssovf_log_info("Closing %s", name); 734 return rte_event_pmd_vdev_uninit(name); 735 } 736 737 static struct rte_vdev_driver vdev_ssovf_pmd = { 738 .probe = ssovf_vdev_probe, 739 .remove = ssovf_vdev_remove 740 }; 741 742 RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_OCTEONTX_PMD, vdev_ssovf_pmd); 743