1aaf4363eSJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause 2aaf4363eSJerin Jacob * Copyright(c) 2017 Cavium, Inc 334498de6SJerin Jacob */ 434498de6SJerin Jacob 5b1b3d9f9SJerin Jacob #include <inttypes.h> 672b452c5SDmitry Kozlyuk #include <stdlib.h> 7b1b3d9f9SJerin Jacob 834498de6SJerin Jacob #include <rte_common.h> 992cb1309SAkhil Goyal #include <cryptodev_pmd.h> 1034498de6SJerin Jacob #include <rte_debug.h> 111acb7f54SDavid Marchand #include <dev_driver.h> 1234498de6SJerin Jacob #include <rte_eal.h> 13df96fd0dSBruce Richardson #include <ethdev_driver.h> 1445a914c5SPavan Nikhilesh #include <rte_event_eth_rx_adapter.h> 153516327eSPavan Nikhilesh #include <rte_kvargs.h> 1634498de6SJerin Jacob #include <rte_lcore.h> 1734498de6SJerin Jacob #include <rte_log.h> 1834498de6SJerin Jacob #include <rte_malloc.h> 1934498de6SJerin Jacob #include <rte_memory.h> 204851ef2bSDavid Marchand #include <bus_vdev_driver.h> 2134498de6SJerin Jacob 2234498de6SJerin Jacob #include "ssovf_evdev.h" 23f874c1ebSPavan Nikhilesh #include "timvf_evdev.h" 248dc6c2f1SShijith Thotton #include "otx_cryptodev_hw_access.h" 2534498de6SJerin Jacob 26d1925c87SPavan Nikhilesh static uint8_t timvf_enable_stats; 276ff17178SPavan Nikhilesh 28eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(otx_logtype_ssovf, NOTICE); 296ff17178SPavan Nikhilesh 3034498de6SJerin Jacob /* SSOPF Mailbox messages */ 3134498de6SJerin Jacob 3234498de6SJerin Jacob struct ssovf_mbox_dev_info { 3334498de6SJerin Jacob uint64_t min_deq_timeout_ns; 3434498de6SJerin Jacob uint64_t max_deq_timeout_ns; 3534498de6SJerin Jacob uint32_t max_num_events; 3634498de6SJerin Jacob }; 3734498de6SJerin Jacob 3834498de6SJerin Jacob static int 3934498de6SJerin Jacob ssovf_mbox_dev_info(struct ssovf_mbox_dev_info *info) 4034498de6SJerin Jacob { 4134498de6SJerin Jacob struct octeontx_mbox_hdr hdr = {0}; 4234498de6SJerin Jacob uint16_t len = sizeof(struct ssovf_mbox_dev_info); 4334498de6SJerin Jacob 4434498de6SJerin Jacob hdr.coproc = SSO_COPROC; 4534498de6SJerin Jacob hdr.msg = SSO_GET_DEV_INFO; 4634498de6SJerin Jacob hdr.vfid = 0; 4734498de6SJerin Jacob 4834498de6SJerin Jacob memset(info, 0, len); 49d8dd3165SPavan Nikhilesh return octeontx_mbox_send(&hdr, NULL, 0, info, len); 5034498de6SJerin Jacob } 5134498de6SJerin Jacob 52f14b5ac2SJerin Jacob struct ssovf_mbox_getwork_wait { 53f14b5ac2SJerin Jacob uint64_t wait_ns; 54f14b5ac2SJerin Jacob }; 55f14b5ac2SJerin Jacob 56f14b5ac2SJerin Jacob static int 57f14b5ac2SJerin Jacob ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns) 58f14b5ac2SJerin Jacob { 59f14b5ac2SJerin Jacob struct octeontx_mbox_hdr hdr = {0}; 60f14b5ac2SJerin Jacob struct ssovf_mbox_getwork_wait tmo_set; 61f14b5ac2SJerin Jacob uint16_t len = sizeof(struct ssovf_mbox_getwork_wait); 62f14b5ac2SJerin Jacob int ret; 63f14b5ac2SJerin Jacob 64f14b5ac2SJerin Jacob hdr.coproc = SSO_COPROC; 65f14b5ac2SJerin Jacob hdr.msg = SSO_SET_GETWORK_WAIT; 66f14b5ac2SJerin Jacob hdr.vfid = 0; 67f14b5ac2SJerin Jacob 68f14b5ac2SJerin Jacob tmo_set.wait_ns = timeout_ns; 69d8dd3165SPavan Nikhilesh ret = octeontx_mbox_send(&hdr, &tmo_set, len, NULL, 0); 70f14b5ac2SJerin Jacob if (ret) 71f14b5ac2SJerin Jacob ssovf_log_err("Failed to set getwork timeout(%d)", ret); 72f14b5ac2SJerin Jacob 73f14b5ac2SJerin Jacob return ret; 74f14b5ac2SJerin Jacob } 75f14b5ac2SJerin Jacob 76d44a26ffSJerin Jacob struct ssovf_mbox_grp_pri { 77b4134b2dSPavan Nikhilesh uint8_t vhgrp_id; 78d44a26ffSJerin Jacob uint8_t wgt_left; /* Read only */ 79d44a26ffSJerin Jacob uint8_t weight; 80d44a26ffSJerin Jacob uint8_t affinity; 81d44a26ffSJerin Jacob uint8_t priority; 82d44a26ffSJerin Jacob }; 83d44a26ffSJerin Jacob 84d44a26ffSJerin Jacob static int 85d44a26ffSJerin Jacob ssovf_mbox_priority_set(uint8_t queue, uint8_t prio) 86d44a26ffSJerin Jacob { 87d44a26ffSJerin Jacob struct octeontx_mbox_hdr hdr = {0}; 88d44a26ffSJerin Jacob struct ssovf_mbox_grp_pri grp; 89d44a26ffSJerin Jacob uint16_t len = sizeof(struct ssovf_mbox_grp_pri); 90d44a26ffSJerin Jacob int ret; 91d44a26ffSJerin Jacob 92d44a26ffSJerin Jacob hdr.coproc = SSO_COPROC; 93d44a26ffSJerin Jacob hdr.msg = SSO_GRP_SET_PRIORITY; 94d44a26ffSJerin Jacob hdr.vfid = queue; 95d44a26ffSJerin Jacob 96b4134b2dSPavan Nikhilesh grp.vhgrp_id = queue; 97d44a26ffSJerin Jacob grp.weight = 0xff; 98d44a26ffSJerin Jacob grp.affinity = 0xff; 99d44a26ffSJerin Jacob grp.priority = prio / 32; /* Normalize to 0 to 7 */ 100d44a26ffSJerin Jacob 101d8dd3165SPavan Nikhilesh ret = octeontx_mbox_send(&hdr, &grp, len, NULL, 0); 102d44a26ffSJerin Jacob if (ret) 103d44a26ffSJerin Jacob ssovf_log_err("Failed to set grp=%d prio=%d", queue, prio); 104d44a26ffSJerin Jacob 105d44a26ffSJerin Jacob return ret; 106d44a26ffSJerin Jacob } 107d44a26ffSJerin Jacob 108613c7027SJerin Jacob struct ssovf_mbox_convert_ns_getworks_iter { 109613c7027SJerin Jacob uint64_t wait_ns; 110613c7027SJerin Jacob uint32_t getwork_iter;/* Get_work iterations for the given wait_ns */ 111613c7027SJerin Jacob }; 112613c7027SJerin Jacob 113613c7027SJerin Jacob static int 114613c7027SJerin Jacob ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks) 115613c7027SJerin Jacob { 116613c7027SJerin Jacob struct octeontx_mbox_hdr hdr = {0}; 117613c7027SJerin Jacob struct ssovf_mbox_convert_ns_getworks_iter ns2iter; 118613c7027SJerin Jacob uint16_t len = sizeof(ns2iter); 119613c7027SJerin Jacob int ret; 120613c7027SJerin Jacob 121613c7027SJerin Jacob hdr.coproc = SSO_COPROC; 122613c7027SJerin Jacob hdr.msg = SSO_CONVERT_NS_GETWORK_ITER; 123613c7027SJerin Jacob hdr.vfid = 0; 124613c7027SJerin Jacob 125613c7027SJerin Jacob memset(&ns2iter, 0, len); 126613c7027SJerin Jacob ns2iter.wait_ns = ns; 127d8dd3165SPavan Nikhilesh ret = octeontx_mbox_send(&hdr, &ns2iter, len, &ns2iter, len); 128613c7027SJerin Jacob if (ret < 0 || (ret != len)) { 129613c7027SJerin Jacob ssovf_log_err("Failed to get tmo ticks ns=%"PRId64"", ns); 130613c7027SJerin Jacob return -EIO; 131613c7027SJerin Jacob } 132613c7027SJerin Jacob 133613c7027SJerin Jacob *tmo_ticks = ns2iter.getwork_iter; 134613c7027SJerin Jacob return 0; 135613c7027SJerin Jacob } 136613c7027SJerin Jacob 1378b3808caSJerin Jacob static void 1388b3808caSJerin Jacob ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info) 1398b3808caSJerin Jacob { 1408b3808caSJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 1418b3808caSJerin Jacob 1420d9b31bfSJerin Jacob dev_info->driver_name = RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD); 1438b3808caSJerin Jacob dev_info->min_dequeue_timeout_ns = edev->min_deq_timeout_ns; 1448b3808caSJerin Jacob dev_info->max_dequeue_timeout_ns = edev->max_deq_timeout_ns; 1458b3808caSJerin Jacob dev_info->max_event_queues = edev->max_event_queues; 1468b3808caSJerin Jacob dev_info->max_event_queue_flows = (1ULL << 20); 1478b3808caSJerin Jacob dev_info->max_event_queue_priority_levels = 8; 1488b3808caSJerin Jacob dev_info->max_event_priority_levels = 1; 1498b3808caSJerin Jacob dev_info->max_event_ports = edev->max_event_ports; 1508b3808caSJerin Jacob dev_info->max_event_port_dequeue_depth = 1; 1518b3808caSJerin Jacob dev_info->max_event_port_enqueue_depth = 1; 1528b3808caSJerin Jacob dev_info->max_num_events = edev->max_num_events; 1538b3808caSJerin Jacob dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_QUEUE_QOS | 15468a92affSBruce Richardson RTE_EVENT_DEV_CAP_ATOMIC | 15568a92affSBruce Richardson RTE_EVENT_DEV_CAP_ORDERED | 15668a92affSBruce Richardson RTE_EVENT_DEV_CAP_PARALLEL | 1578b3808caSJerin Jacob RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED | 15883017147SLiang Ma RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES| 15983017147SLiang Ma RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK | 16083017147SLiang Ma RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT | 16175d11313STimothy McDaniel RTE_EVENT_DEV_CAP_NONSEQ_MODE | 162bd991897SMattias Rönnblom RTE_EVENT_DEV_CAP_CARRY_FLOW_ID | 163bd991897SMattias Rönnblom RTE_EVENT_DEV_CAP_MAINTENANCE_FREE; 164d007a7f3SPavan Nikhilesh dev_info->max_profiles_per_port = 1; 1658b3808caSJerin Jacob } 1668b3808caSJerin Jacob 167f14b5ac2SJerin Jacob static int 168f14b5ac2SJerin Jacob ssovf_configure(const struct rte_eventdev *dev) 169f14b5ac2SJerin Jacob { 170f14b5ac2SJerin Jacob struct rte_event_dev_config *conf = &dev->data->dev_conf; 171f14b5ac2SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 172f14b5ac2SJerin Jacob uint64_t deq_tmo_ns; 173f14b5ac2SJerin Jacob 174f14b5ac2SJerin Jacob ssovf_func_trace(); 175f14b5ac2SJerin Jacob deq_tmo_ns = conf->dequeue_timeout_ns; 17641218a9dSJerin Jacob if (deq_tmo_ns == 0) 17741218a9dSJerin Jacob deq_tmo_ns = edev->min_deq_timeout_ns; 178f14b5ac2SJerin Jacob 179f14b5ac2SJerin Jacob if (conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT) { 180f14b5ac2SJerin Jacob edev->is_timeout_deq = 1; 181f14b5ac2SJerin Jacob deq_tmo_ns = edev->min_deq_timeout_ns; 182f14b5ac2SJerin Jacob } 183f14b5ac2SJerin Jacob edev->nb_event_queues = conf->nb_event_queues; 184f14b5ac2SJerin Jacob edev->nb_event_ports = conf->nb_event_ports; 185f14b5ac2SJerin Jacob 186f14b5ac2SJerin Jacob return ssovf_mbox_getwork_tmo_set(deq_tmo_ns); 187f14b5ac2SJerin Jacob } 1888b3808caSJerin Jacob 189d44a26ffSJerin Jacob static void 190d44a26ffSJerin Jacob ssovf_queue_def_conf(struct rte_eventdev *dev, uint8_t queue_id, 191d44a26ffSJerin Jacob struct rte_event_queue_conf *queue_conf) 192d44a26ffSJerin Jacob { 193d44a26ffSJerin Jacob RTE_SET_USED(dev); 194d44a26ffSJerin Jacob RTE_SET_USED(queue_id); 195d44a26ffSJerin Jacob 196d44a26ffSJerin Jacob queue_conf->nb_atomic_flows = (1ULL << 20); 197d44a26ffSJerin Jacob queue_conf->nb_atomic_order_sequences = (1ULL << 20); 198d44a26ffSJerin Jacob queue_conf->event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES; 199d44a26ffSJerin Jacob queue_conf->priority = RTE_EVENT_DEV_PRIORITY_NORMAL; 200d44a26ffSJerin Jacob } 201d44a26ffSJerin Jacob 202d44a26ffSJerin Jacob static void 203d44a26ffSJerin Jacob ssovf_queue_release(struct rte_eventdev *dev, uint8_t queue_id) 204d44a26ffSJerin Jacob { 205d44a26ffSJerin Jacob RTE_SET_USED(dev); 206d44a26ffSJerin Jacob RTE_SET_USED(queue_id); 207d44a26ffSJerin Jacob } 208d44a26ffSJerin Jacob 209d44a26ffSJerin Jacob static int 210d44a26ffSJerin Jacob ssovf_queue_setup(struct rte_eventdev *dev, uint8_t queue_id, 211d44a26ffSJerin Jacob const struct rte_event_queue_conf *queue_conf) 212d44a26ffSJerin Jacob { 213d44a26ffSJerin Jacob RTE_SET_USED(dev); 214d44a26ffSJerin Jacob ssovf_func_trace("queue=%d prio=%d", queue_id, queue_conf->priority); 215d44a26ffSJerin Jacob 216d44a26ffSJerin Jacob return ssovf_mbox_priority_set(queue_id, queue_conf->priority); 217d44a26ffSJerin Jacob } 218d44a26ffSJerin Jacob 219708bac97SJerin Jacob static void 220708bac97SJerin Jacob ssovf_port_def_conf(struct rte_eventdev *dev, uint8_t port_id, 221708bac97SJerin Jacob struct rte_event_port_conf *port_conf) 222708bac97SJerin Jacob { 223708bac97SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 224708bac97SJerin Jacob 225708bac97SJerin Jacob RTE_SET_USED(port_id); 226708bac97SJerin Jacob port_conf->new_event_threshold = edev->max_num_events; 227708bac97SJerin Jacob port_conf->dequeue_depth = 1; 228708bac97SJerin Jacob port_conf->enqueue_depth = 1; 22975d11313STimothy McDaniel port_conf->event_port_cfg = 0; 230708bac97SJerin Jacob } 231708bac97SJerin Jacob 232708bac97SJerin Jacob static void 233708bac97SJerin Jacob ssovf_port_release(void *port) 234708bac97SJerin Jacob { 235708bac97SJerin Jacob rte_free(port); 236708bac97SJerin Jacob } 237708bac97SJerin Jacob 238708bac97SJerin Jacob static int 239708bac97SJerin Jacob ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id, 240708bac97SJerin Jacob const struct rte_event_port_conf *port_conf) 241708bac97SJerin Jacob { 242708bac97SJerin Jacob struct ssows *ws; 243708bac97SJerin Jacob uint32_t reg_off; 244708bac97SJerin Jacob uint8_t q; 245708bac97SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 246708bac97SJerin Jacob 247708bac97SJerin Jacob ssovf_func_trace("port=%d", port_id); 248708bac97SJerin Jacob RTE_SET_USED(port_conf); 249708bac97SJerin Jacob 250708bac97SJerin Jacob /* Free memory prior to re-allocation if needed */ 251708bac97SJerin Jacob if (dev->data->ports[port_id] != NULL) { 252708bac97SJerin Jacob ssovf_port_release(dev->data->ports[port_id]); 253708bac97SJerin Jacob dev->data->ports[port_id] = NULL; 254708bac97SJerin Jacob } 255708bac97SJerin Jacob 256708bac97SJerin Jacob /* Allocate event port memory */ 257708bac97SJerin Jacob ws = rte_zmalloc_socket("eventdev ssows", 258708bac97SJerin Jacob sizeof(struct ssows), RTE_CACHE_LINE_SIZE, 259708bac97SJerin Jacob dev->data->socket_id); 260708bac97SJerin Jacob if (ws == NULL) { 261708bac97SJerin Jacob ssovf_log_err("Failed to alloc memory for port=%d", port_id); 262708bac97SJerin Jacob return -ENOMEM; 263708bac97SJerin Jacob } 264708bac97SJerin Jacob 265d8dd3165SPavan Nikhilesh ws->base = ssovf_bar(OCTEONTX_SSO_HWS, port_id, 0); 266708bac97SJerin Jacob if (ws->base == NULL) { 267708bac97SJerin Jacob rte_free(ws); 268708bac97SJerin Jacob ssovf_log_err("Failed to get hws base addr port=%d", port_id); 269708bac97SJerin Jacob return -EINVAL; 270708bac97SJerin Jacob } 271708bac97SJerin Jacob 272708bac97SJerin Jacob reg_off = SSOW_VHWS_OP_GET_WORK0; 273708bac97SJerin Jacob reg_off |= 1 << 4; /* Index_ggrp_mask (Use maskset zero) */ 274708bac97SJerin Jacob reg_off |= 1 << 16; /* Wait */ 275708bac97SJerin Jacob ws->getwork = ws->base + reg_off; 276708bac97SJerin Jacob ws->port = port_id; 277cf55f04aSHarman Kalra ws->lookup_mem = octeontx_fastpath_lookup_mem_get(); 278708bac97SJerin Jacob 279708bac97SJerin Jacob for (q = 0; q < edev->nb_event_queues; q++) { 280d8dd3165SPavan Nikhilesh ws->grps[q] = ssovf_bar(OCTEONTX_SSO_GROUP, q, 2); 281708bac97SJerin Jacob if (ws->grps[q] == NULL) { 282708bac97SJerin Jacob rte_free(ws); 283708bac97SJerin Jacob ssovf_log_err("Failed to get grp%d base addr", q); 284708bac97SJerin Jacob return -EINVAL; 285708bac97SJerin Jacob } 286708bac97SJerin Jacob } 287708bac97SJerin Jacob 288708bac97SJerin Jacob dev->data->ports[port_id] = ws; 289708bac97SJerin Jacob ssovf_log_dbg("port=%d ws=%p", port_id, ws); 290708bac97SJerin Jacob return 0; 291708bac97SJerin Jacob } 29235a228acSJerin Jacob 29335a228acSJerin Jacob static int 29435a228acSJerin Jacob ssovf_port_link(struct rte_eventdev *dev, void *port, const uint8_t queues[], 29535a228acSJerin Jacob const uint8_t priorities[], uint16_t nb_links) 29635a228acSJerin Jacob { 29735a228acSJerin Jacob uint16_t link; 29835a228acSJerin Jacob uint64_t val; 29935a228acSJerin Jacob struct ssows *ws = port; 30035a228acSJerin Jacob 30135a228acSJerin Jacob ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_links); 30235a228acSJerin Jacob RTE_SET_USED(dev); 30335a228acSJerin Jacob RTE_SET_USED(priorities); 30435a228acSJerin Jacob 30535a228acSJerin Jacob for (link = 0; link < nb_links; link++) { 30635a228acSJerin Jacob val = queues[link]; 30735a228acSJerin Jacob val |= (1ULL << 24); /* Set membership */ 30835a228acSJerin Jacob ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0)); 30935a228acSJerin Jacob } 31035a228acSJerin Jacob return (int)nb_links; 31135a228acSJerin Jacob } 31235a228acSJerin Jacob 31335a228acSJerin Jacob static int 31435a228acSJerin Jacob ssovf_port_unlink(struct rte_eventdev *dev, void *port, uint8_t queues[], 31535a228acSJerin Jacob uint16_t nb_unlinks) 31635a228acSJerin Jacob { 31735a228acSJerin Jacob uint16_t unlink; 31835a228acSJerin Jacob uint64_t val; 31935a228acSJerin Jacob struct ssows *ws = port; 32035a228acSJerin Jacob 32135a228acSJerin Jacob ssovf_func_trace("port=%d nb_links=%d", ws->port, nb_unlinks); 32235a228acSJerin Jacob RTE_SET_USED(dev); 32335a228acSJerin Jacob 32435a228acSJerin Jacob for (unlink = 0; unlink < nb_unlinks; unlink++) { 32535a228acSJerin Jacob val = queues[unlink]; 32635a228acSJerin Jacob val &= ~(1ULL << 24); /* Clear membership */ 32735a228acSJerin Jacob ssovf_write64(val, ws->base + SSOW_VHWS_GRPMSK_CHGX(0)); 32835a228acSJerin Jacob } 32935a228acSJerin Jacob return (int)nb_unlinks; 33035a228acSJerin Jacob } 33135a228acSJerin Jacob 332613c7027SJerin Jacob static int 333613c7027SJerin Jacob ssovf_timeout_ticks(struct rte_eventdev *dev, uint64_t ns, uint64_t *tmo_ticks) 334613c7027SJerin Jacob { 335613c7027SJerin Jacob RTE_SET_USED(dev); 336613c7027SJerin Jacob 337613c7027SJerin Jacob return ssovf_mbox_timeout_ticks(ns, tmo_ticks); 338613c7027SJerin Jacob } 339613c7027SJerin Jacob 340558413c0SJerin Jacob static void 341558413c0SJerin Jacob ssows_dump(struct ssows *ws, FILE *f) 342558413c0SJerin Jacob { 343558413c0SJerin Jacob uint8_t *base = ws->base; 344558413c0SJerin Jacob uint64_t val; 345558413c0SJerin Jacob 346558413c0SJerin Jacob fprintf(f, "\t---------------port%d---------------\n", ws->port); 347558413c0SJerin Jacob val = ssovf_read64(base + SSOW_VHWS_TAG); 348558413c0SJerin Jacob fprintf(f, "\ttag=0x%x tt=%d head=%d tail=%d grp=%d index=%d tail=%d\n", 349558413c0SJerin Jacob (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3, 350558413c0SJerin Jacob (int)(val >> 34) & 0x1, (int)(val >> 35) & 0x1, 351558413c0SJerin Jacob (int)(val >> 36) & 0x3ff, (int)(val >> 48) & 0x3ff, 352558413c0SJerin Jacob (int)(val >> 63) & 0x1); 353558413c0SJerin Jacob 354558413c0SJerin Jacob val = ssovf_read64(base + SSOW_VHWS_WQP); 355558413c0SJerin Jacob fprintf(f, "\twqp=0x%"PRIx64"\n", val); 356558413c0SJerin Jacob 357558413c0SJerin Jacob val = ssovf_read64(base + SSOW_VHWS_LINKS); 358558413c0SJerin Jacob fprintf(f, "\tindex=%d valid=%d revlink=%d tail=%d head=%d grp=%d\n", 359558413c0SJerin Jacob (int)(val & 0x3ff), (int)(val >> 10) & 0x1, 360558413c0SJerin Jacob (int)(val >> 11) & 0x3ff, (int)(val >> 26) & 0x1, 361558413c0SJerin Jacob (int)(val >> 27) & 0x1, (int)(val >> 28) & 0x3ff); 362558413c0SJerin Jacob 363558413c0SJerin Jacob val = ssovf_read64(base + SSOW_VHWS_PENDTAG); 364558413c0SJerin Jacob fprintf(f, "\tptag=0x%x ptt=%d pgwi=%d pdesc=%d pgw=%d pgww=%d ps=%d\n", 365558413c0SJerin Jacob (uint32_t)(val & 0xffffffff), (int)(val >> 32) & 0x3, 366558413c0SJerin Jacob (int)(val >> 56) & 0x1, (int)(val >> 58) & 0x1, 367558413c0SJerin Jacob (int)(val >> 61) & 0x1, (int)(val >> 62) & 0x1, 368558413c0SJerin Jacob (int)(val >> 63) & 0x1); 369558413c0SJerin Jacob 370558413c0SJerin Jacob val = ssovf_read64(base + SSOW_VHWS_PENDWQP); 371558413c0SJerin Jacob fprintf(f, "\tpwqp=0x%"PRIx64"\n", val); 372558413c0SJerin Jacob } 373558413c0SJerin Jacob 37445a914c5SPavan Nikhilesh static int 37545a914c5SPavan Nikhilesh ssovf_eth_rx_adapter_caps_get(const struct rte_eventdev *dev, 37645a914c5SPavan Nikhilesh const struct rte_eth_dev *eth_dev, uint32_t *caps) 37745a914c5SPavan Nikhilesh { 37845a914c5SPavan Nikhilesh int ret; 37945a914c5SPavan Nikhilesh RTE_SET_USED(dev); 38045a914c5SPavan Nikhilesh 38145a914c5SPavan Nikhilesh ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 38245a914c5SPavan Nikhilesh if (ret) 38345a914c5SPavan Nikhilesh *caps = RTE_EVENT_ETH_RX_ADAPTER_SW_CAP; 38445a914c5SPavan Nikhilesh else 38545a914c5SPavan Nikhilesh *caps = RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT; 38645a914c5SPavan Nikhilesh 38745a914c5SPavan Nikhilesh return 0; 38845a914c5SPavan Nikhilesh } 38945a914c5SPavan Nikhilesh 39045a914c5SPavan Nikhilesh static int 39145a914c5SPavan Nikhilesh ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev, 39245a914c5SPavan Nikhilesh const struct rte_eth_dev *eth_dev, int32_t rx_queue_id, 39345a914c5SPavan Nikhilesh const struct rte_event_eth_rx_adapter_queue_conf *queue_conf) 39445a914c5SPavan Nikhilesh { 39545a914c5SPavan Nikhilesh const struct octeontx_nic *nic = eth_dev->data->dev_private; 396844d302dSHarman Kalra struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 397227f2835SPavan Nikhilesh uint16_t free_idx = UINT16_MAX; 398227f2835SPavan Nikhilesh struct octeontx_rxq *rxq; 39945a914c5SPavan Nikhilesh pki_mod_qos_t pki_qos; 400227f2835SPavan Nikhilesh uint8_t found = false; 401227f2835SPavan Nikhilesh int i, ret = 0; 402227f2835SPavan Nikhilesh void *old_ptr; 40345a914c5SPavan Nikhilesh 40445a914c5SPavan Nikhilesh ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 40545a914c5SPavan Nikhilesh if (ret) 40645a914c5SPavan Nikhilesh return -EINVAL; 40745a914c5SPavan Nikhilesh 40845a914c5SPavan Nikhilesh if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL) 40945a914c5SPavan Nikhilesh return -ENOTSUP; 41045a914c5SPavan Nikhilesh 411227f2835SPavan Nikhilesh /* eth_octeontx only supports one rq. */ 412227f2835SPavan Nikhilesh rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id; 413227f2835SPavan Nikhilesh rxq = eth_dev->data->rx_queues[rx_queue_id]; 414227f2835SPavan Nikhilesh /* Add rxq pool to list of used pools and reduce available events. */ 415227f2835SPavan Nikhilesh for (i = 0; i < edev->rxq_pools; i++) { 416227f2835SPavan Nikhilesh if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) { 417227f2835SPavan Nikhilesh edev->rxq_pool_rcnt[i]++; 418227f2835SPavan Nikhilesh found = true; 419227f2835SPavan Nikhilesh break; 420227f2835SPavan Nikhilesh } else if (free_idx == UINT16_MAX && 421227f2835SPavan Nikhilesh edev->rxq_pool_array[i] == 0) { 422227f2835SPavan Nikhilesh free_idx = i; 423227f2835SPavan Nikhilesh } 424227f2835SPavan Nikhilesh } 425227f2835SPavan Nikhilesh 426227f2835SPavan Nikhilesh if (!found) { 427227f2835SPavan Nikhilesh uint16_t idx; 428227f2835SPavan Nikhilesh 429227f2835SPavan Nikhilesh if (edev->available_events < rxq->pool->size) { 430227f2835SPavan Nikhilesh ssovf_log_err( 431227f2835SPavan Nikhilesh "Max available events %"PRIu32" requested events in rxq pool %"PRIu32"", 432227f2835SPavan Nikhilesh edev->available_events, rxq->pool->size); 433227f2835SPavan Nikhilesh return -ENOMEM; 434227f2835SPavan Nikhilesh } 435227f2835SPavan Nikhilesh 436227f2835SPavan Nikhilesh if (free_idx != UINT16_MAX) { 437227f2835SPavan Nikhilesh idx = free_idx; 438227f2835SPavan Nikhilesh } else { 439227f2835SPavan Nikhilesh old_ptr = edev->rxq_pool_array; 440227f2835SPavan Nikhilesh edev->rxq_pools++; 441227f2835SPavan Nikhilesh edev->rxq_pool_array = rte_realloc( 442227f2835SPavan Nikhilesh edev->rxq_pool_array, 443227f2835SPavan Nikhilesh sizeof(uint64_t) * edev->rxq_pools, 0); 444227f2835SPavan Nikhilesh if (edev->rxq_pool_array == NULL) { 445227f2835SPavan Nikhilesh edev->rxq_pools--; 446227f2835SPavan Nikhilesh edev->rxq_pool_array = old_ptr; 447227f2835SPavan Nikhilesh return -ENOMEM; 448227f2835SPavan Nikhilesh } 449227f2835SPavan Nikhilesh 450227f2835SPavan Nikhilesh old_ptr = edev->rxq_pool_rcnt; 451227f2835SPavan Nikhilesh edev->rxq_pool_rcnt = rte_realloc( 452227f2835SPavan Nikhilesh edev->rxq_pool_rcnt, 453227f2835SPavan Nikhilesh sizeof(uint8_t) * edev->rxq_pools, 0); 454227f2835SPavan Nikhilesh if (edev->rxq_pool_rcnt == NULL) { 455227f2835SPavan Nikhilesh edev->rxq_pools--; 456227f2835SPavan Nikhilesh edev->rxq_pool_rcnt = old_ptr; 457227f2835SPavan Nikhilesh return -ENOMEM; 458227f2835SPavan Nikhilesh } 459227f2835SPavan Nikhilesh idx = edev->rxq_pools - 1; 460227f2835SPavan Nikhilesh } 461227f2835SPavan Nikhilesh 462227f2835SPavan Nikhilesh edev->rxq_pool_array[idx] = (uintptr_t)rxq->pool; 463227f2835SPavan Nikhilesh edev->rxq_pool_rcnt[idx] = 1; 464227f2835SPavan Nikhilesh edev->available_events -= rxq->pool->size; 465227f2835SPavan Nikhilesh } 466227f2835SPavan Nikhilesh 46745a914c5SPavan Nikhilesh memset(&pki_qos, 0, sizeof(pki_mod_qos_t)); 46845a914c5SPavan Nikhilesh 46945a914c5SPavan Nikhilesh pki_qos.port_type = 0; 47045a914c5SPavan Nikhilesh pki_qos.index = 0; 47145a914c5SPavan Nikhilesh pki_qos.mmask.f_tag_type = 1; 47245a914c5SPavan Nikhilesh pki_qos.mmask.f_port_add = 1; 47345a914c5SPavan Nikhilesh pki_qos.mmask.f_grp_ok = 1; 47445a914c5SPavan Nikhilesh pki_qos.mmask.f_grp_bad = 1; 47545a914c5SPavan Nikhilesh pki_qos.mmask.f_grptag_ok = 1; 47645a914c5SPavan Nikhilesh pki_qos.mmask.f_grptag_bad = 1; 47745a914c5SPavan Nikhilesh 478b4134b2dSPavan Nikhilesh pki_qos.qos_entry.tag_type = queue_conf->ev.sched_type; 47945a914c5SPavan Nikhilesh pki_qos.qos_entry.port_add = 0; 48045a914c5SPavan Nikhilesh pki_qos.qos_entry.ggrp_ok = queue_conf->ev.queue_id; 48145a914c5SPavan Nikhilesh pki_qos.qos_entry.ggrp_bad = queue_conf->ev.queue_id; 48245a914c5SPavan Nikhilesh pki_qos.qos_entry.grptag_bad = 0; 48345a914c5SPavan Nikhilesh pki_qos.qos_entry.grptag_ok = 0; 48445a914c5SPavan Nikhilesh 48545a914c5SPavan Nikhilesh ret = octeontx_pki_port_modify_qos(nic->port_id, &pki_qos); 48645a914c5SPavan Nikhilesh if (ret < 0) 48745a914c5SPavan Nikhilesh ssovf_log_err("failed to modify QOS, port=%d, q=%d", 48845a914c5SPavan Nikhilesh nic->port_id, queue_conf->ev.queue_id); 48945a914c5SPavan Nikhilesh 490844d302dSHarman Kalra edev->rx_offload_flags = nic->rx_offload_flags; 491844d302dSHarman Kalra edev->tx_offload_flags = nic->tx_offload_flags; 49245a914c5SPavan Nikhilesh return ret; 49345a914c5SPavan Nikhilesh } 49445a914c5SPavan Nikhilesh 49545a914c5SPavan Nikhilesh static int 49645a914c5SPavan Nikhilesh ssovf_eth_rx_adapter_queue_del(const struct rte_eventdev *dev, 49745a914c5SPavan Nikhilesh const struct rte_eth_dev *eth_dev, int32_t rx_queue_id) 49845a914c5SPavan Nikhilesh { 49945a914c5SPavan Nikhilesh const struct octeontx_nic *nic = eth_dev->data->dev_private; 500227f2835SPavan Nikhilesh struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 501227f2835SPavan Nikhilesh struct octeontx_rxq *rxq; 50245a914c5SPavan Nikhilesh pki_del_qos_t pki_qos; 503227f2835SPavan Nikhilesh uint8_t found = false; 504227f2835SPavan Nikhilesh int i, ret = 0; 505227f2835SPavan Nikhilesh 506227f2835SPavan Nikhilesh rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id; 507227f2835SPavan Nikhilesh rxq = eth_dev->data->rx_queues[rx_queue_id]; 508227f2835SPavan Nikhilesh for (i = 0; i < edev->rxq_pools; i++) { 509227f2835SPavan Nikhilesh if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) { 510227f2835SPavan Nikhilesh found = true; 511227f2835SPavan Nikhilesh break; 512227f2835SPavan Nikhilesh } 513227f2835SPavan Nikhilesh } 514227f2835SPavan Nikhilesh 515227f2835SPavan Nikhilesh if (found) { 516227f2835SPavan Nikhilesh edev->rxq_pool_rcnt[i]--; 517227f2835SPavan Nikhilesh if (edev->rxq_pool_rcnt[i] == 0) 518227f2835SPavan Nikhilesh edev->rxq_pool_array[i] = 0; 519227f2835SPavan Nikhilesh edev->available_events += rxq->pool->size; 520227f2835SPavan Nikhilesh } 52145a914c5SPavan Nikhilesh 52245a914c5SPavan Nikhilesh ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 52345a914c5SPavan Nikhilesh if (ret) 52445a914c5SPavan Nikhilesh return -EINVAL; 52545a914c5SPavan Nikhilesh 52645a914c5SPavan Nikhilesh pki_qos.port_type = 0; 52745a914c5SPavan Nikhilesh pki_qos.index = 0; 52845a914c5SPavan Nikhilesh memset(&pki_qos, 0, sizeof(pki_del_qos_t)); 52945a914c5SPavan Nikhilesh ret = octeontx_pki_port_delete_qos(nic->port_id, &pki_qos); 53045a914c5SPavan Nikhilesh if (ret < 0) 53145a914c5SPavan Nikhilesh ssovf_log_err("Failed to delete QOS port=%d, q=%d", 53297573583SFerruh Yigit nic->port_id, rx_queue_id); 53345a914c5SPavan Nikhilesh return ret; 53445a914c5SPavan Nikhilesh } 53545a914c5SPavan Nikhilesh 53645a914c5SPavan Nikhilesh static int 53745a914c5SPavan Nikhilesh ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev, 53845a914c5SPavan Nikhilesh const struct rte_eth_dev *eth_dev) 53945a914c5SPavan Nikhilesh { 54045a914c5SPavan Nikhilesh RTE_SET_USED(dev); 54156aa489eSPavan Nikhilesh RTE_SET_USED(eth_dev); 54245a914c5SPavan Nikhilesh 54345a914c5SPavan Nikhilesh return 0; 54445a914c5SPavan Nikhilesh } 54545a914c5SPavan Nikhilesh 54645a914c5SPavan Nikhilesh 54745a914c5SPavan Nikhilesh static int 54845a914c5SPavan Nikhilesh ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev, 54945a914c5SPavan Nikhilesh const struct rte_eth_dev *eth_dev) 55045a914c5SPavan Nikhilesh { 55145a914c5SPavan Nikhilesh RTE_SET_USED(dev); 55256aa489eSPavan Nikhilesh RTE_SET_USED(eth_dev); 55345a914c5SPavan Nikhilesh 55445a914c5SPavan Nikhilesh return 0; 55545a914c5SPavan Nikhilesh } 55645a914c5SPavan Nikhilesh 5571dedffebSPavan Nikhilesh static int 5581dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_caps_get(const struct rte_eventdev *dev, 5591dedffebSPavan Nikhilesh const struct rte_eth_dev *eth_dev, uint32_t *caps) 5601dedffebSPavan Nikhilesh { 5611dedffebSPavan Nikhilesh int ret; 5621dedffebSPavan Nikhilesh RTE_SET_USED(dev); 5631dedffebSPavan Nikhilesh 5641dedffebSPavan Nikhilesh ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); 5651dedffebSPavan Nikhilesh if (ret) 5661dedffebSPavan Nikhilesh *caps = 0; 5671dedffebSPavan Nikhilesh else 5681dedffebSPavan Nikhilesh *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT; 5691dedffebSPavan Nikhilesh 5701dedffebSPavan Nikhilesh return 0; 5711dedffebSPavan Nikhilesh } 5721dedffebSPavan Nikhilesh 5731dedffebSPavan Nikhilesh static int 5741dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_create(uint8_t id, const struct rte_eventdev *dev) 5751dedffebSPavan Nikhilesh { 5761dedffebSPavan Nikhilesh RTE_SET_USED(id); 5771dedffebSPavan Nikhilesh RTE_SET_USED(dev); 5781dedffebSPavan Nikhilesh return 0; 5791dedffebSPavan Nikhilesh } 5801dedffebSPavan Nikhilesh 5811dedffebSPavan Nikhilesh static int 5821dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_free(uint8_t id, const struct rte_eventdev *dev) 5831dedffebSPavan Nikhilesh { 5841dedffebSPavan Nikhilesh RTE_SET_USED(id); 5851dedffebSPavan Nikhilesh RTE_SET_USED(dev); 5861dedffebSPavan Nikhilesh return 0; 5871dedffebSPavan Nikhilesh } 5881dedffebSPavan Nikhilesh 5891dedffebSPavan Nikhilesh static int 5901dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *dev, 5911dedffebSPavan Nikhilesh const struct rte_eth_dev *eth_dev, int32_t tx_queue_id) 5921dedffebSPavan Nikhilesh { 5931dedffebSPavan Nikhilesh RTE_SET_USED(id); 5941dedffebSPavan Nikhilesh RTE_SET_USED(dev); 5951dedffebSPavan Nikhilesh RTE_SET_USED(eth_dev); 5961dedffebSPavan Nikhilesh RTE_SET_USED(tx_queue_id); 5971dedffebSPavan Nikhilesh return 0; 5981dedffebSPavan Nikhilesh } 5991dedffebSPavan Nikhilesh 6001dedffebSPavan Nikhilesh static int 6011dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *dev, 6021dedffebSPavan Nikhilesh const struct rte_eth_dev *eth_dev, int32_t tx_queue_id) 6031dedffebSPavan Nikhilesh { 6041dedffebSPavan Nikhilesh RTE_SET_USED(id); 6051dedffebSPavan Nikhilesh RTE_SET_USED(dev); 6061dedffebSPavan Nikhilesh RTE_SET_USED(eth_dev); 6071dedffebSPavan Nikhilesh RTE_SET_USED(tx_queue_id); 6081dedffebSPavan Nikhilesh return 0; 6091dedffebSPavan Nikhilesh } 6101dedffebSPavan Nikhilesh 6111dedffebSPavan Nikhilesh static int 6121dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_start(uint8_t id, const struct rte_eventdev *dev) 6131dedffebSPavan Nikhilesh { 6141dedffebSPavan Nikhilesh RTE_SET_USED(id); 6151dedffebSPavan Nikhilesh RTE_SET_USED(dev); 6161dedffebSPavan Nikhilesh return 0; 6171dedffebSPavan Nikhilesh } 6181dedffebSPavan Nikhilesh 6191dedffebSPavan Nikhilesh static int 6201dedffebSPavan Nikhilesh ssovf_eth_tx_adapter_stop(uint8_t id, const struct rte_eventdev *dev) 6211dedffebSPavan Nikhilesh { 6221dedffebSPavan Nikhilesh RTE_SET_USED(id); 6231dedffebSPavan Nikhilesh RTE_SET_USED(dev); 6241dedffebSPavan Nikhilesh return 0; 6251dedffebSPavan Nikhilesh } 6261dedffebSPavan Nikhilesh 6271dedffebSPavan Nikhilesh 628558413c0SJerin Jacob static void 629558413c0SJerin Jacob ssovf_dump(struct rte_eventdev *dev, FILE *f) 630558413c0SJerin Jacob { 631558413c0SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 632558413c0SJerin Jacob uint8_t port; 633558413c0SJerin Jacob 634558413c0SJerin Jacob /* Dump SSOWVF debug registers */ 635558413c0SJerin Jacob for (port = 0; port < edev->nb_event_ports; port++) 636558413c0SJerin Jacob ssows_dump(dev->data->ports[port], f); 637558413c0SJerin Jacob } 638558413c0SJerin Jacob 639f61808eaSJerin Jacob static int 640f61808eaSJerin Jacob ssovf_start(struct rte_eventdev *dev) 641f61808eaSJerin Jacob { 642f61808eaSJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 643f61808eaSJerin Jacob struct ssows *ws; 644f61808eaSJerin Jacob uint8_t *base; 645f61808eaSJerin Jacob uint8_t i; 646f61808eaSJerin Jacob 647f61808eaSJerin Jacob ssovf_func_trace(); 648f61808eaSJerin Jacob for (i = 0; i < edev->nb_event_ports; i++) { 649f61808eaSJerin Jacob ws = dev->data->ports[i]; 650f61808eaSJerin Jacob ssows_reset(ws); 651f61808eaSJerin Jacob ws->swtag_req = 0; 652f61808eaSJerin Jacob } 653f61808eaSJerin Jacob 654f61808eaSJerin Jacob for (i = 0; i < edev->nb_event_queues; i++) { 655f61808eaSJerin Jacob /* Consume all the events through HWS0 */ 6568384f0e0SJerin Jacob ssows_flush_events(dev->data->ports[0], i, NULL, NULL); 657f61808eaSJerin Jacob 658d8dd3165SPavan Nikhilesh base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); 659f61808eaSJerin Jacob base += SSO_VHGRP_QCTL; 660f61808eaSJerin Jacob ssovf_write64(1, base); /* Enable SSO group */ 661f61808eaSJerin Jacob } 662f61808eaSJerin Jacob 663f61808eaSJerin Jacob ssovf_fastpath_fns_set(dev); 664f61808eaSJerin Jacob return 0; 665f61808eaSJerin Jacob } 666619d54c6SJerin Jacob 667619d54c6SJerin Jacob static void 6688384f0e0SJerin Jacob ssows_handle_event(void *arg, struct rte_event event) 6698384f0e0SJerin Jacob { 6708384f0e0SJerin Jacob struct rte_eventdev *dev = arg; 6718384f0e0SJerin Jacob 6728384f0e0SJerin Jacob if (dev->dev_ops->dev_stop_flush != NULL) 6738384f0e0SJerin Jacob dev->dev_ops->dev_stop_flush(dev->data->dev_id, event, 6748384f0e0SJerin Jacob dev->data->dev_stop_flush_arg); 6758384f0e0SJerin Jacob } 6768384f0e0SJerin Jacob 6778384f0e0SJerin Jacob static void 678619d54c6SJerin Jacob ssovf_stop(struct rte_eventdev *dev) 679619d54c6SJerin Jacob { 680619d54c6SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 681619d54c6SJerin Jacob struct ssows *ws; 682619d54c6SJerin Jacob uint8_t *base; 683619d54c6SJerin Jacob uint8_t i; 684619d54c6SJerin Jacob 685619d54c6SJerin Jacob ssovf_func_trace(); 686619d54c6SJerin Jacob for (i = 0; i < edev->nb_event_ports; i++) { 687619d54c6SJerin Jacob ws = dev->data->ports[i]; 688619d54c6SJerin Jacob ssows_reset(ws); 689619d54c6SJerin Jacob ws->swtag_req = 0; 690619d54c6SJerin Jacob } 691619d54c6SJerin Jacob 692619d54c6SJerin Jacob for (i = 0; i < edev->nb_event_queues; i++) { 693619d54c6SJerin Jacob /* Consume all the events through HWS0 */ 6948384f0e0SJerin Jacob ssows_flush_events(dev->data->ports[0], i, 6958384f0e0SJerin Jacob ssows_handle_event, dev); 696619d54c6SJerin Jacob 697d8dd3165SPavan Nikhilesh base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); 698619d54c6SJerin Jacob base += SSO_VHGRP_QCTL; 699619d54c6SJerin Jacob ssovf_write64(0, base); /* Disable SSO group */ 700619d54c6SJerin Jacob } 701619d54c6SJerin Jacob } 702619d54c6SJerin Jacob 703619d54c6SJerin Jacob static int 704619d54c6SJerin Jacob ssovf_close(struct rte_eventdev *dev) 705619d54c6SJerin Jacob { 706619d54c6SJerin Jacob struct ssovf_evdev *edev = ssovf_pmd_priv(dev); 707619d54c6SJerin Jacob uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV]; 708619d54c6SJerin Jacob uint8_t i; 709619d54c6SJerin Jacob 710619d54c6SJerin Jacob for (i = 0; i < edev->nb_event_queues; i++) 711619d54c6SJerin Jacob all_queues[i] = i; 712619d54c6SJerin Jacob 713619d54c6SJerin Jacob for (i = 0; i < edev->nb_event_ports; i++) 714619d54c6SJerin Jacob ssovf_port_unlink(dev, dev->data->ports[i], all_queues, 715619d54c6SJerin Jacob edev->nb_event_queues); 716619d54c6SJerin Jacob return 0; 717619d54c6SJerin Jacob } 718619d54c6SJerin Jacob 7193516327eSPavan Nikhilesh static int 720*3e86eee0SHanumanth Pothula ssovf_parsekv(const char *key, const char *value, void *opaque) 7213516327eSPavan Nikhilesh { 722*3e86eee0SHanumanth Pothula uint8_t *flag = opaque; 723*3e86eee0SHanumanth Pothula uint64_t v; 724*3e86eee0SHanumanth Pothula char *end; 725*3e86eee0SHanumanth Pothula 726*3e86eee0SHanumanth Pothula errno = 0; 727*3e86eee0SHanumanth Pothula v = strtoul(value, &end, 0); 728*3e86eee0SHanumanth Pothula if ((errno != 0) || (value == end) || *end != '\0' || v > 1) { 729*3e86eee0SHanumanth Pothula ssovf_log_err("invalid %s value %s", key, value); 730*3e86eee0SHanumanth Pothula return -EINVAL; 731*3e86eee0SHanumanth Pothula } 732*3e86eee0SHanumanth Pothula 733*3e86eee0SHanumanth Pothula *flag = !!v; 7343516327eSPavan Nikhilesh return 0; 7353516327eSPavan Nikhilesh } 7363516327eSPavan Nikhilesh 737f874c1ebSPavan Nikhilesh static int 738f874c1ebSPavan Nikhilesh ssovf_timvf_caps_get(const struct rte_eventdev *dev, uint64_t flags, 73953548ad3SPavan Nikhilesh uint32_t *caps, const struct event_timer_adapter_ops **ops) 740f874c1ebSPavan Nikhilesh { 741d1925c87SPavan Nikhilesh return timvf_timer_adapter_caps_get(dev, flags, caps, ops, 742d1925c87SPavan Nikhilesh timvf_enable_stats); 743f874c1ebSPavan Nikhilesh } 744f874c1ebSPavan Nikhilesh 7458dc6c2f1SShijith Thotton static int 7468dc6c2f1SShijith Thotton ssovf_crypto_adapter_caps_get(const struct rte_eventdev *dev, 7478dc6c2f1SShijith Thotton const struct rte_cryptodev *cdev, uint32_t *caps) 7488dc6c2f1SShijith Thotton { 7498dc6c2f1SShijith Thotton RTE_SET_USED(dev); 7508dc6c2f1SShijith Thotton RTE_SET_USED(cdev); 7518dc6c2f1SShijith Thotton 75244a2cebbSShijith Thotton *caps = RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD | 75344a2cebbSShijith Thotton RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA; 7548dc6c2f1SShijith Thotton 7558dc6c2f1SShijith Thotton return 0; 7568dc6c2f1SShijith Thotton } 7578dc6c2f1SShijith Thotton 7588dc6c2f1SShijith Thotton static int 7598dc6c2f1SShijith Thotton ssovf_crypto_adapter_qp_add(const struct rte_eventdev *dev, 7608dc6c2f1SShijith Thotton const struct rte_cryptodev *cdev, 7618dc6c2f1SShijith Thotton int32_t queue_pair_id, 762c1749bc5SVolodymyr Fialko const struct rte_event_crypto_adapter_queue_conf *conf) 7638dc6c2f1SShijith Thotton { 7648dc6c2f1SShijith Thotton struct cpt_instance *qp; 7658dc6c2f1SShijith Thotton uint8_t qp_id; 7668dc6c2f1SShijith Thotton 767c1749bc5SVolodymyr Fialko RTE_SET_USED(conf); 7688dc6c2f1SShijith Thotton 7698dc6c2f1SShijith Thotton if (queue_pair_id == -1) { 7708dc6c2f1SShijith Thotton for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) { 7718dc6c2f1SShijith Thotton qp = cdev->data->queue_pairs[qp_id]; 7728dc6c2f1SShijith Thotton qp->ca_enabled = 1; 7738dc6c2f1SShijith Thotton } 7748dc6c2f1SShijith Thotton } else { 7758dc6c2f1SShijith Thotton qp = cdev->data->queue_pairs[queue_pair_id]; 7768dc6c2f1SShijith Thotton qp->ca_enabled = 1; 7778dc6c2f1SShijith Thotton } 7788dc6c2f1SShijith Thotton 7798dc6c2f1SShijith Thotton ssovf_fastpath_fns_set((struct rte_eventdev *)(uintptr_t)dev); 7808dc6c2f1SShijith Thotton 7818dc6c2f1SShijith Thotton return 0; 7828dc6c2f1SShijith Thotton } 7838dc6c2f1SShijith Thotton 7848dc6c2f1SShijith Thotton static int 7858dc6c2f1SShijith Thotton ssovf_crypto_adapter_qp_del(const struct rte_eventdev *dev, 7868dc6c2f1SShijith Thotton const struct rte_cryptodev *cdev, 7878dc6c2f1SShijith Thotton int32_t queue_pair_id) 7888dc6c2f1SShijith Thotton { 7898dc6c2f1SShijith Thotton struct cpt_instance *qp; 7908dc6c2f1SShijith Thotton uint8_t qp_id; 7918dc6c2f1SShijith Thotton 7928dc6c2f1SShijith Thotton RTE_SET_USED(dev); 7938dc6c2f1SShijith Thotton 7948dc6c2f1SShijith Thotton if (queue_pair_id == -1) { 7958dc6c2f1SShijith Thotton for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) { 7968dc6c2f1SShijith Thotton qp = cdev->data->queue_pairs[qp_id]; 7978dc6c2f1SShijith Thotton qp->ca_enabled = 0; 7988dc6c2f1SShijith Thotton } 7998dc6c2f1SShijith Thotton } else { 8008dc6c2f1SShijith Thotton qp = cdev->data->queue_pairs[queue_pair_id]; 8018dc6c2f1SShijith Thotton qp->ca_enabled = 0; 8028dc6c2f1SShijith Thotton } 8038dc6c2f1SShijith Thotton 8048dc6c2f1SShijith Thotton return 0; 8058dc6c2f1SShijith Thotton } 8068dc6c2f1SShijith Thotton 8078b3808caSJerin Jacob /* Initialize and register event driver with DPDK Application */ 80823d06e37SPavan Nikhilesh static struct eventdev_ops ssovf_ops = { 8098b3808caSJerin Jacob .dev_infos_get = ssovf_info_get, 810f14b5ac2SJerin Jacob .dev_configure = ssovf_configure, 811d44a26ffSJerin Jacob .queue_def_conf = ssovf_queue_def_conf, 812d44a26ffSJerin Jacob .queue_setup = ssovf_queue_setup, 813d44a26ffSJerin Jacob .queue_release = ssovf_queue_release, 814708bac97SJerin Jacob .port_def_conf = ssovf_port_def_conf, 815708bac97SJerin Jacob .port_setup = ssovf_port_setup, 816708bac97SJerin Jacob .port_release = ssovf_port_release, 81735a228acSJerin Jacob .port_link = ssovf_port_link, 81835a228acSJerin Jacob .port_unlink = ssovf_port_unlink, 819613c7027SJerin Jacob .timeout_ticks = ssovf_timeout_ticks, 82045a914c5SPavan Nikhilesh 82145a914c5SPavan Nikhilesh .eth_rx_adapter_caps_get = ssovf_eth_rx_adapter_caps_get, 82245a914c5SPavan Nikhilesh .eth_rx_adapter_queue_add = ssovf_eth_rx_adapter_queue_add, 82345a914c5SPavan Nikhilesh .eth_rx_adapter_queue_del = ssovf_eth_rx_adapter_queue_del, 82445a914c5SPavan Nikhilesh .eth_rx_adapter_start = ssovf_eth_rx_adapter_start, 82545a914c5SPavan Nikhilesh .eth_rx_adapter_stop = ssovf_eth_rx_adapter_stop, 82645a914c5SPavan Nikhilesh 8271dedffebSPavan Nikhilesh .eth_tx_adapter_caps_get = ssovf_eth_tx_adapter_caps_get, 8281dedffebSPavan Nikhilesh .eth_tx_adapter_create = ssovf_eth_tx_adapter_create, 8291dedffebSPavan Nikhilesh .eth_tx_adapter_free = ssovf_eth_tx_adapter_free, 8301dedffebSPavan Nikhilesh .eth_tx_adapter_queue_add = ssovf_eth_tx_adapter_queue_add, 8311dedffebSPavan Nikhilesh .eth_tx_adapter_queue_del = ssovf_eth_tx_adapter_queue_del, 8321dedffebSPavan Nikhilesh .eth_tx_adapter_start = ssovf_eth_tx_adapter_start, 8331dedffebSPavan Nikhilesh .eth_tx_adapter_stop = ssovf_eth_tx_adapter_stop, 8341dedffebSPavan Nikhilesh 835f874c1ebSPavan Nikhilesh .timer_adapter_caps_get = ssovf_timvf_caps_get, 836f874c1ebSPavan Nikhilesh 8378dc6c2f1SShijith Thotton .crypto_adapter_caps_get = ssovf_crypto_adapter_caps_get, 8388dc6c2f1SShijith Thotton .crypto_adapter_queue_pair_add = ssovf_crypto_adapter_qp_add, 8398dc6c2f1SShijith Thotton .crypto_adapter_queue_pair_del = ssovf_crypto_adapter_qp_del, 8408dc6c2f1SShijith Thotton 841c54b7866SPavan Nikhilesh .dev_selftest = test_eventdev_octeontx, 842c54b7866SPavan Nikhilesh 843558413c0SJerin Jacob .dump = ssovf_dump, 844f61808eaSJerin Jacob .dev_start = ssovf_start, 845619d54c6SJerin Jacob .dev_stop = ssovf_stop, 846619d54c6SJerin Jacob .dev_close = ssovf_close 8478b3808caSJerin Jacob }; 8488b3808caSJerin Jacob 84934498de6SJerin Jacob static int 8505d2aa461SJan Blunck ssovf_vdev_probe(struct rte_vdev_device *vdev) 85134498de6SJerin Jacob { 852d8dd3165SPavan Nikhilesh struct ssovf_info oinfo; 85334498de6SJerin Jacob struct ssovf_mbox_dev_info info; 85434498de6SJerin Jacob struct ssovf_evdev *edev; 85534498de6SJerin Jacob struct rte_eventdev *eventdev; 85634498de6SJerin Jacob static int ssovf_init_once; 8575d2aa461SJan Blunck const char *name; 8583516327eSPavan Nikhilesh const char *params; 85934498de6SJerin Jacob int ret; 8603516327eSPavan Nikhilesh 8613516327eSPavan Nikhilesh static const char *const args[] = { 862d1925c87SPavan Nikhilesh TIMVF_ENABLE_STATS_ARG, 8633516327eSPavan Nikhilesh NULL 8643516327eSPavan Nikhilesh }; 86534498de6SJerin Jacob 8665d2aa461SJan Blunck name = rte_vdev_device_name(vdev); 86734498de6SJerin Jacob /* More than one instance is not supported */ 86834498de6SJerin Jacob if (ssovf_init_once) { 86934498de6SJerin Jacob ssovf_log_err("Request to create >1 %s instance", name); 87034498de6SJerin Jacob return -EINVAL; 87134498de6SJerin Jacob } 87234498de6SJerin Jacob 8733516327eSPavan Nikhilesh params = rte_vdev_device_args(vdev); 8743516327eSPavan Nikhilesh if (params != NULL && params[0] != '\0') { 8753516327eSPavan Nikhilesh struct rte_kvargs *kvlist = rte_kvargs_parse(params, args); 8763516327eSPavan Nikhilesh 8773516327eSPavan Nikhilesh if (!kvlist) { 8783516327eSPavan Nikhilesh ssovf_log_info( 8793516327eSPavan Nikhilesh "Ignoring unsupported params supplied '%s'", 8803516327eSPavan Nikhilesh name); 8813516327eSPavan Nikhilesh } else { 882a912cb5bSPavan Nikhilesh ret = rte_kvargs_process(kvlist, TIMVF_ENABLE_STATS_ARG, 883a912cb5bSPavan Nikhilesh ssovf_parsekv, 884a912cb5bSPavan Nikhilesh &timvf_enable_stats); 885d1925c87SPavan Nikhilesh if (ret != 0) { 886d1925c87SPavan Nikhilesh ssovf_log_err("%s: Error in timvf stats", name); 887d1925c87SPavan Nikhilesh rte_kvargs_free(kvlist); 888d1925c87SPavan Nikhilesh return ret; 889d1925c87SPavan Nikhilesh } 8903516327eSPavan Nikhilesh } 8913516327eSPavan Nikhilesh 8923516327eSPavan Nikhilesh rte_kvargs_free(kvlist); 8933516327eSPavan Nikhilesh } 8943516327eSPavan Nikhilesh 89534498de6SJerin Jacob eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev), 896928b5c70SBruce Richardson rte_socket_id(), vdev); 89734498de6SJerin Jacob if (eventdev == NULL) { 89834498de6SJerin Jacob ssovf_log_err("Failed to create eventdev vdev %s", name); 89934498de6SJerin Jacob return -ENOMEM; 90034498de6SJerin Jacob } 9018b3808caSJerin Jacob eventdev->dev_ops = &ssovf_ops; 90234498de6SJerin Jacob 903227f2835SPavan Nikhilesh timvf_set_eventdevice(eventdev); 904227f2835SPavan Nikhilesh 90534498de6SJerin Jacob /* For secondary processes, the primary has done all the work */ 906f61808eaSJerin Jacob if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 907f61808eaSJerin Jacob ssovf_fastpath_fns_set(eventdev); 90834498de6SJerin Jacob return 0; 909f61808eaSJerin Jacob } 91034498de6SJerin Jacob 911b4134b2dSPavan Nikhilesh octeontx_mbox_init(); 912d8dd3165SPavan Nikhilesh ret = ssovf_info(&oinfo); 91334498de6SJerin Jacob if (ret) { 91434498de6SJerin Jacob ssovf_log_err("Failed to probe and validate ssovfs %d", ret); 91534498de6SJerin Jacob goto error; 91634498de6SJerin Jacob } 91734498de6SJerin Jacob 91834498de6SJerin Jacob edev = ssovf_pmd_priv(eventdev); 91934498de6SJerin Jacob edev->max_event_ports = oinfo.total_ssowvfs; 92034498de6SJerin Jacob edev->max_event_queues = oinfo.total_ssovfs; 92134498de6SJerin Jacob edev->is_timeout_deq = 0; 92234498de6SJerin Jacob 92334498de6SJerin Jacob ret = ssovf_mbox_dev_info(&info); 92434498de6SJerin Jacob if (ret < 0 || ret != sizeof(struct ssovf_mbox_dev_info)) { 92534498de6SJerin Jacob ssovf_log_err("Failed to get mbox devinfo %d", ret); 92634498de6SJerin Jacob goto error; 92734498de6SJerin Jacob } 92834498de6SJerin Jacob 92934498de6SJerin Jacob edev->min_deq_timeout_ns = info.min_deq_timeout_ns; 93034498de6SJerin Jacob edev->max_deq_timeout_ns = info.max_deq_timeout_ns; 93134498de6SJerin Jacob edev->max_num_events = info.max_num_events; 932227f2835SPavan Nikhilesh edev->available_events = info.max_num_events; 933227f2835SPavan Nikhilesh 934227f2835SPavan Nikhilesh ssovf_log_dbg("min_deq_tmo=%" PRId64 " max_deq_tmo=%" PRId64 935227f2835SPavan Nikhilesh " max_evts=%d", 93634498de6SJerin Jacob info.min_deq_timeout_ns, info.max_deq_timeout_ns, 93734498de6SJerin Jacob info.max_num_events); 93834498de6SJerin Jacob 93934498de6SJerin Jacob if (!edev->max_event_ports || !edev->max_event_queues) { 94034498de6SJerin Jacob ssovf_log_err("Not enough eventdev resource queues=%d ports=%d", 94134498de6SJerin Jacob edev->max_event_queues, edev->max_event_ports); 94234498de6SJerin Jacob ret = -ENODEV; 94334498de6SJerin Jacob goto error; 94434498de6SJerin Jacob } 94534498de6SJerin Jacob 94634498de6SJerin Jacob ssovf_log_info("Initializing %s domain=%d max_queues=%d max_ports=%d", 94734498de6SJerin Jacob name, oinfo.domain, edev->max_event_queues, 94834498de6SJerin Jacob edev->max_event_ports); 94934498de6SJerin Jacob 95034498de6SJerin Jacob ssovf_init_once = 1; 95185be9971SPavan Nikhilesh event_dev_probing_finish(eventdev); 95234498de6SJerin Jacob return 0; 95334498de6SJerin Jacob 95434498de6SJerin Jacob error: 95534498de6SJerin Jacob rte_event_pmd_vdev_uninit(name); 95634498de6SJerin Jacob return ret; 95734498de6SJerin Jacob } 95834498de6SJerin Jacob 95934498de6SJerin Jacob static int 9605d2aa461SJan Blunck ssovf_vdev_remove(struct rte_vdev_device *vdev) 96134498de6SJerin Jacob { 9625d2aa461SJan Blunck const char *name; 9635d2aa461SJan Blunck 9645d2aa461SJan Blunck name = rte_vdev_device_name(vdev); 96534498de6SJerin Jacob ssovf_log_info("Closing %s", name); 96634498de6SJerin Jacob return rte_event_pmd_vdev_uninit(name); 96734498de6SJerin Jacob } 96834498de6SJerin Jacob 96934498de6SJerin Jacob static struct rte_vdev_driver vdev_ssovf_pmd = { 97034498de6SJerin Jacob .probe = ssovf_vdev_probe, 97134498de6SJerin Jacob .remove = ssovf_vdev_remove 97234498de6SJerin Jacob }; 97334498de6SJerin Jacob 97434498de6SJerin Jacob RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_OCTEONTX_PMD, vdev_ssovf_pmd); 975