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