X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fevent%2Focteontx%2Fssovf_evdev.c;h=17325bbf6aaee59c42099d080e361938bad68ecd;hb=300b796262a1;hp=54512217ded0c9acdc34d736e1b9196580632456;hpb=ec36d881f56de787b59ec545372c351ecee6179a;p=dpdk.git diff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c index 54512217de..17325bbf6a 100644 --- a/drivers/event/octeontx/ssovf_evdev.c +++ b/drivers/event/octeontx/ssovf_evdev.c @@ -8,8 +8,9 @@ #include #include #include -#include +#include #include +#include #include #include #include @@ -17,17 +18,11 @@ #include #include "ssovf_evdev.h" +#include "timvf_evdev.h" -int otx_logtype_ssovf; +static uint8_t timvf_enable_stats; -RTE_INIT(otx_ssovf_init_log); -static void -otx_ssovf_init_log(void) -{ - otx_logtype_ssovf = rte_log_register("pmd.otx.eventdev"); - if (otx_logtype_ssovf >= 0) - rte_log_set_level(otx_logtype_ssovf, RTE_LOG_NOTICE); -} +RTE_LOG_REGISTER(otx_logtype_ssovf, pmd.event.octeontx, NOTICE); /* SSOPF Mailbox messages */ @@ -48,7 +43,7 @@ ssovf_mbox_dev_info(struct ssovf_mbox_dev_info *info) hdr.vfid = 0; memset(info, 0, len); - return octeontx_ssovf_mbox_send(&hdr, NULL, 0, info, len); + return octeontx_mbox_send(&hdr, NULL, 0, info, len); } struct ssovf_mbox_getwork_wait { @@ -68,7 +63,7 @@ ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns) hdr.vfid = 0; tmo_set.wait_ns = timeout_ns; - ret = octeontx_ssovf_mbox_send(&hdr, &tmo_set, len, NULL, 0); + ret = octeontx_mbox_send(&hdr, &tmo_set, len, NULL, 0); if (ret) ssovf_log_err("Failed to set getwork timeout(%d)", ret); @@ -76,6 +71,7 @@ ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns) } struct ssovf_mbox_grp_pri { + uint8_t vhgrp_id; uint8_t wgt_left; /* Read only */ uint8_t weight; uint8_t affinity; @@ -94,11 +90,12 @@ ssovf_mbox_priority_set(uint8_t queue, uint8_t prio) hdr.msg = SSO_GRP_SET_PRIORITY; hdr.vfid = queue; + grp.vhgrp_id = queue; grp.weight = 0xff; grp.affinity = 0xff; grp.priority = prio / 32; /* Normalize to 0 to 7 */ - ret = octeontx_ssovf_mbox_send(&hdr, &grp, len, NULL, 0); + ret = octeontx_mbox_send(&hdr, &grp, len, NULL, 0); if (ret) ssovf_log_err("Failed to set grp=%d prio=%d", queue, prio); @@ -124,7 +121,7 @@ ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks) memset(&ns2iter, 0, len); ns2iter.wait_ns = ns; - ret = octeontx_ssovf_mbox_send(&hdr, &ns2iter, len, &ns2iter, len); + ret = octeontx_mbox_send(&hdr, &ns2iter, len, &ns2iter, len); if (ret < 0 || (ret != len)) { ssovf_log_err("Failed to get tmo ticks ns=%"PRId64"", ns); return -EIO; @@ -134,24 +131,6 @@ ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks) return 0; } -static void -ssovf_fastpath_fns_set(struct rte_eventdev *dev) -{ - struct ssovf_evdev *edev = ssovf_pmd_priv(dev); - - dev->enqueue = ssows_enq; - dev->enqueue_burst = ssows_enq_burst; - dev->enqueue_new_burst = ssows_enq_new_burst; - dev->enqueue_forward_burst = ssows_enq_fwd_burst; - dev->dequeue = ssows_deq; - dev->dequeue_burst = ssows_deq_burst; - - if (edev->is_timeout_deq) { - dev->dequeue = ssows_deq_timeout; - dev->dequeue_burst = ssows_deq_timeout_burst; - } -} - static void ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info) { @@ -170,7 +149,12 @@ ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info) dev_info->max_num_events = edev->max_num_events; dev_info->event_dev_cap = RTE_EVENT_DEV_CAP_QUEUE_QOS | RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED | - RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES; + RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES| + RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK | + RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT | + RTE_EVENT_DEV_CAP_NONSEQ_MODE | + RTE_EVENT_DEV_CAP_CARRY_FLOW_ID; + } static int @@ -235,7 +219,7 @@ ssovf_port_def_conf(struct rte_eventdev *dev, uint8_t port_id, port_conf->new_event_threshold = edev->max_num_events; port_conf->dequeue_depth = 1; port_conf->enqueue_depth = 1; - port_conf->disable_implicit_release = 0; + port_conf->event_port_cfg = 0; } static void @@ -271,7 +255,7 @@ ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id, return -ENOMEM; } - ws->base = octeontx_ssovf_bar(OCTEONTX_SSO_HWS, port_id, 0); + ws->base = ssovf_bar(OCTEONTX_SSO_HWS, port_id, 0); if (ws->base == NULL) { rte_free(ws); ssovf_log_err("Failed to get hws base addr port=%d", port_id); @@ -283,9 +267,10 @@ ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id, reg_off |= 1 << 16; /* Wait */ ws->getwork = ws->base + reg_off; ws->port = port_id; + ws->lookup_mem = octeontx_fastpath_lookup_mem_get(); for (q = 0; q < edev->nb_event_queues; q++) { - ws->grps[q] = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, q, 2); + ws->grps[q] = ssovf_bar(OCTEONTX_SSO_GROUP, q, 2); if (ws->grps[q] == NULL) { rte_free(ws); ssovf_log_err("Failed to get grp%d base addr", q); @@ -400,21 +385,78 @@ ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev, const struct rte_eth_dev *eth_dev, int32_t rx_queue_id, const struct rte_event_eth_rx_adapter_queue_conf *queue_conf) { - int ret = 0; const struct octeontx_nic *nic = eth_dev->data->dev_private; + struct ssovf_evdev *edev = ssovf_pmd_priv(dev); + uint16_t free_idx = UINT16_MAX; + struct octeontx_rxq *rxq; pki_mod_qos_t pki_qos; - RTE_SET_USED(dev); + uint8_t found = false; + int i, ret = 0; + void *old_ptr; ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); if (ret) return -EINVAL; - if (rx_queue_id >= 0) - return -EINVAL; - if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL) return -ENOTSUP; + /* eth_octeontx only supports one rq. */ + rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id; + rxq = eth_dev->data->rx_queues[rx_queue_id]; + /* Add rxq pool to list of used pools and reduce available events. */ + for (i = 0; i < edev->rxq_pools; i++) { + if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) { + edev->rxq_pool_rcnt[i]++; + found = true; + break; + } else if (free_idx == UINT16_MAX && + edev->rxq_pool_array[i] == 0) { + free_idx = i; + } + } + + if (!found) { + uint16_t idx; + + if (edev->available_events < rxq->pool->size) { + ssovf_log_err( + "Max available events %"PRIu32" requested events in rxq pool %"PRIu32"", + edev->available_events, rxq->pool->size); + return -ENOMEM; + } + + if (free_idx != UINT16_MAX) { + idx = free_idx; + } else { + old_ptr = edev->rxq_pool_array; + edev->rxq_pools++; + edev->rxq_pool_array = rte_realloc( + edev->rxq_pool_array, + sizeof(uint64_t) * edev->rxq_pools, 0); + if (edev->rxq_pool_array == NULL) { + edev->rxq_pools--; + edev->rxq_pool_array = old_ptr; + return -ENOMEM; + } + + old_ptr = edev->rxq_pool_rcnt; + edev->rxq_pool_rcnt = rte_realloc( + edev->rxq_pool_rcnt, + sizeof(uint8_t) * edev->rxq_pools, 0); + if (edev->rxq_pool_rcnt == NULL) { + edev->rxq_pools--; + edev->rxq_pool_rcnt = old_ptr; + return -ENOMEM; + } + idx = edev->rxq_pools - 1; + } + + edev->rxq_pool_array[idx] = (uintptr_t)rxq->pool; + edev->rxq_pool_rcnt[idx] = 1; + edev->available_events -= rxq->pool->size; + } + memset(&pki_qos, 0, sizeof(pki_mod_qos_t)); pki_qos.port_type = 0; @@ -426,7 +468,7 @@ ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev, pki_qos.mmask.f_grptag_ok = 1; pki_qos.mmask.f_grptag_bad = 1; - pki_qos.tag_type = queue_conf->ev.sched_type; + pki_qos.qos_entry.tag_type = queue_conf->ev.sched_type; pki_qos.qos_entry.port_add = 0; pki_qos.qos_entry.ggrp_ok = queue_conf->ev.queue_id; pki_qos.qos_entry.ggrp_bad = queue_conf->ev.queue_id; @@ -438,6 +480,8 @@ ssovf_eth_rx_adapter_queue_add(const struct rte_eventdev *dev, ssovf_log_err("failed to modify QOS, port=%d, q=%d", nic->port_id, queue_conf->ev.queue_id); + edev->rx_offload_flags = nic->rx_offload_flags; + edev->tx_offload_flags = nic->tx_offload_flags; return ret; } @@ -445,11 +489,28 @@ static int ssovf_eth_rx_adapter_queue_del(const struct rte_eventdev *dev, const struct rte_eth_dev *eth_dev, int32_t rx_queue_id) { - int ret = 0; const struct octeontx_nic *nic = eth_dev->data->dev_private; + struct ssovf_evdev *edev = ssovf_pmd_priv(dev); + struct octeontx_rxq *rxq; pki_del_qos_t pki_qos; - RTE_SET_USED(dev); - RTE_SET_USED(rx_queue_id); + uint8_t found = false; + int i, ret = 0; + + rx_queue_id = rx_queue_id == -1 ? 0 : rx_queue_id; + rxq = eth_dev->data->rx_queues[rx_queue_id]; + for (i = 0; i < edev->rxq_pools; i++) { + if (edev->rxq_pool_array[i] == (uintptr_t)rxq->pool) { + found = true; + break; + } + } + + if (found) { + edev->rxq_pool_rcnt[i]--; + if (edev->rxq_pool_rcnt[i] == 0) + edev->rxq_pool_array[i] = 0; + edev->available_events += rxq->pool->size; + } ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); if (ret) @@ -461,7 +522,7 @@ ssovf_eth_rx_adapter_queue_del(const struct rte_eventdev *dev, ret = octeontx_pki_port_delete_qos(nic->port_id, &pki_qos); if (ret < 0) ssovf_log_err("Failed to delete QOS port=%d, q=%d", - nic->port_id, queue_conf->ev.queue_id); + nic->port_id, rx_queue_id); return ret; } @@ -469,14 +530,9 @@ static int ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev, const struct rte_eth_dev *eth_dev) { - int ret; - const struct octeontx_nic *nic = eth_dev->data->dev_private; RTE_SET_USED(dev); + RTE_SET_USED(eth_dev); - ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); - if (ret) - return 0; - octeontx_pki_port_start(nic->port_id); return 0; } @@ -484,18 +540,84 @@ ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev, static int ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev, const struct rte_eth_dev *eth_dev) +{ + RTE_SET_USED(dev); + RTE_SET_USED(eth_dev); + + return 0; +} + +static int +ssovf_eth_tx_adapter_caps_get(const struct rte_eventdev *dev, + const struct rte_eth_dev *eth_dev, uint32_t *caps) { int ret; - const struct octeontx_nic *nic = eth_dev->data->dev_private; RTE_SET_USED(dev); ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); if (ret) - return 0; - octeontx_pki_port_stop(nic->port_id); + *caps = 0; + else + *caps = RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT; + + return 0; +} + +static int +ssovf_eth_tx_adapter_create(uint8_t id, const struct rte_eventdev *dev) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); return 0; } +static int +ssovf_eth_tx_adapter_free(uint8_t id, const struct rte_eventdev *dev) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); + return 0; +} + +static int +ssovf_eth_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *dev, + const struct rte_eth_dev *eth_dev, int32_t tx_queue_id) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); + RTE_SET_USED(eth_dev); + RTE_SET_USED(tx_queue_id); + return 0; +} + +static int +ssovf_eth_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *dev, + const struct rte_eth_dev *eth_dev, int32_t tx_queue_id) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); + RTE_SET_USED(eth_dev); + RTE_SET_USED(tx_queue_id); + return 0; +} + +static int +ssovf_eth_tx_adapter_start(uint8_t id, const struct rte_eventdev *dev) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); + return 0; +} + +static int +ssovf_eth_tx_adapter_stop(uint8_t id, const struct rte_eventdev *dev) +{ + RTE_SET_USED(id); + RTE_SET_USED(dev); + return 0; +} + + static void ssovf_dump(struct rte_eventdev *dev, FILE *f) { @@ -524,9 +646,9 @@ ssovf_start(struct rte_eventdev *dev) for (i = 0; i < edev->nb_event_queues; i++) { /* Consume all the events through HWS0 */ - ssows_flush_events(dev->data->ports[0], i); + ssows_flush_events(dev->data->ports[0], i, NULL, NULL); - base = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); + base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); base += SSO_VHGRP_QCTL; ssovf_write64(1, base); /* Enable SSO group */ } @@ -535,6 +657,16 @@ ssovf_start(struct rte_eventdev *dev) return 0; } +static void +ssows_handle_event(void *arg, struct rte_event event) +{ + struct rte_eventdev *dev = arg; + + if (dev->dev_ops->dev_stop_flush != NULL) + dev->dev_ops->dev_stop_flush(dev->data->dev_id, event, + dev->data->dev_stop_flush_arg); +} + static void ssovf_stop(struct rte_eventdev *dev) { @@ -552,9 +684,10 @@ ssovf_stop(struct rte_eventdev *dev) for (i = 0; i < edev->nb_event_queues; i++) { /* Consume all the events through HWS0 */ - ssows_flush_events(dev->data->ports[0], i); + ssows_flush_events(dev->data->ports[0], i, + ssows_handle_event, dev); - base = octeontx_ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); + base = ssovf_bar(OCTEONTX_SSO_GROUP, i, 0); base += SSO_VHGRP_QCTL; ssovf_write64(0, base); /* Disable SSO group */ } @@ -576,8 +709,24 @@ ssovf_close(struct rte_eventdev *dev) return 0; } +static int +ssovf_parsekv(const char *key __rte_unused, const char *value, void *opaque) +{ + int *flag = opaque; + *flag = !!atoi(value); + return 0; +} + +static int +ssovf_timvf_caps_get(const struct rte_eventdev *dev, uint64_t flags, + uint32_t *caps, const struct rte_event_timer_adapter_ops **ops) +{ + return timvf_timer_adapter_caps_get(dev, flags, caps, ops, + timvf_enable_stats); +} + /* Initialize and register event driver with DPDK Application */ -static const struct rte_eventdev_ops ssovf_ops = { +static struct rte_eventdev_ops ssovf_ops = { .dev_infos_get = ssovf_info_get, .dev_configure = ssovf_configure, .queue_def_conf = ssovf_queue_def_conf, @@ -596,6 +745,18 @@ static const struct rte_eventdev_ops ssovf_ops = { .eth_rx_adapter_start = ssovf_eth_rx_adapter_start, .eth_rx_adapter_stop = ssovf_eth_rx_adapter_stop, + .eth_tx_adapter_caps_get = ssovf_eth_tx_adapter_caps_get, + .eth_tx_adapter_create = ssovf_eth_tx_adapter_create, + .eth_tx_adapter_free = ssovf_eth_tx_adapter_free, + .eth_tx_adapter_queue_add = ssovf_eth_tx_adapter_queue_add, + .eth_tx_adapter_queue_del = ssovf_eth_tx_adapter_queue_del, + .eth_tx_adapter_start = ssovf_eth_tx_adapter_start, + .eth_tx_adapter_stop = ssovf_eth_tx_adapter_stop, + + .timer_adapter_caps_get = ssovf_timvf_caps_get, + + .dev_selftest = test_eventdev_octeontx, + .dump = ssovf_dump, .dev_start = ssovf_start, .dev_stop = ssovf_stop, @@ -605,14 +766,20 @@ static const struct rte_eventdev_ops ssovf_ops = { static int ssovf_vdev_probe(struct rte_vdev_device *vdev) { - struct octeontx_ssovf_info oinfo; + struct ssovf_info oinfo; struct ssovf_mbox_dev_info info; struct ssovf_evdev *edev; struct rte_eventdev *eventdev; static int ssovf_init_once; const char *name; + const char *params; int ret; + static const char *const args[] = { + TIMVF_ENABLE_STATS_ARG, + NULL + }; + name = rte_vdev_device_name(vdev); /* More than one instance is not supported */ if (ssovf_init_once) { @@ -620,6 +787,28 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev) return -EINVAL; } + params = rte_vdev_device_args(vdev); + if (params != NULL && params[0] != '\0') { + struct rte_kvargs *kvlist = rte_kvargs_parse(params, args); + + if (!kvlist) { + ssovf_log_info( + "Ignoring unsupported params supplied '%s'", + name); + } else { + ret = rte_kvargs_process(kvlist, TIMVF_ENABLE_STATS_ARG, + ssovf_parsekv, + &timvf_enable_stats); + if (ret != 0) { + ssovf_log_err("%s: Error in timvf stats", name); + rte_kvargs_free(kvlist); + return ret; + } + } + + rte_kvargs_free(kvlist); + } + eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev), rte_socket_id()); if (eventdev == NULL) { @@ -628,13 +817,16 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev) } eventdev->dev_ops = &ssovf_ops; + timvf_set_eventdevice(eventdev); + /* For secondary processes, the primary has done all the work */ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ssovf_fastpath_fns_set(eventdev); return 0; } - ret = octeontx_ssovf_info(&oinfo); + octeontx_mbox_init(); + ret = ssovf_info(&oinfo); if (ret) { ssovf_log_err("Failed to probe and validate ssovfs %d", ret); goto error; @@ -654,9 +846,12 @@ ssovf_vdev_probe(struct rte_vdev_device *vdev) edev->min_deq_timeout_ns = info.min_deq_timeout_ns; edev->max_deq_timeout_ns = info.max_deq_timeout_ns; edev->max_num_events = info.max_num_events; - ssovf_log_dbg("min_deq_tmo=%"PRId64" max_deq_tmo=%"PRId64" max_evts=%d", - info.min_deq_timeout_ns, info.max_deq_timeout_ns, - info.max_num_events); + edev->available_events = info.max_num_events; + + ssovf_log_dbg("min_deq_tmo=%" PRId64 " max_deq_tmo=%" PRId64 + " max_evts=%d", + info.min_deq_timeout_ns, info.max_deq_timeout_ns, + info.max_num_events); if (!edev->max_event_ports || !edev->max_event_queues) { ssovf_log_err("Not enough eventdev resource queues=%d ports=%d",