static int ssovf_port_setup(struct rte_eventdev *dev, uint8_t port_id, const struct rte_event_port_conf *port_conf) { struct ssows *ws; uint32_t reg_off; uint8_t q; struct ssovf_evdev *edev = ssovf_pmd_priv(dev); ssovf_func_trace("port=%d", port_id); RTE_SET_USED(port_conf); /* Free memory prior to re-allocation if needed */ if (dev->data->ports[port_id] != NULL) { ssovf_port_release(dev->data->ports[port_id]); dev->data->ports[port_id] = NULL; } /* Allocate event port memory */ ws = rte_zmalloc_socket("eventdev ssows", sizeof(struct ssows), RTE_CACHE_LINE_SIZE, dev->data->socket_id); if (ws == NULL) { ssovf_log_err("Failed to alloc memory for port=%d", port_id); return -ENOMEM; } 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); return -EINVAL; } reg_off = SSOW_VHWS_OP_GET_WORK0; reg_off |= 1 << 4; /* Index_ggrp_mask (Use maskset zero) */ reg_off |= 1 << 16; /* Wait */ ws->getwork = ws->base + reg_off; ws->port = port_id; for (q = 0; q < edev->nb_event_queues; q++) { 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); return -EINVAL; } } dev->data->ports[port_id] = ws; ssovf_log_dbg("port=%d ws=%p", port_id, ws); return 0; }
static int 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; pki_mod_qos_t pki_qos; RTE_SET_USED(dev); 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; memset(&pki_qos, 0, sizeof(pki_mod_qos_t)); pki_qos.port_type = 0; pki_qos.index = 0; pki_qos.mmask.f_tag_type = 1; pki_qos.mmask.f_port_add = 1; pki_qos.mmask.f_grp_ok = 1; pki_qos.mmask.f_grp_bad = 1; 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.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; pki_qos.qos_entry.grptag_bad = 0; pki_qos.qos_entry.grptag_ok = 0; ret = octeontx_pki_port_modify_qos(nic->port_id, &pki_qos); if (ret < 0) ssovf_log_err("failed to modify QOS, port=%d, q=%d", nic->port_id, queue_conf->ev.queue_id); return ret; }
static int ssovf_mbox_getwork_tmo_set(uint32_t timeout_ns) { struct octeontx_mbox_hdr hdr = {0}; struct ssovf_mbox_getwork_wait tmo_set; uint16_t len = sizeof(struct ssovf_mbox_getwork_wait); int ret; hdr.coproc = SSO_COPROC; hdr.msg = SSO_SET_GETWORK_WAIT; hdr.vfid = 0; tmo_set.wait_ns = timeout_ns; ret = octeontx_mbox_send(&hdr, &tmo_set, len, NULL, 0); if (ret) ssovf_log_err("Failed to set getwork timeout(%d)", ret); return ret; }
static int ssovf_mbox_priority_set(uint8_t queue, uint8_t prio) { struct octeontx_mbox_hdr hdr = {0}; struct ssovf_mbox_grp_pri grp; uint16_t len = sizeof(struct ssovf_mbox_grp_pri); int ret; hdr.coproc = SSO_COPROC; hdr.msg = SSO_GRP_SET_PRIORITY; hdr.vfid = queue; grp.weight = 0xff; grp.affinity = 0xff; grp.priority = prio / 32; /* Normalize to 0 to 7 */ ret = octeontx_mbox_send(&hdr, &grp, len, NULL, 0); if (ret) ssovf_log_err("Failed to set grp=%d prio=%d", queue, prio); return ret; }
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; pki_del_qos_t pki_qos; RTE_SET_USED(dev); ret = strncmp(eth_dev->data->name, "eth_octeontx", 12); if (ret) return -EINVAL; pki_qos.port_type = 0; pki_qos.index = 0; memset(&pki_qos, 0, sizeof(pki_del_qos_t)); 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, rx_queue_id); return ret; }
static int ssovf_mbox_timeout_ticks(uint64_t ns, uint64_t *tmo_ticks) { struct octeontx_mbox_hdr hdr = {0}; struct ssovf_mbox_convert_ns_getworks_iter ns2iter; uint16_t len = sizeof(ns2iter); int ret; hdr.coproc = SSO_COPROC; hdr.msg = SSO_CONVERT_NS_GETWORK_ITER; hdr.vfid = 0; memset(&ns2iter, 0, len); ns2iter.wait_ns = ns; 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; } *tmo_ticks = ns2iter.getwork_iter; return 0; }
static int ssovf_vdev_probe(struct rte_vdev_device *vdev) { struct octeontx_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; int ret; name = rte_vdev_device_name(vdev); /* More than one instance is not supported */ if (ssovf_init_once) { ssovf_log_err("Request to create >1 %s instance", name); return -EINVAL; } eventdev = rte_event_pmd_vdev_init(name, sizeof(struct ssovf_evdev), rte_socket_id()); if (eventdev == NULL) { ssovf_log_err("Failed to create eventdev vdev %s", name); return -ENOMEM; } eventdev->dev_ops = &ssovf_ops; /* 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); if (ret) { ssovf_log_err("Failed to probe and validate ssovfs %d", ret); goto error; } edev = ssovf_pmd_priv(eventdev); edev->max_event_ports = oinfo.total_ssowvfs; edev->max_event_queues = oinfo.total_ssovfs; edev->is_timeout_deq = 0; ret = ssovf_mbox_dev_info(&info); if (ret < 0 || ret != sizeof(struct ssovf_mbox_dev_info)) { ssovf_log_err("Failed to get mbox devinfo %d", ret); goto error; } 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); if (!edev->max_event_ports || !edev->max_event_queues) { ssovf_log_err("Not enough eventdev resource queues=%d ports=%d", edev->max_event_queues, edev->max_event_ports); ret = -ENODEV; goto error; } ssovf_log_info("Initializing %s domain=%d max_queues=%d max_ports=%d", name, oinfo.domain, edev->max_event_queues, edev->max_event_ports); ssovf_init_once = 1; return 0; error: rte_event_pmd_vdev_uninit(name); return ret; }