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_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; }