xref: /dpdk/drivers/event/octeontx/ssovf_evdev.c (revision 3e86eee028c69b98144e2c62ec48091467e790be)
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