xref: /dpdk/drivers/net/mlx5/mlx5_testpmd.c (revision 3dfa78770ed53c376df2da7c2bd997e0b2d33cd1)
1f41a5092SSpike Du /* SPDX-License-Identifier: BSD-3-Clause
2f41a5092SSpike Du  * Copyright 2021 6WIND S.A.
3f41a5092SSpike Du  * Copyright 2021 Mellanox Technologies, Ltd
4f41a5092SSpike Du  */
5f41a5092SSpike Du 
6f41a5092SSpike Du #include <stdint.h>
7f41a5092SSpike Du #include <string.h>
8f41a5092SSpike Du #include <stdlib.h>
985d9252eSMichael Baum #include <unistd.h>
1085d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
1185d9252eSMichael Baum #include <sys/socket.h>
1285d9252eSMichael Baum #include <sys/un.h>
1385d9252eSMichael Baum #endif
14f41a5092SSpike Du 
15f41a5092SSpike Du #include <rte_prefetch.h>
16f41a5092SSpike Du #include <rte_common.h>
17f41a5092SSpike Du #include <rte_branch_prediction.h>
18f41a5092SSpike Du #include <rte_ether.h>
19f41a5092SSpike Du #include <rte_alarm.h>
20f41a5092SSpike Du #include <rte_pmd_mlx5.h>
21f41a5092SSpike Du #include <rte_ethdev.h>
2285d9252eSMichael Baum 
23f41a5092SSpike Du #include "mlx5_testpmd.h"
24f41a5092SSpike Du #include "testpmd.h"
25f41a5092SSpike Du 
26f41a5092SSpike Du #define SHAPER_DISABLE_DELAY_US 100000 /* 100ms */
270683c002SMichael Baum #define MAX_GENEVE_OPTIONS_RESOURCES 7
28baafc81eSRongwei Liu #define PARSE_DELIMITER " \f\n\r\t\v"
290683c002SMichael Baum #define SPACE_DELIMITER (" ")
300683c002SMichael Baum 
310683c002SMichael Baum static uint8_t host_shaper_avail_thresh_triggered[RTE_MAX_ETHPORTS];
320683c002SMichael Baum 
330683c002SMichael Baum struct mlx5_port {
340683c002SMichael Baum 	void *geneve_tlv_parser_handle;
350683c002SMichael Baum };
360683c002SMichael Baum 
370683c002SMichael Baum static struct mlx5_port private_port[RTE_MAX_ETHPORTS] = {{0}};
380683c002SMichael Baum 
390683c002SMichael Baum struct tlv_list_manager {
400683c002SMichael Baum 	uint8_t nb_options;
410683c002SMichael Baum 	struct rte_pmd_mlx5_geneve_tlv tlv_list[MAX_GENEVE_OPTIONS_RESOURCES];
420683c002SMichael Baum };
430683c002SMichael Baum 
440683c002SMichael Baum static struct tlv_list_manager tlv_mng = {.nb_options = 0};
45baafc81eSRongwei Liu 
46baafc81eSRongwei Liu static int
parse_uint(uint64_t * value,const char * str)47baafc81eSRongwei Liu parse_uint(uint64_t *value, const char *str)
48baafc81eSRongwei Liu {
49baafc81eSRongwei Liu 	char *next = NULL;
50baafc81eSRongwei Liu 	uint64_t n;
51baafc81eSRongwei Liu 
52baafc81eSRongwei Liu 	errno = 0;
53baafc81eSRongwei Liu 	/* Parse number string */
54baafc81eSRongwei Liu 	if (!strncasecmp(str, "0x", 2)) {
55baafc81eSRongwei Liu 		str += 2;
56baafc81eSRongwei Liu 		n = strtol(str, &next, 16);
57baafc81eSRongwei Liu 	} else {
58baafc81eSRongwei Liu 		n = strtol(str, &next, 10);
59baafc81eSRongwei Liu 	}
60baafc81eSRongwei Liu 	if (errno != 0 || str == next || *next != '\0')
61baafc81eSRongwei Liu 		return -1;
62baafc81eSRongwei Liu 
63baafc81eSRongwei Liu 	*value = n;
64baafc81eSRongwei Liu 
65baafc81eSRongwei Liu 	return 0;
66baafc81eSRongwei Liu }
67f41a5092SSpike Du 
68f41a5092SSpike Du /**
69f41a5092SSpike Du  * Disable the host shaper and re-arm available descriptor threshold event.
70f41a5092SSpike Du  *
71f41a5092SSpike Du  * @param[in] args
72f41a5092SSpike Du  *   uint32_t integer combining port_id and rxq_id.
73f41a5092SSpike Du  */
74f41a5092SSpike Du static void
mlx5_test_host_shaper_disable(void * args)75f41a5092SSpike Du mlx5_test_host_shaper_disable(void *args)
76f41a5092SSpike Du {
77f41a5092SSpike Du 	uint32_t port_rxq_id = (uint32_t)(uintptr_t)args;
78f41a5092SSpike Du 	uint16_t port_id = port_rxq_id & 0xffff;
79f41a5092SSpike Du 	uint16_t qid = (port_rxq_id >> 16) & 0xffff;
80f41a5092SSpike Du 	struct rte_eth_rxq_info qinfo;
810f3ba0d4SSpike Du 	struct rte_port *port;
82f41a5092SSpike Du 
830f3ba0d4SSpike Du 	port = &ports[port_id];
840f3ba0d4SSpike Du 	if (port->port_status != RTE_PORT_STARTED) {
850f3ba0d4SSpike Du 		printf("%s port_status(%d) is incorrect, stop avail_thresh "
860f3ba0d4SSpike Du 		       "event processing.\n",
870f3ba0d4SSpike Du 		       __func__, port->port_status);
880f3ba0d4SSpike Du 		return;
890f3ba0d4SSpike Du 	}
90f41a5092SSpike Du 	printf("%s disable shaper\n", __func__);
91f41a5092SSpike Du 	if (rte_eth_rx_queue_info_get(port_id, qid, &qinfo)) {
92f41a5092SSpike Du 		printf("rx_queue_info_get returns error\n");
93f41a5092SSpike Du 		return;
94f41a5092SSpike Du 	}
95f41a5092SSpike Du 	/* Rearm the available descriptor threshold event. */
96f41a5092SSpike Du 	if (rte_eth_rx_avail_thresh_set(port_id, qid, qinfo.avail_thresh)) {
97f41a5092SSpike Du 		printf("config avail_thresh returns error\n");
98f41a5092SSpike Du 		return;
99f41a5092SSpike Du 	}
100f41a5092SSpike Du 	/* Only disable the shaper when avail_thresh_triggered is set. */
101f41a5092SSpike Du 	if (host_shaper_avail_thresh_triggered[port_id] &&
102f41a5092SSpike Du 	    rte_pmd_mlx5_host_shaper_config(port_id, 0, 0))
103f41a5092SSpike Du 		printf("%s disable shaper returns error\n", __func__);
104f41a5092SSpike Du }
105f41a5092SSpike Du 
106f41a5092SSpike Du void
mlx5_test_avail_thresh_event_handler(uint16_t port_id,uint16_t rxq_id)107f41a5092SSpike Du mlx5_test_avail_thresh_event_handler(uint16_t port_id, uint16_t rxq_id)
108f41a5092SSpike Du {
109f41a5092SSpike Du 	struct rte_eth_dev_info dev_info;
110f41a5092SSpike Du 	uint32_t port_rxq_id = port_id | (rxq_id << 16);
111f41a5092SSpike Du 
112f41a5092SSpike Du 	/* Ensure it's MLX5 port. */
113f41a5092SSpike Du 	if (rte_eth_dev_info_get(port_id, &dev_info) != 0 ||
114f41a5092SSpike Du 	    (strncmp(dev_info.driver_name, "mlx5", 4) != 0))
115f41a5092SSpike Du 		return;
116f41a5092SSpike Du 	rte_eal_alarm_set(SHAPER_DISABLE_DELAY_US,
117f41a5092SSpike Du 			  mlx5_test_host_shaper_disable,
118f41a5092SSpike Du 			  (void *)(uintptr_t)port_rxq_id);
119f41a5092SSpike Du 	printf("%s port_id:%u rxq_id:%u\n", __func__, port_id, rxq_id);
120f41a5092SSpike Du }
121f41a5092SSpike Du 
122f41a5092SSpike Du /**
123f41a5092SSpike Du  * Configure host shaper's avail_thresh_triggered and current rate.
124f41a5092SSpike Du  *
125f41a5092SSpike Du  * @param[in] avail_thresh_triggered
126f41a5092SSpike Du  *   Disable/enable avail_thresh_triggered.
127f41a5092SSpike Du  * @param[in] rate
128f41a5092SSpike Du  *   Configure current host shaper rate.
129f41a5092SSpike Du  * @return
130f41a5092SSpike Du  *   On success, returns 0.
131f41a5092SSpike Du  *   On failure, returns < 0.
132f41a5092SSpike Du  */
133f41a5092SSpike Du static int
mlx5_test_set_port_host_shaper(uint16_t port_id,uint16_t avail_thresh_triggered,uint8_t rate)134f41a5092SSpike Du mlx5_test_set_port_host_shaper(uint16_t port_id, uint16_t avail_thresh_triggered, uint8_t rate)
135f41a5092SSpike Du {
136f41a5092SSpike Du 	struct rte_eth_link link;
137f41a5092SSpike Du 	bool port_id_valid = false;
138f41a5092SSpike Du 	uint16_t pid;
139f41a5092SSpike Du 	int ret;
140f41a5092SSpike Du 
141f41a5092SSpike Du 	RTE_ETH_FOREACH_DEV(pid)
142f41a5092SSpike Du 		if (port_id == pid) {
143f41a5092SSpike Du 			port_id_valid = true;
144f41a5092SSpike Du 			break;
145f41a5092SSpike Du 		}
146f41a5092SSpike Du 	if (!port_id_valid)
147f41a5092SSpike Du 		return -EINVAL;
148f41a5092SSpike Du 	ret = rte_eth_link_get_nowait(port_id, &link);
149f41a5092SSpike Du 	if (ret < 0)
150f41a5092SSpike Du 		return ret;
151f41a5092SSpike Du 	host_shaper_avail_thresh_triggered[port_id] = avail_thresh_triggered ? 1 : 0;
152f41a5092SSpike Du 	if (!avail_thresh_triggered) {
153f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 0,
15486647d46SThomas Monjalon 		RTE_BIT32(RTE_PMD_MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
155f41a5092SSpike Du 	} else {
156f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 1,
15786647d46SThomas Monjalon 		RTE_BIT32(RTE_PMD_MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
158f41a5092SSpike Du 	}
159f41a5092SSpike Du 	if (ret)
160f41a5092SSpike Du 		return ret;
161f41a5092SSpike Du 	ret = rte_pmd_mlx5_host_shaper_config(port_id, rate, 0);
162f41a5092SSpike Du 	if (ret)
163f41a5092SSpike Du 		return ret;
164f41a5092SSpike Du 	return 0;
165f41a5092SSpike Du }
166f41a5092SSpike Du 
16785d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
16885d9252eSMichael Baum static const char*
mlx5_test_get_socket_path(char * extend)16985d9252eSMichael Baum mlx5_test_get_socket_path(char *extend)
17085d9252eSMichael Baum {
17185d9252eSMichael Baum 	if (strstr(extend, "socket=") == extend) {
17285d9252eSMichael Baum 		const char *socket_path = strchr(extend, '=') + 1;
17385d9252eSMichael Baum 
17485d9252eSMichael Baum 		TESTPMD_LOG(DEBUG, "MLX5 socket path is %s\n", socket_path);
17585d9252eSMichael Baum 		return socket_path;
17685d9252eSMichael Baum 	}
17785d9252eSMichael Baum 
17885d9252eSMichael Baum 	TESTPMD_LOG(ERR, "Failed to extract a valid socket path from %s\n",
17985d9252eSMichael Baum 		    extend);
18085d9252eSMichael Baum 	return NULL;
18185d9252eSMichael Baum }
18285d9252eSMichael Baum 
18385d9252eSMichael Baum static int
mlx5_test_extend_devargs(char * identifier,char * extend)18485d9252eSMichael Baum mlx5_test_extend_devargs(char *identifier, char *extend)
18585d9252eSMichael Baum {
18685d9252eSMichael Baum 	struct sockaddr_un un = {
18785d9252eSMichael Baum 		.sun_family = AF_UNIX,
18885d9252eSMichael Baum 	};
18985d9252eSMichael Baum 	int cmd_fd;
19085d9252eSMichael Baum 	int pd_handle;
19185d9252eSMichael Baum 	struct iovec iov = {
19285d9252eSMichael Baum 		.iov_base = &pd_handle,
19385d9252eSMichael Baum 		.iov_len = sizeof(int),
19485d9252eSMichael Baum 	};
19585d9252eSMichael Baum 	union {
19685d9252eSMichael Baum 		char buf[CMSG_SPACE(sizeof(int))];
19785d9252eSMichael Baum 		struct cmsghdr align;
19885d9252eSMichael Baum 	} control;
19985d9252eSMichael Baum 	struct msghdr msgh = {
20085d9252eSMichael Baum 		.msg_iov = NULL,
20185d9252eSMichael Baum 		.msg_iovlen = 0,
20285d9252eSMichael Baum 	};
20385d9252eSMichael Baum 	struct cmsghdr *cmsg;
20485d9252eSMichael Baum 	const char *path = mlx5_test_get_socket_path(extend + 1);
20585d9252eSMichael Baum 	size_t len = 1;
20685d9252eSMichael Baum 	int socket_fd;
20785d9252eSMichael Baum 	int ret;
20885d9252eSMichael Baum 
20985d9252eSMichael Baum 	if (path == NULL) {
21085d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Invalid devargs extension is specified\n");
21185d9252eSMichael Baum 		return -1;
21285d9252eSMichael Baum 	}
21385d9252eSMichael Baum 
21485d9252eSMichael Baum 	/* Initialize IPC channel. */
21585d9252eSMichael Baum 	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
21685d9252eSMichael Baum 	if (socket_fd < 0) {
21785d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to create unix socket: %s\n",
21885d9252eSMichael Baum 			    strerror(errno));
21985d9252eSMichael Baum 		return -1;
22085d9252eSMichael Baum 	}
22185d9252eSMichael Baum 	rte_strlcpy(un.sun_path, path, sizeof(un.sun_path));
22285d9252eSMichael Baum 	if (connect(socket_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
22385d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to connect %s: %s\n", un.sun_path,
22485d9252eSMichael Baum 			    strerror(errno));
22585d9252eSMichael Baum 		close(socket_fd);
22685d9252eSMichael Baum 		return -1;
22785d9252eSMichael Baum 	}
22885d9252eSMichael Baum 
22985d9252eSMichael Baum 	/* Send the request message. */
23085d9252eSMichael Baum 	do {
23185d9252eSMichael Baum 		ret = sendmsg(socket_fd, &msgh, 0);
23285d9252eSMichael Baum 	} while (ret < 0 && errno == EINTR);
23385d9252eSMichael Baum 	if (ret < 0) {
23485d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to send request to (%s): %s\n", path,
23585d9252eSMichael Baum 			    strerror(errno));
23685d9252eSMichael Baum 		close(socket_fd);
23785d9252eSMichael Baum 		return -1;
23885d9252eSMichael Baum 	}
23985d9252eSMichael Baum 
24085d9252eSMichael Baum 	msgh.msg_iov = &iov;
24185d9252eSMichael Baum 	msgh.msg_iovlen = 1;
24285d9252eSMichael Baum 	msgh.msg_control = control.buf;
24385d9252eSMichael Baum 	msgh.msg_controllen = sizeof(control.buf);
24485d9252eSMichael Baum 	do {
24585d9252eSMichael Baum 		ret = recvmsg(socket_fd, &msgh, 0);
24685d9252eSMichael Baum 	} while (ret < 0);
24785d9252eSMichael Baum 	if (ret != sizeof(int) || (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
24885d9252eSMichael Baum 		TESTPMD_LOG(ERR, "truncated msg");
24985d9252eSMichael Baum 		close(socket_fd);
25085d9252eSMichael Baum 		return -1;
25185d9252eSMichael Baum 	}
25285d9252eSMichael Baum 
25385d9252eSMichael Baum 	/* Translate the FD. */
25485d9252eSMichael Baum 	cmsg = CMSG_FIRSTHDR(&msgh);
25585d9252eSMichael Baum 	if (cmsg == NULL || cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
25685d9252eSMichael Baum 	    cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
25785d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Fail to get FD using SCM_RIGHTS mechanism\n");
25885d9252eSMichael Baum 		close(socket_fd);
25985d9252eSMichael Baum 		unlink(un.sun_path);
26085d9252eSMichael Baum 		return -1;
26185d9252eSMichael Baum 	}
26285d9252eSMichael Baum 	memcpy(&cmd_fd, CMSG_DATA(cmsg), sizeof(int));
26385d9252eSMichael Baum 
26485d9252eSMichael Baum 	TESTPMD_LOG(DEBUG, "Command FD (%d) and PD handle (%d) "
26585d9252eSMichael Baum 		    "are successfully imported from remote process\n",
26685d9252eSMichael Baum 		    cmd_fd, pd_handle);
26785d9252eSMichael Baum 
26885d9252eSMichael Baum 	/* Cleanup IPC channel. */
26985d9252eSMichael Baum 	close(socket_fd);
27085d9252eSMichael Baum 
27185d9252eSMichael Baum 	/* Calculate the new length of devargs string. */
27285d9252eSMichael Baum 	len += snprintf(NULL, 0, ",cmd_fd=%d,pd_handle=%d", cmd_fd, pd_handle);
27385d9252eSMichael Baum 	/* Extend the devargs string. */
27485d9252eSMichael Baum 	snprintf(extend, len, ",cmd_fd=%d,pd_handle=%d", cmd_fd, pd_handle);
27585d9252eSMichael Baum 
27685d9252eSMichael Baum 	TESTPMD_LOG(DEBUG, "Attach port with extra devargs %s\n", identifier);
27785d9252eSMichael Baum 	return 0;
27885d9252eSMichael Baum }
27985d9252eSMichael Baum 
28085d9252eSMichael Baum static bool
is_delimiter_path_spaces(char * extend)28185d9252eSMichael Baum is_delimiter_path_spaces(char *extend)
28285d9252eSMichael Baum {
28385d9252eSMichael Baum 	while (*extend != '\0') {
28485d9252eSMichael Baum 		if (*extend != ' ')
28585d9252eSMichael Baum 			return true;
28685d9252eSMichael Baum 		extend++;
28785d9252eSMichael Baum 	}
28885d9252eSMichael Baum 	return false;
28985d9252eSMichael Baum }
29085d9252eSMichael Baum 
29185d9252eSMichael Baum /*
29285d9252eSMichael Baum  * Extend devargs list with "cmd_fd" and "pd_handle" coming from external
29385d9252eSMichael Baum  * process. It happens only in this format:
29485d9252eSMichael Baum  *  testpmd> mlx5 port attach (identifier) socket=<socket path>
29585d9252eSMichael Baum  * all "(identifier) socket=<socket path>" is in the same string pointed
29685d9252eSMichael Baum  * by the input parameter 'identifier'.
29785d9252eSMichael Baum  *
29885d9252eSMichael Baum  * @param identifier
29985d9252eSMichael Baum  *   Identifier of port attach command line.
30085d9252eSMichael Baum  */
30185d9252eSMichael Baum static void
mlx5_test_attach_port_extend_devargs(char * identifier)30285d9252eSMichael Baum mlx5_test_attach_port_extend_devargs(char *identifier)
30385d9252eSMichael Baum {
30485d9252eSMichael Baum 	char *extend;
30585d9252eSMichael Baum 
30685d9252eSMichael Baum 	if (identifier == NULL) {
30785d9252eSMichael Baum 		fprintf(stderr, "Invalid parameters are specified\n");
30885d9252eSMichael Baum 		return;
30985d9252eSMichael Baum 	}
31085d9252eSMichael Baum 
31185d9252eSMichael Baum 	extend = strchr(identifier, ' ');
31285d9252eSMichael Baum 	if (extend != NULL && is_delimiter_path_spaces(extend) &&
31385d9252eSMichael Baum 	    mlx5_test_extend_devargs(identifier, extend) < 0) {
31485d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to extend devargs for port %s\n",
31585d9252eSMichael Baum 			    identifier);
31685d9252eSMichael Baum 		return;
31785d9252eSMichael Baum 	}
31885d9252eSMichael Baum 
31985d9252eSMichael Baum 	attach_port(identifier);
32085d9252eSMichael Baum }
32185d9252eSMichael Baum #endif
32285d9252eSMichael Baum 
3230683c002SMichael Baum static inline const char *
mode2string(uint8_t mode)3240683c002SMichael Baum mode2string(uint8_t mode)
3250683c002SMichael Baum {
3260683c002SMichael Baum 	switch (mode) {
3270683c002SMichael Baum 	case 0:
3280683c002SMichael Baum 		return "ignored\t";
3290683c002SMichael Baum 	case 1:
3300683c002SMichael Baum 		return "fixed\t";
3310683c002SMichael Baum 	case 2:
3320683c002SMichael Baum 		return "matchable";
3330683c002SMichael Baum 	default:
3340683c002SMichael Baum 		break;
3350683c002SMichael Baum 	}
3360683c002SMichael Baum 	return "unknown";
3370683c002SMichael Baum }
3380683c002SMichael Baum 
3390683c002SMichael Baum static inline uint8_t
string2mode(const char * mode)3400683c002SMichael Baum string2mode(const char *mode)
3410683c002SMichael Baum {
3420683c002SMichael Baum 	if (strcmp(mode, "ignored") == 0)
3430683c002SMichael Baum 		return 0;
3440683c002SMichael Baum 	if (strcmp(mode, "fixed") == 0)
3450683c002SMichael Baum 		return 1;
3460683c002SMichael Baum 	if (strcmp(mode, "matchable") == 0)
3470683c002SMichael Baum 		return 2;
3480683c002SMichael Baum 	return UINT8_MAX;
3490683c002SMichael Baum }
3500683c002SMichael Baum 
3510683c002SMichael Baum static int
mlx5_test_parse_geneve_option_data(const char * buff,uint8_t data_len,rte_be32_t ** match_data_mask)3520683c002SMichael Baum mlx5_test_parse_geneve_option_data(const char *buff, uint8_t data_len,
3530683c002SMichael Baum 				   rte_be32_t **match_data_mask)
3540683c002SMichael Baum {
3550683c002SMichael Baum 	rte_be32_t *data;
3560683c002SMichael Baum 	char *buff2;
3570683c002SMichael Baum 	char *token;
3580683c002SMichael Baum 	uint8_t i = 0;
3590683c002SMichael Baum 
3600683c002SMichael Baum 	if (data_len == 0) {
3610683c002SMichael Baum 		*match_data_mask = NULL;
3620683c002SMichael Baum 		return 0;
3630683c002SMichael Baum 	}
3640683c002SMichael Baum 
3650683c002SMichael Baum 	data = calloc(data_len, sizeof(rte_be32_t));
3660683c002SMichael Baum 	if (data == NULL) {
3670683c002SMichael Baum 		TESTPMD_LOG(ERR, "Fail to allocate memory for GENEVE TLV option data\n");
3680683c002SMichael Baum 		return -ENOMEM;
3690683c002SMichael Baum 	}
3700683c002SMichael Baum 
3710683c002SMichael Baum 	buff2 = strdup(buff);
3720683c002SMichael Baum 	if (buff2 == NULL) {
3730683c002SMichael Baum 		TESTPMD_LOG(ERR,
3740683c002SMichael Baum 			    "Fail to duplicate GENEVE TLV option data string (%s)\n",
3750683c002SMichael Baum 			    buff);
3760683c002SMichael Baum 		free(data);
3770683c002SMichael Baum 		return -ENOMEM;
3780683c002SMichael Baum 	}
3790683c002SMichael Baum 
3800683c002SMichael Baum 	token = strtok(buff2, SPACE_DELIMITER);
3810683c002SMichael Baum 	while (token != NULL) {
3820683c002SMichael Baum 		if (i == data_len) {
3830683c002SMichael Baum 			TESTPMD_LOG(ERR,
3840683c002SMichael Baum 				    "GENEVE TLV option has more data then given data length %u\n",
3850683c002SMichael Baum 				    data_len);
3860683c002SMichael Baum 			free(buff2);
3870683c002SMichael Baum 			free(data);
3880683c002SMichael Baum 			return -EINVAL;
3890683c002SMichael Baum 		}
3900683c002SMichael Baum 
3910683c002SMichael Baum 		if (strcmp(token, "0xffffffff") == 0)
3920683c002SMichael Baum 			data[i] = 0xffffffff;
3930683c002SMichael Baum 		else
3940683c002SMichael Baum 			data[i] = 0x0;
3950683c002SMichael Baum 
3960683c002SMichael Baum 		token = strtok(NULL, SPACE_DELIMITER);
3970683c002SMichael Baum 		i++;
3980683c002SMichael Baum 	}
3990683c002SMichael Baum 
4000683c002SMichael Baum 	free(buff2);
4010683c002SMichael Baum 	*match_data_mask = data;
4020683c002SMichael Baum 	return 0;
4030683c002SMichael Baum }
4040683c002SMichael Baum 
405f41a5092SSpike Du /* *** SET HOST_SHAPER FOR A PORT *** */
406f41a5092SSpike Du struct cmd_port_host_shaper_result {
407f41a5092SSpike Du 	cmdline_fixed_string_t mlx5;
408f41a5092SSpike Du 	cmdline_fixed_string_t set;
409f41a5092SSpike Du 	cmdline_fixed_string_t port;
410f41a5092SSpike Du 	uint16_t port_num;
411f41a5092SSpike Du 	cmdline_fixed_string_t host_shaper;
412f41a5092SSpike Du 	cmdline_fixed_string_t avail_thresh_triggered;
413f41a5092SSpike Du 	uint16_t fr;
414f41a5092SSpike Du 	cmdline_fixed_string_t rate;
415f41a5092SSpike Du 	uint8_t rate_num;
416f41a5092SSpike Du };
417f41a5092SSpike Du 
cmd_port_host_shaper_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)418f41a5092SSpike Du static void cmd_port_host_shaper_parsed(void *parsed_result,
419f41a5092SSpike Du 		__rte_unused struct cmdline *cl,
420f41a5092SSpike Du 		__rte_unused void *data)
421f41a5092SSpike Du {
422f41a5092SSpike Du 	struct cmd_port_host_shaper_result *res = parsed_result;
423f41a5092SSpike Du 	int ret = 0;
424f41a5092SSpike Du 
425f41a5092SSpike Du 	if ((strcmp(res->mlx5, "mlx5") == 0) &&
426f41a5092SSpike Du 	    (strcmp(res->set, "set") == 0) &&
427f41a5092SSpike Du 	    (strcmp(res->port, "port") == 0) &&
428f41a5092SSpike Du 	    (strcmp(res->host_shaper, "host_shaper") == 0) &&
429f41a5092SSpike Du 	    (strcmp(res->avail_thresh_triggered, "avail_thresh_triggered") == 0) &&
430f41a5092SSpike Du 	    (strcmp(res->rate, "rate") == 0))
431f41a5092SSpike Du 		ret = mlx5_test_set_port_host_shaper(res->port_num, res->fr,
432f41a5092SSpike Du 					   res->rate_num);
433f41a5092SSpike Du 	if (ret < 0)
434f41a5092SSpike Du 		printf("cmd_port_host_shaper error: (%s)\n", strerror(-ret));
435f41a5092SSpike Du }
436f41a5092SSpike Du 
437f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_mlx5 =
438f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
439f41a5092SSpike Du 				mlx5, "mlx5");
440f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_set =
441f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
442f41a5092SSpike Du 				set, "set");
443f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_port =
444f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
445f41a5092SSpike Du 				port, "port");
446f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_portnum =
447f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
448f41a5092SSpike Du 				port_num, RTE_UINT16);
449f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_host_shaper =
450f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
451f41a5092SSpike Du 				 host_shaper, "host_shaper");
452f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_avail_thresh_triggered =
453f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
454f41a5092SSpike Du 				 avail_thresh_triggered, "avail_thresh_triggered");
455f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_fr =
456f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
457f41a5092SSpike Du 			      fr, RTE_UINT16);
458f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_rate =
459f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
460f41a5092SSpike Du 				 rate, "rate");
461f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_rate_num =
462f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
463f41a5092SSpike Du 			      rate_num, RTE_UINT8);
464f41a5092SSpike Du static cmdline_parse_inst_t mlx5_test_cmd_port_host_shaper = {
465f41a5092SSpike Du 	.f = cmd_port_host_shaper_parsed,
466f41a5092SSpike Du 	.data = (void *)0,
467f41a5092SSpike Du 	.help_str = "mlx5 set port <port_id> host_shaper avail_thresh_triggered <0|1> "
468f41a5092SSpike Du 	"rate <rate_num>: Set HOST_SHAPER avail_thresh_triggered and rate with port_id",
469f41a5092SSpike Du 	.tokens = {
470f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_mlx5,
471f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_set,
472f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_port,
473f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_portnum,
474f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_host_shaper,
475f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_avail_thresh_triggered,
476f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_fr,
477f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate,
478f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate_num,
479f41a5092SSpike Du 		NULL,
480f41a5092SSpike Du 	}
481f41a5092SSpike Du };
482f41a5092SSpike Du 
48385d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
48485d9252eSMichael Baum /* *** attach a specified port *** */
48585d9252eSMichael Baum struct mlx5_cmd_operate_attach_port_result {
48685d9252eSMichael Baum 	cmdline_fixed_string_t mlx5;
48785d9252eSMichael Baum 	cmdline_fixed_string_t port;
48885d9252eSMichael Baum 	cmdline_fixed_string_t keyword;
48985d9252eSMichael Baum 	cmdline_multi_string_t identifier;
49085d9252eSMichael Baum };
49185d9252eSMichael Baum 
mlx5_cmd_operate_attach_port_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)49285d9252eSMichael Baum static void mlx5_cmd_operate_attach_port_parsed(void *parsed_result,
49385d9252eSMichael Baum 						__rte_unused struct cmdline *cl,
49485d9252eSMichael Baum 						__rte_unused void *data)
49585d9252eSMichael Baum {
49685d9252eSMichael Baum 	struct mlx5_cmd_operate_attach_port_result *res = parsed_result;
49785d9252eSMichael Baum 
49885d9252eSMichael Baum 	if (!strcmp(res->keyword, "attach"))
49985d9252eSMichael Baum 		mlx5_test_attach_port_extend_devargs(res->identifier);
50085d9252eSMichael Baum 	else
50185d9252eSMichael Baum 		fprintf(stderr, "Unknown parameter\n");
50285d9252eSMichael Baum }
50385d9252eSMichael Baum 
50485d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_mlx5 =
50585d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
50685d9252eSMichael Baum 				 mlx5, "mlx5");
50785d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_port =
50885d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
50985d9252eSMichael Baum 				 port, "port");
51085d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_keyword =
51185d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
51285d9252eSMichael Baum 				 keyword, "attach");
51385d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_identifier =
51485d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
51585d9252eSMichael Baum 				 identifier, TOKEN_STRING_MULTI);
51685d9252eSMichael Baum 
51785d9252eSMichael Baum static cmdline_parse_inst_t mlx5_cmd_operate_attach_port = {
51885d9252eSMichael Baum 	.f = mlx5_cmd_operate_attach_port_parsed,
51985d9252eSMichael Baum 	.data = NULL,
52085d9252eSMichael Baum 	.help_str = "mlx5 port attach <identifier> socket=<path>: "
52185d9252eSMichael Baum 		"(identifier: pci address or virtual dev name"
52285d9252eSMichael Baum 		", path (optional): socket path to get cmd FD and PD handle)",
52385d9252eSMichael Baum 	.tokens = {
52485d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_mlx5,
52585d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_port,
52685d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_keyword,
52785d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_identifier,
52885d9252eSMichael Baum 		NULL,
52985d9252eSMichael Baum 	},
53085d9252eSMichael Baum };
53185d9252eSMichael Baum #endif
53285d9252eSMichael Baum 
533740a2836SMichael Baum /* Map HW queue index to rte queue index. */
534740a2836SMichael Baum struct mlx5_cmd_map_ext_rxq {
535740a2836SMichael Baum 	cmdline_fixed_string_t mlx5;
536740a2836SMichael Baum 	cmdline_fixed_string_t port;
537740a2836SMichael Baum 	portid_t port_id;
538740a2836SMichael Baum 	cmdline_fixed_string_t ext_rxq;
539740a2836SMichael Baum 	cmdline_fixed_string_t map;
540740a2836SMichael Baum 	uint16_t sw_queue_id;
541740a2836SMichael Baum 	uint32_t hw_queue_id;
542740a2836SMichael Baum };
543740a2836SMichael Baum 
544740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_mlx5 =
545740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, mlx5, "mlx5");
546740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_port =
547740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, port, "port");
548740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_port_id =
549740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, port_id, RTE_UINT16);
550740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_ext_rxq =
551740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, ext_rxq,
552740a2836SMichael Baum 				 "ext_rxq");
553740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_map =
554740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, map, "map");
555740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_sw_queue_id =
556740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, sw_queue_id,
557740a2836SMichael Baum 			      RTE_UINT16);
558740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_hw_queue_id =
559740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, hw_queue_id,
560740a2836SMichael Baum 			      RTE_UINT32);
561740a2836SMichael Baum 
562740a2836SMichael Baum static void
mlx5_cmd_map_ext_rxq_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)563740a2836SMichael Baum mlx5_cmd_map_ext_rxq_parsed(void *parsed_result,
564740a2836SMichael Baum 			    __rte_unused struct cmdline *cl,
565740a2836SMichael Baum 			    __rte_unused void *data)
566740a2836SMichael Baum {
567740a2836SMichael Baum 	struct mlx5_cmd_map_ext_rxq *res = parsed_result;
568740a2836SMichael Baum 	int ret;
569740a2836SMichael Baum 
570740a2836SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
571740a2836SMichael Baum 		return;
572740a2836SMichael Baum 	ret = rte_pmd_mlx5_external_rx_queue_id_map(res->port_id,
573740a2836SMichael Baum 						    res->sw_queue_id,
574740a2836SMichael Baum 						    res->hw_queue_id);
575740a2836SMichael Baum 	switch (ret) {
576740a2836SMichael Baum 	case 0:
577740a2836SMichael Baum 		break;
578740a2836SMichael Baum 	case -EINVAL:
579740a2836SMichael Baum 		fprintf(stderr, "invalid ethdev index (%u), out of range\n",
580740a2836SMichael Baum 			res->sw_queue_id);
581740a2836SMichael Baum 		break;
582740a2836SMichael Baum 	case -ENODEV:
583740a2836SMichael Baum 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
584740a2836SMichael Baum 		break;
585740a2836SMichael Baum 	case -ENOTSUP:
586740a2836SMichael Baum 		fprintf(stderr, "function not implemented or supported\n");
587740a2836SMichael Baum 		break;
588740a2836SMichael Baum 	case -EEXIST:
589740a2836SMichael Baum 		fprintf(stderr, "mapping with index %u already exists\n",
590740a2836SMichael Baum 			res->sw_queue_id);
591740a2836SMichael Baum 		break;
592740a2836SMichael Baum 	default:
593740a2836SMichael Baum 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
594740a2836SMichael Baum 	}
595740a2836SMichael Baum }
596740a2836SMichael Baum 
597740a2836SMichael Baum cmdline_parse_inst_t mlx5_cmd_map_ext_rxq = {
598740a2836SMichael Baum 	.f = mlx5_cmd_map_ext_rxq_parsed,
599740a2836SMichael Baum 	.data = NULL,
600740a2836SMichael Baum 	.help_str = "mlx5 port <port_id> ext_rxq map <sw_queue_id> <hw_queue_id>",
601740a2836SMichael Baum 	.tokens = {
602740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_mlx5,
603740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_port,
604740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_port_id,
605740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_ext_rxq,
606740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_map,
607740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_sw_queue_id,
608740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_hw_queue_id,
609740a2836SMichael Baum 		NULL,
610740a2836SMichael Baum 	}
611740a2836SMichael Baum };
612740a2836SMichael Baum 
613740a2836SMichael Baum /* Unmap HW queue index to rte queue index. */
614740a2836SMichael Baum struct mlx5_cmd_unmap_ext_rxq {
615740a2836SMichael Baum 	cmdline_fixed_string_t mlx5;
616740a2836SMichael Baum 	cmdline_fixed_string_t port;
617740a2836SMichael Baum 	portid_t port_id;
618740a2836SMichael Baum 	cmdline_fixed_string_t ext_rxq;
619740a2836SMichael Baum 	cmdline_fixed_string_t unmap;
620740a2836SMichael Baum 	uint16_t queue_id;
621740a2836SMichael Baum };
622740a2836SMichael Baum 
623740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_mlx5 =
624740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, mlx5, "mlx5");
625740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_port =
626740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, port, "port");
627740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_unmap_ext_rxq_port_id =
628740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, port_id,
629740a2836SMichael Baum 			      RTE_UINT16);
630740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_ext_rxq =
631740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, ext_rxq,
632740a2836SMichael Baum 				 "ext_rxq");
633740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_unmap =
634740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, unmap, "unmap");
635740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_unmap_ext_rxq_queue_id =
636740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, queue_id,
637740a2836SMichael Baum 			      RTE_UINT16);
638740a2836SMichael Baum 
639740a2836SMichael Baum static void
mlx5_cmd_unmap_ext_rxq_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)640740a2836SMichael Baum mlx5_cmd_unmap_ext_rxq_parsed(void *parsed_result,
641740a2836SMichael Baum 			      __rte_unused struct cmdline *cl,
642740a2836SMichael Baum 			      __rte_unused void *data)
643740a2836SMichael Baum {
644740a2836SMichael Baum 	struct mlx5_cmd_unmap_ext_rxq *res = parsed_result;
645740a2836SMichael Baum 	int ret;
646740a2836SMichael Baum 
647740a2836SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
648740a2836SMichael Baum 		return;
649740a2836SMichael Baum 	ret = rte_pmd_mlx5_external_rx_queue_id_unmap(res->port_id,
650740a2836SMichael Baum 						      res->queue_id);
651740a2836SMichael Baum 	switch (ret) {
652740a2836SMichael Baum 	case 0:
653740a2836SMichael Baum 		break;
654740a2836SMichael Baum 	case -EINVAL:
655740a2836SMichael Baum 		fprintf(stderr, "invalid rte_flow index (%u), "
656740a2836SMichael Baum 			"out of range, doesn't exist or still referenced\n",
657740a2836SMichael Baum 			res->queue_id);
658740a2836SMichael Baum 		break;
659740a2836SMichael Baum 	case -ENODEV:
660740a2836SMichael Baum 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
661740a2836SMichael Baum 		break;
662740a2836SMichael Baum 	case -ENOTSUP:
663740a2836SMichael Baum 		fprintf(stderr, "function not implemented or supported\n");
664740a2836SMichael Baum 		break;
665740a2836SMichael Baum 	default:
666740a2836SMichael Baum 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
667740a2836SMichael Baum 	}
668740a2836SMichael Baum }
669740a2836SMichael Baum 
670740a2836SMichael Baum cmdline_parse_inst_t mlx5_cmd_unmap_ext_rxq = {
671740a2836SMichael Baum 	.f = mlx5_cmd_unmap_ext_rxq_parsed,
672740a2836SMichael Baum 	.data = NULL,
673740a2836SMichael Baum 	.help_str = "mlx5 port <port_id> ext_rxq unmap <queue_id>",
674740a2836SMichael Baum 	.tokens = {
675740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_mlx5,
676740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_port,
677740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_port_id,
678740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_ext_rxq,
679740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_unmap,
680740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_queue_id,
681740a2836SMichael Baum 		NULL,
682740a2836SMichael Baum 	}
683740a2836SMichael Baum };
684740a2836SMichael Baum 
685baafc81eSRongwei Liu /* Set flow engine mode with flags command. */
686baafc81eSRongwei Liu struct mlx5_cmd_set_flow_engine_mode {
687baafc81eSRongwei Liu 	cmdline_fixed_string_t mlx5;
688baafc81eSRongwei Liu 	cmdline_fixed_string_t set;
689baafc81eSRongwei Liu 	cmdline_fixed_string_t flow_engine;
690baafc81eSRongwei Liu 	cmdline_multi_string_t mode;
691baafc81eSRongwei Liu };
692baafc81eSRongwei Liu 
693baafc81eSRongwei Liu static int
parse_multi_token_flow_engine_mode(char * t_str,enum rte_pmd_mlx5_flow_engine_mode * mode,uint32_t * flag)69486647d46SThomas Monjalon parse_multi_token_flow_engine_mode(char *t_str,
69586647d46SThomas Monjalon 		enum rte_pmd_mlx5_flow_engine_mode *mode, uint32_t *flag)
696baafc81eSRongwei Liu {
697baafc81eSRongwei Liu 	uint64_t val;
698baafc81eSRongwei Liu 	char *token;
699baafc81eSRongwei Liu 	int ret;
700baafc81eSRongwei Liu 
701baafc81eSRongwei Liu 	*flag = 0;
702baafc81eSRongwei Liu 	/* First token: mode string */
703baafc81eSRongwei Liu 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
704baafc81eSRongwei Liu 	if (token ==  NULL)
705baafc81eSRongwei Liu 		return -1;
706baafc81eSRongwei Liu 
707baafc81eSRongwei Liu 	if (!strcmp(token, "active"))
70886647d46SThomas Monjalon 		*mode = RTE_PMD_MLX5_FLOW_ENGINE_MODE_ACTIVE;
709baafc81eSRongwei Liu 	else if (!strcmp(token, "standby"))
71086647d46SThomas Monjalon 		*mode = RTE_PMD_MLX5_FLOW_ENGINE_MODE_STANDBY;
711baafc81eSRongwei Liu 	else
712baafc81eSRongwei Liu 		return -1;
713baafc81eSRongwei Liu 
714baafc81eSRongwei Liu 	/* Second token: flag */
715baafc81eSRongwei Liu 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
716baafc81eSRongwei Liu 	if (token == NULL)
717baafc81eSRongwei Liu 		return 0;
718baafc81eSRongwei Liu 
719baafc81eSRongwei Liu 	ret = parse_uint(&val, token);
720baafc81eSRongwei Liu 	if (ret != 0 || val > UINT32_MAX)
721baafc81eSRongwei Liu 		return -1;
722baafc81eSRongwei Liu 
723baafc81eSRongwei Liu 	*flag = val;
724baafc81eSRongwei Liu 	return 0;
725baafc81eSRongwei Liu }
726baafc81eSRongwei Liu 
727baafc81eSRongwei Liu static void
mlx5_cmd_set_flow_engine_mode_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)728baafc81eSRongwei Liu mlx5_cmd_set_flow_engine_mode_parsed(void *parsed_result,
729baafc81eSRongwei Liu 				     __rte_unused struct cmdline *cl,
730baafc81eSRongwei Liu 				     __rte_unused void *data)
731baafc81eSRongwei Liu {
732baafc81eSRongwei Liu 	struct mlx5_cmd_set_flow_engine_mode *res = parsed_result;
73386647d46SThomas Monjalon 	enum rte_pmd_mlx5_flow_engine_mode mode;
734baafc81eSRongwei Liu 	uint32_t flag;
735baafc81eSRongwei Liu 	int ret;
736baafc81eSRongwei Liu 
737baafc81eSRongwei Liu 	ret = parse_multi_token_flow_engine_mode(res->mode, &mode, &flag);
738baafc81eSRongwei Liu 
739baafc81eSRongwei Liu 	if (ret < 0) {
740baafc81eSRongwei Liu 		fprintf(stderr, "Bad input\n");
741baafc81eSRongwei Liu 		return;
742baafc81eSRongwei Liu 	}
743baafc81eSRongwei Liu 
744baafc81eSRongwei Liu 	ret = rte_pmd_mlx5_flow_engine_set_mode(mode, flag);
745baafc81eSRongwei Liu 
746baafc81eSRongwei Liu 	if (ret < 0)
747baafc81eSRongwei Liu 		fprintf(stderr, "Fail to set flow_engine to %s mode with flag 0x%x, error %s\n",
74886647d46SThomas Monjalon 			mode == RTE_PMD_MLX5_FLOW_ENGINE_MODE_ACTIVE ? "active" : "standby", flag,
749baafc81eSRongwei Liu 			strerror(-ret));
750baafc81eSRongwei Liu 	else
751baafc81eSRongwei Liu 		TESTPMD_LOG(DEBUG, "Set %d ports flow_engine to %s mode with flag 0x%x\n", ret,
75286647d46SThomas Monjalon 			mode == RTE_PMD_MLX5_FLOW_ENGINE_MODE_ACTIVE ? "active" : "standby", flag);
753baafc81eSRongwei Liu }
754baafc81eSRongwei Liu 
755baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_mlx5 =
756baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, mlx5,
757baafc81eSRongwei Liu 				 "mlx5");
758baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_set =
759baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, set,
760baafc81eSRongwei Liu 				 "set");
761baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_flow_engine =
762baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, flow_engine,
763baafc81eSRongwei Liu 				 "flow_engine");
764baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_mode =
765baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, mode,
766baafc81eSRongwei Liu 				 TOKEN_STRING_MULTI);
767baafc81eSRongwei Liu 
768baafc81eSRongwei Liu cmdline_parse_inst_t mlx5_cmd_set_flow_engine_mode = {
769baafc81eSRongwei Liu 	.f = &mlx5_cmd_set_flow_engine_mode_parsed,
770baafc81eSRongwei Liu 	.data = NULL,
771baafc81eSRongwei Liu 	.help_str = "mlx5 set flow_engine <active|standby> [<flag>]",
772baafc81eSRongwei Liu 	.tokens = {
773baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_mlx5,
774baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_set,
775baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_flow_engine,
776baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_mode,
777baafc81eSRongwei Liu 		NULL,
778baafc81eSRongwei Liu 	}
779baafc81eSRongwei Liu };
780baafc81eSRongwei Liu 
7810683c002SMichael Baum /* Prepare single GENEVE TLV option and add it into global option list. */
7820683c002SMichael Baum struct mlx5_cmd_set_tlv_option {
7830683c002SMichael Baum 	cmdline_fixed_string_t mlx5;
7840683c002SMichael Baum 	cmdline_fixed_string_t set;
7850683c002SMichael Baum 	cmdline_fixed_string_t tlv_option;
7860683c002SMichael Baum 	cmdline_fixed_string_t class;
7870683c002SMichael Baum 	uint16_t class_id;
7880683c002SMichael Baum 	cmdline_fixed_string_t type;
7890683c002SMichael Baum 	uint8_t type_id;
7900683c002SMichael Baum 	cmdline_fixed_string_t len;
7910683c002SMichael Baum 	uint8_t option_len;
7920683c002SMichael Baum 	cmdline_fixed_string_t offset;
7930683c002SMichael Baum 	uint8_t off;
7940683c002SMichael Baum 	cmdline_fixed_string_t sample_len;
7950683c002SMichael Baum 	uint8_t length;
7960683c002SMichael Baum 	cmdline_fixed_string_t class_mode;
7970683c002SMichael Baum 	cmdline_fixed_string_t cmode;
7980683c002SMichael Baum 	cmdline_fixed_string_t data;
7990683c002SMichael Baum 	cmdline_fixed_string_t data_mask;
8000683c002SMichael Baum };
8010683c002SMichael Baum 
8020683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_mlx5 =
8030683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, mlx5, "mlx5");
8040683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_set =
8050683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, set, "set");
8060683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_tlv_option =
8070683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, tlv_option,
8080683c002SMichael Baum 				 "tlv_option");
8090683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_class =
8100683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, class,
8110683c002SMichael Baum 				 "class");
8120683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_set_tlv_option_class_id =
8130683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_set_tlv_option, class_id,
8140683c002SMichael Baum 			      RTE_UINT16);
8150683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_type =
8160683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, type, "type");
8170683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_set_tlv_option_type_id =
8180683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_set_tlv_option, type_id,
8190683c002SMichael Baum 			      RTE_UINT8);
8200683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_len =
8210683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, len, "len");
8220683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_set_tlv_option_option_len =
8230683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_set_tlv_option, option_len,
8240683c002SMichael Baum 			      RTE_UINT8);
8250683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_offset =
8260683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, offset,
8270683c002SMichael Baum 				 "offset");
8280683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_set_tlv_option_off =
8290683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_set_tlv_option, off, RTE_UINT8);
8300683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_sample_len =
8310683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, sample_len,
8320683c002SMichael Baum 				 "sample_len");
8330683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_set_tlv_option_length =
8340683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_set_tlv_option, length,
8350683c002SMichael Baum 			      RTE_UINT8);
8360683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_class_mode =
8370683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, class_mode,
8380683c002SMichael Baum 				 "class_mode");
8390683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_cmode =
8400683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, cmode,
8410683c002SMichael Baum 				 "ignored#fixed#matchable");
8420683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_data =
8430683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, data, "data");
8440683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_set_tlv_option_data_mask =
8450683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_tlv_option, data_mask, "");
8460683c002SMichael Baum 
8470683c002SMichael Baum static void
mlx5_cmd_set_tlv_option_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)8480683c002SMichael Baum mlx5_cmd_set_tlv_option_parsed(void *parsed_result,
8490683c002SMichael Baum 			       __rte_unused struct cmdline *cl,
8500683c002SMichael Baum 			       __rte_unused void *data)
8510683c002SMichael Baum {
8520683c002SMichael Baum 	struct mlx5_cmd_set_tlv_option *res = parsed_result;
8530683c002SMichael Baum 	struct rte_pmd_mlx5_geneve_tlv *option;
8540683c002SMichael Baum 	uint8_t class_mode;
8550683c002SMichael Baum 	int ret;
8560683c002SMichael Baum 
8570683c002SMichael Baum 	if (tlv_mng.nb_options == MAX_GENEVE_OPTIONS_RESOURCES) {
8580683c002SMichael Baum 		fprintf(stderr, "GENEVE TLV option list is full\n");
8590683c002SMichael Baum 		return;
8600683c002SMichael Baum 	}
8610683c002SMichael Baum 
8620683c002SMichael Baum 	if (res->option_len < res->length + res->off) {
8630683c002SMichael Baum 		fprintf(stderr,
8640683c002SMichael Baum 			"GENEVE TLV option length (%u) cannot be less than offset (%u) + sample_len (%u)\n",
8650683c002SMichael Baum 			res->option_len, res->length, res->off);
8660683c002SMichael Baum 		return;
8670683c002SMichael Baum 	}
8680683c002SMichael Baum 
8690683c002SMichael Baum 	if (res->option_len > 32) {
8700683c002SMichael Baum 		fprintf(stderr,
8710683c002SMichael Baum 			"GENEVE TLV option length (%u) must be less than 32\n",
8720683c002SMichael Baum 			res->option_len);
8730683c002SMichael Baum 		return;
8740683c002SMichael Baum 	}
8750683c002SMichael Baum 
8760683c002SMichael Baum 	class_mode = string2mode(res->cmode);
8770683c002SMichael Baum 	if (class_mode == UINT8_MAX) {
8780683c002SMichael Baum 		fprintf(stderr, "Invalid class mode \"%s\"\n", res->cmode);
8790683c002SMichael Baum 		return;
8800683c002SMichael Baum 	}
8810683c002SMichael Baum 
8820683c002SMichael Baum 	if (res->length > 0) {
8830683c002SMichael Baum 		if (strcmp(res->data, "data") || !strcmp(res->data_mask, "")) {
8840683c002SMichael Baum 			fprintf(stderr,
8850683c002SMichael Baum 				"sample_len is %u but any data isn't provided\n",
8860683c002SMichael Baum 				res->length);
8870683c002SMichael Baum 			return;
8880683c002SMichael Baum 		}
8890683c002SMichael Baum 	} else {
8900683c002SMichael Baum 		if (!strcmp(res->data, "data") && strcmp(res->data_mask, "")) {
8910683c002SMichael Baum 			fprintf(stderr,
8920683c002SMichael Baum 				"sample_len is 0 but data is provided (%s)\n",
8930683c002SMichael Baum 				res->data_mask);
8940683c002SMichael Baum 			return;
8950683c002SMichael Baum 		}
8960683c002SMichael Baum 	}
8970683c002SMichael Baum 
8980683c002SMichael Baum 	option = &tlv_mng.tlv_list[tlv_mng.nb_options];
8990683c002SMichael Baum 	ret = mlx5_test_parse_geneve_option_data(res->data_mask, res->length,
9000683c002SMichael Baum 						 &option->match_data_mask);
9010683c002SMichael Baum 	if (ret < 0)
9020683c002SMichael Baum 		return;
9030683c002SMichael Baum 
9040683c002SMichael Baum 	option->match_on_class_mode = class_mode;
9050683c002SMichael Baum 	option->option_class = rte_cpu_to_be_16(res->class_id);
9060683c002SMichael Baum 	option->option_type = res->type_id;
9070683c002SMichael Baum 	option->option_len = res->option_len;
9080683c002SMichael Baum 	option->offset = res->off;
9090683c002SMichael Baum 	option->sample_len = res->length;
9100683c002SMichael Baum 	tlv_mng.nb_options++;
9110683c002SMichael Baum 
9120683c002SMichael Baum 	TESTPMD_LOG(DEBUG,
9130683c002SMichael Baum 		    "set new option in global list, now it has %u options\n",
9140683c002SMichael Baum 		    tlv_mng.nb_options);
9150683c002SMichael Baum }
9160683c002SMichael Baum 
9170683c002SMichael Baum cmdline_parse_inst_t mlx5_cmd_set_tlv_option = {
9180683c002SMichael Baum 	.f = mlx5_cmd_set_tlv_option_parsed,
9190683c002SMichael Baum 	.data = NULL,
9200683c002SMichael Baum 	.help_str = "mlx5 set tlv_option class <class_id> type <type_id> len "
9210683c002SMichael Baum 		"<option_len> offset <sample_offset> sample_len "
9220683c002SMichael Baum 		"<sample_length> class_mode <ignored|fixed|matchable> data <mask1 [mask2 [...]>",
9230683c002SMichael Baum 	.tokens = {
9240683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_mlx5,
9250683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_set,
9260683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_tlv_option,
9270683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_class,
9280683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_class_id,
9290683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_type,
9300683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_type_id,
9310683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_len,
9320683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_option_len,
9330683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_offset,
9340683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_off,
9350683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_sample_len,
9360683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_length,
9370683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_class_mode,
9380683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_cmode,
9390683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_data,
9400683c002SMichael Baum 		(void *)&mlx5_cmd_set_tlv_option_data_mask,
9410683c002SMichael Baum 		NULL,
9420683c002SMichael Baum 	}
9430683c002SMichael Baum };
9440683c002SMichael Baum 
9450683c002SMichael Baum /* Print all GENEVE TLV options which are configured so far. */
9460683c002SMichael Baum struct mlx5_cmd_list_tlv_options {
9470683c002SMichael Baum 	cmdline_fixed_string_t mlx5;
9480683c002SMichael Baum 	cmdline_fixed_string_t list;
9490683c002SMichael Baum 	cmdline_fixed_string_t tlv_options;
9500683c002SMichael Baum };
9510683c002SMichael Baum 
9520683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_list_tlv_options_mlx5 =
9530683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_list_tlv_options, mlx5,
9540683c002SMichael Baum 				 "mlx5");
9550683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_list_tlv_options_list =
9560683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_list_tlv_options, list,
9570683c002SMichael Baum 				 "list");
9580683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_list_tlv_options_tlv_options =
9590683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_list_tlv_options, tlv_options,
9600683c002SMichael Baum 				 "tlv_options");
9610683c002SMichael Baum 
9620683c002SMichael Baum static void
mlx5_cmd_list_tlv_options_parsed(__rte_unused void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)9630683c002SMichael Baum mlx5_cmd_list_tlv_options_parsed(__rte_unused void *parsed_result,
9640683c002SMichael Baum 				 __rte_unused struct cmdline *cl,
9650683c002SMichael Baum 				 __rte_unused void *data)
9660683c002SMichael Baum {
9670683c002SMichael Baum 	struct rte_pmd_mlx5_geneve_tlv *option;
9680683c002SMichael Baum 	uint8_t i, j;
9690683c002SMichael Baum 
9700683c002SMichael Baum 	printf("ID\tType\tClass\tClass_mode\tLen\tOffset\tSample_len\tData\n");
9710683c002SMichael Baum 	for (i = 0; i < tlv_mng.nb_options; ++i) {
9720683c002SMichael Baum 		option = &tlv_mng.tlv_list[i];
9730683c002SMichael Baum 		printf("%u\t%u\t%u\t%s\t%u\t%u\t%u\t\t", i,
9740683c002SMichael Baum 		       option->option_type, rte_be_to_cpu_16(option->option_class),
9750683c002SMichael Baum 		       mode2string(option->match_on_class_mode),
9760683c002SMichael Baum 		       option->option_len,
9770683c002SMichael Baum 		       option->offset, option->sample_len);
9780683c002SMichael Baum 		for (j = 0; j < option->sample_len; ++j)
9790683c002SMichael Baum 			printf("0x%x ", option->match_data_mask[j]);
9800683c002SMichael Baum 		printf("\n");
9810683c002SMichael Baum 	}
9820683c002SMichael Baum }
9830683c002SMichael Baum 
9840683c002SMichael Baum cmdline_parse_inst_t mlx5_cmd_list_tlv_options = {
9850683c002SMichael Baum 	.f = mlx5_cmd_list_tlv_options_parsed,
9860683c002SMichael Baum 	.data = NULL,
9870683c002SMichael Baum 	.help_str = "mlx5 list tlv_options",
9880683c002SMichael Baum 	.tokens = {
9890683c002SMichael Baum 		(void *)&mlx5_cmd_list_tlv_options_mlx5,
9900683c002SMichael Baum 		(void *)&mlx5_cmd_list_tlv_options_list,
9910683c002SMichael Baum 		(void *)&mlx5_cmd_list_tlv_options_tlv_options,
9920683c002SMichael Baum 		NULL,
9930683c002SMichael Baum 	}
9940683c002SMichael Baum };
9950683c002SMichael Baum 
9960683c002SMichael Baum /* Clear all GENEVE TLV options which are configured so far. */
9970683c002SMichael Baum struct mlx5_cmd_flush_tlv_options {
9980683c002SMichael Baum 	cmdline_fixed_string_t mlx5;
9990683c002SMichael Baum 	cmdline_fixed_string_t flush;
10000683c002SMichael Baum 	cmdline_fixed_string_t tlv_options;
10010683c002SMichael Baum 	cmdline_fixed_string_t max;
10020683c002SMichael Baum 	uint8_t number;
10030683c002SMichael Baum };
10040683c002SMichael Baum 
10050683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_flush_tlv_options_mlx5 =
10060683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_flush_tlv_options, mlx5,
10070683c002SMichael Baum 				 "mlx5");
10080683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_flush_tlv_options_flush =
10090683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_flush_tlv_options, flush,
10100683c002SMichael Baum 				 "flush");
10110683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_flush_tlv_options_tlv_options =
10120683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_flush_tlv_options, tlv_options,
10130683c002SMichael Baum 				 "tlv_options");
10140683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_flush_tlv_options_max =
10150683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_flush_tlv_options, max, "max");
10160683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_flush_tlv_options_number =
10170683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_flush_tlv_options, number,
10180683c002SMichael Baum 			      RTE_UINT8);
10190683c002SMichael Baum 
10200683c002SMichael Baum static void
mlx5_cmd_flush_tlv_options_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)10210683c002SMichael Baum mlx5_cmd_flush_tlv_options_parsed(void *parsed_result,
10220683c002SMichael Baum 				  __rte_unused struct cmdline *cl,
10230683c002SMichael Baum 				  __rte_unused void *data)
10240683c002SMichael Baum {
10250683c002SMichael Baum 	struct mlx5_cmd_flush_tlv_options *res = parsed_result;
10260683c002SMichael Baum 	struct rte_pmd_mlx5_geneve_tlv *option;
10270683c002SMichael Baum 	uint8_t nb_options_flush = tlv_mng.nb_options;
10280683c002SMichael Baum 	uint8_t nb_options_left = 0;
10290683c002SMichael Baum 
10300683c002SMichael Baum 	if (strcmp(res->max, "max") == 0 && res->number < tlv_mng.nb_options) {
10310683c002SMichael Baum 		nb_options_left = tlv_mng.nb_options - res->number;
10320683c002SMichael Baum 		nb_options_flush = RTE_MIN(res->number, nb_options_flush);
10330683c002SMichael Baum 	}
10340683c002SMichael Baum 
10350683c002SMichael Baum 	while (tlv_mng.nb_options > nb_options_left) {
10360683c002SMichael Baum 		tlv_mng.nb_options--;
10370683c002SMichael Baum 		option = &tlv_mng.tlv_list[tlv_mng.nb_options];
10380683c002SMichael Baum 		if (option->match_data_mask) {
10390683c002SMichael Baum 			free(option->match_data_mask);
10400683c002SMichael Baum 			option->match_data_mask = NULL;
10410683c002SMichael Baum 		}
10420683c002SMichael Baum 	}
10430683c002SMichael Baum 
10440683c002SMichael Baum 	TESTPMD_LOG(DEBUG, "Flush %u latest configured GENEVE TLV options, "
10450683c002SMichael Baum 		    "current number of options in the list is %u\n",
10460683c002SMichael Baum 		    nb_options_flush, nb_options_left);
10470683c002SMichael Baum }
10480683c002SMichael Baum 
10490683c002SMichael Baum cmdline_parse_inst_t mlx5_cmd_flush_tlv_options = {
10500683c002SMichael Baum 	.f = mlx5_cmd_flush_tlv_options_parsed,
10510683c002SMichael Baum 	.data = NULL,
10520683c002SMichael Baum 	.help_str = "mlx5 flush tlv_options max <nb_options>",
10530683c002SMichael Baum 	.tokens = {
10540683c002SMichael Baum 		(void *)&mlx5_cmd_flush_tlv_options_mlx5,
10550683c002SMichael Baum 		(void *)&mlx5_cmd_flush_tlv_options_flush,
10560683c002SMichael Baum 		(void *)&mlx5_cmd_flush_tlv_options_tlv_options,
10570683c002SMichael Baum 		(void *)&mlx5_cmd_flush_tlv_options_max,
10580683c002SMichael Baum 		(void *)&mlx5_cmd_flush_tlv_options_number,
10590683c002SMichael Baum 		NULL,
10600683c002SMichael Baum 	}
10610683c002SMichael Baum };
10620683c002SMichael Baum 
10630683c002SMichael Baum /* Create GENEVE TLV parser using option list which is configured before. */
10640683c002SMichael Baum struct mlx5_cmd_apply_tlv_options {
10650683c002SMichael Baum 	cmdline_fixed_string_t mlx5;
10660683c002SMichael Baum 	cmdline_fixed_string_t port;
10670683c002SMichael Baum 	portid_t port_id;
10680683c002SMichael Baum 	cmdline_fixed_string_t apply;
10690683c002SMichael Baum 	cmdline_fixed_string_t tlv_options;
10700683c002SMichael Baum };
10710683c002SMichael Baum 
10720683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_apply_tlv_options_mlx5 =
10730683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_apply_tlv_options, mlx5,
10740683c002SMichael Baum 				 "mlx5");
10750683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_apply_tlv_options_port =
10760683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_apply_tlv_options, port,
10770683c002SMichael Baum 				 "port");
10780683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_apply_tlv_options_port_id =
10790683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_apply_tlv_options, port_id,
10800683c002SMichael Baum 			      RTE_UINT16);
10810683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_apply_tlv_options_apply =
10820683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_apply_tlv_options, apply,
10830683c002SMichael Baum 				 "apply");
10840683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_apply_tlv_options_tlv_options =
10850683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_apply_tlv_options, tlv_options,
10860683c002SMichael Baum 				 "tlv_options");
10870683c002SMichael Baum 
10880683c002SMichael Baum static void
mlx5_cmd_apply_tlv_options_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)10890683c002SMichael Baum mlx5_cmd_apply_tlv_options_parsed(void *parsed_result,
10900683c002SMichael Baum 				  __rte_unused struct cmdline *cl,
10910683c002SMichael Baum 				  __rte_unused void *data)
10920683c002SMichael Baum {
10930683c002SMichael Baum 	struct mlx5_cmd_apply_tlv_options *res = parsed_result;
10940683c002SMichael Baum 	struct mlx5_port *port;
10950683c002SMichael Baum 	void *handle;
10960683c002SMichael Baum 
10970683c002SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10980683c002SMichael Baum 		return;
10990683c002SMichael Baum 
11000683c002SMichael Baum 	if (tlv_mng.nb_options == 0) {
11010683c002SMichael Baum 		fprintf(stderr, "The option list is empty, please set options\n");
11020683c002SMichael Baum 		return;
11030683c002SMichael Baum 	}
11040683c002SMichael Baum 
11050683c002SMichael Baum 	handle = rte_pmd_mlx5_create_geneve_tlv_parser(res->port_id,
11060683c002SMichael Baum 						       tlv_mng.tlv_list,
11070683c002SMichael Baum 						       tlv_mng.nb_options);
11080683c002SMichael Baum 	if (handle == NULL) {
11090683c002SMichael Baum 		fprintf(stderr,
11100683c002SMichael Baum 			"Fail to create GENEVE TLV parser, nb_option=%u: %s\n",
11110683c002SMichael Baum 			tlv_mng.nb_options, strerror(rte_errno));
11120683c002SMichael Baum 		return;
11130683c002SMichael Baum 	}
11140683c002SMichael Baum 
11150683c002SMichael Baum 	TESTPMD_LOG(DEBUG, "GENEVE TLV options parser is successfully created:"
11160683c002SMichael Baum 		    " nb_option=%u, handle=%p\n", tlv_mng.nb_options, handle);
11170683c002SMichael Baum 
11180683c002SMichael Baum 	port = &private_port[res->port_id];
11190683c002SMichael Baum 	port->geneve_tlv_parser_handle = handle;
11200683c002SMichael Baum }
11210683c002SMichael Baum 
11220683c002SMichael Baum cmdline_parse_inst_t mlx5_cmd_apply_tlv_options = {
11230683c002SMichael Baum 	.f = mlx5_cmd_apply_tlv_options_parsed,
11240683c002SMichael Baum 	.data = NULL,
11250683c002SMichael Baum 	.help_str = "mlx5 port <port_id> apply tlv_options",
11260683c002SMichael Baum 	.tokens = {
11270683c002SMichael Baum 		(void *)&mlx5_cmd_apply_tlv_options_mlx5,
11280683c002SMichael Baum 		(void *)&mlx5_cmd_apply_tlv_options_port,
11290683c002SMichael Baum 		(void *)&mlx5_cmd_apply_tlv_options_port_id,
11300683c002SMichael Baum 		(void *)&mlx5_cmd_apply_tlv_options_apply,
11310683c002SMichael Baum 		(void *)&mlx5_cmd_apply_tlv_options_tlv_options,
11320683c002SMichael Baum 		NULL,
11330683c002SMichael Baum 	}
11340683c002SMichael Baum };
11350683c002SMichael Baum 
11360683c002SMichael Baum /* Destroy GENEVE TLV parser created by apply command. */
11370683c002SMichael Baum struct mlx5_cmd_destroy_tlv_options {
11380683c002SMichael Baum 	cmdline_fixed_string_t mlx5;
11390683c002SMichael Baum 	cmdline_fixed_string_t port;
11400683c002SMichael Baum 	portid_t port_id;
11410683c002SMichael Baum 	cmdline_fixed_string_t destroy;
11420683c002SMichael Baum 	cmdline_fixed_string_t tlv_options;
11430683c002SMichael Baum };
11440683c002SMichael Baum 
11450683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_destroy_tlv_options_mlx5 =
11460683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_destroy_tlv_options, mlx5,
11470683c002SMichael Baum 				 "mlx5");
11480683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_destroy_tlv_options_port =
11490683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_destroy_tlv_options, port,
11500683c002SMichael Baum 				 "port");
11510683c002SMichael Baum cmdline_parse_token_num_t mlx5_cmd_destroy_tlv_options_port_id =
11520683c002SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_destroy_tlv_options, port_id,
11530683c002SMichael Baum 			      RTE_UINT16);
11540683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_destroy_tlv_options_destroy =
11550683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_destroy_tlv_options, destroy,
11560683c002SMichael Baum 				 "destroy");
11570683c002SMichael Baum cmdline_parse_token_string_t mlx5_cmd_destroy_tlv_options_tlv_options =
11580683c002SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_destroy_tlv_options, tlv_options,
11590683c002SMichael Baum 				 "tlv_options");
11600683c002SMichael Baum 
11610683c002SMichael Baum static void
mlx5_cmd_destroy_tlv_options_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)11620683c002SMichael Baum mlx5_cmd_destroy_tlv_options_parsed(void *parsed_result,
11630683c002SMichael Baum 				    __rte_unused struct cmdline *cl,
11640683c002SMichael Baum 				    __rte_unused void *data)
11650683c002SMichael Baum {
11660683c002SMichael Baum 	struct mlx5_cmd_destroy_tlv_options *res = parsed_result;
11670683c002SMichael Baum 	struct mlx5_port *port;
11680683c002SMichael Baum 	int ret;
11690683c002SMichael Baum 
11700683c002SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
11710683c002SMichael Baum 		return;
11720683c002SMichael Baum 
11730683c002SMichael Baum 	port = &private_port[res->port_id];
11740683c002SMichael Baum 	if (!port->geneve_tlv_parser_handle)
11750683c002SMichael Baum 		return;
11760683c002SMichael Baum 
11770683c002SMichael Baum 	ret = rte_pmd_mlx5_destroy_geneve_tlv_parser(port->geneve_tlv_parser_handle);
11780683c002SMichael Baum 	if (ret < 0) {
11790683c002SMichael Baum 		fprintf(stderr, "Fail to destroy GENEVE TLV parser: %s\n",
11800683c002SMichael Baum 			strerror(-ret));
11810683c002SMichael Baum 		return;
11820683c002SMichael Baum 	}
11830683c002SMichael Baum 
11840683c002SMichael Baum 	TESTPMD_LOG(DEBUG, "GENEVE TLV options parser is successfully released:"
11850683c002SMichael Baum 		    " handle=%p\n", port->geneve_tlv_parser_handle);
11860683c002SMichael Baum 
11870683c002SMichael Baum 	port->geneve_tlv_parser_handle = NULL;
11880683c002SMichael Baum }
11890683c002SMichael Baum 
11900683c002SMichael Baum cmdline_parse_inst_t mlx5_cmd_destroy_tlv_options = {
11910683c002SMichael Baum 	.f = mlx5_cmd_destroy_tlv_options_parsed,
11920683c002SMichael Baum 	.data = NULL,
11930683c002SMichael Baum 	.help_str = "mlx5 port <port_id> destroy tlv_options",
11940683c002SMichael Baum 	.tokens = {
11950683c002SMichael Baum 		(void *)&mlx5_cmd_destroy_tlv_options_mlx5,
11960683c002SMichael Baum 		(void *)&mlx5_cmd_destroy_tlv_options_port,
11970683c002SMichael Baum 		(void *)&mlx5_cmd_destroy_tlv_options_port_id,
11980683c002SMichael Baum 		(void *)&mlx5_cmd_destroy_tlv_options_destroy,
11990683c002SMichael Baum 		(void *)&mlx5_cmd_destroy_tlv_options_tlv_options,
12000683c002SMichael Baum 		NULL,
12010683c002SMichael Baum 	}
12020683c002SMichael Baum };
12030683c002SMichael Baum 
1204*3dfa7877SKiran Vedere /* Dump SQ Context for a given port/queue*/
1205*3dfa7877SKiran Vedere struct mlx5_cmd_dump_sq_context_options {
1206*3dfa7877SKiran Vedere 	cmdline_fixed_string_t mlx5;
1207*3dfa7877SKiran Vedere 	cmdline_fixed_string_t port;
1208*3dfa7877SKiran Vedere 	portid_t port_id;
1209*3dfa7877SKiran Vedere 	cmdline_fixed_string_t queue;
1210*3dfa7877SKiran Vedere 	queueid_t queue_id;
1211*3dfa7877SKiran Vedere 	cmdline_fixed_string_t dump;
1212*3dfa7877SKiran Vedere 	cmdline_fixed_string_t sq_context;
1213*3dfa7877SKiran Vedere 	cmdline_fixed_string_t file_name;
1214*3dfa7877SKiran Vedere };
1215*3dfa7877SKiran Vedere 
1216*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_mlx5 =
1217*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, mlx5,
1218*3dfa7877SKiran Vedere 				 "mlx5");
1219*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_port =
1220*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, port,
1221*3dfa7877SKiran Vedere 				 "port");
1222*3dfa7877SKiran Vedere cmdline_parse_token_num_t mlx5_cmd_dump_sq_context_options_port_id =
1223*3dfa7877SKiran Vedere 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, port_id,
1224*3dfa7877SKiran Vedere 			      RTE_UINT16);
1225*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_queue =
1226*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, queue,
1227*3dfa7877SKiran Vedere 				 "queue");
1228*3dfa7877SKiran Vedere cmdline_parse_token_num_t mlx5_cmd_dump_sq_context_options_queue_id =
1229*3dfa7877SKiran Vedere 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, queue_id,
1230*3dfa7877SKiran Vedere 			      RTE_UINT16);
1231*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_dump =
1232*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, dump,
1233*3dfa7877SKiran Vedere 				 "dump");
1234*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_sq_context =
1235*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, sq_context,
1236*3dfa7877SKiran Vedere 				 "sq_context");
1237*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_sq_context_options_file_name =
1238*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_sq_context_options, file_name,
1239*3dfa7877SKiran Vedere 				 NULL);
1240*3dfa7877SKiran Vedere 
1241*3dfa7877SKiran Vedere static void
mlx5_cmd_dump_sq_context_options_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)1242*3dfa7877SKiran Vedere mlx5_cmd_dump_sq_context_options_parsed(void *parsed_result,
1243*3dfa7877SKiran Vedere 				    __rte_unused struct cmdline *cl,
1244*3dfa7877SKiran Vedere 				    __rte_unused void *data)
1245*3dfa7877SKiran Vedere {
1246*3dfa7877SKiran Vedere 	struct mlx5_cmd_dump_sq_context_options *res = parsed_result;
1247*3dfa7877SKiran Vedere 	int ret;
1248*3dfa7877SKiran Vedere 
1249*3dfa7877SKiran Vedere 	ret = rte_pmd_mlx5_txq_dump_contexts(res->port_id, res->queue_id, res->file_name);
1250*3dfa7877SKiran Vedere 
1251*3dfa7877SKiran Vedere 	switch (ret) {
1252*3dfa7877SKiran Vedere 	case 0:
1253*3dfa7877SKiran Vedere 		break;
1254*3dfa7877SKiran Vedere 	case -EINVAL:
1255*3dfa7877SKiran Vedere 		fprintf(stderr, "invalid queue index (%u), out of range\n",
1256*3dfa7877SKiran Vedere 			res->queue_id);
1257*3dfa7877SKiran Vedere 		break;
1258*3dfa7877SKiran Vedere 	case -ENODEV:
1259*3dfa7877SKiran Vedere 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
1260*3dfa7877SKiran Vedere 		break;
1261*3dfa7877SKiran Vedere 	case -EIO:
1262*3dfa7877SKiran Vedere 		fprintf(stderr, "File Access Error (%s)\n", strerror(rte_errno));
1263*3dfa7877SKiran Vedere 		break;
1264*3dfa7877SKiran Vedere 	default:
1265*3dfa7877SKiran Vedere 		fprintf(stderr, "Unable to dump SQ/CQ HW Context (%s)\n", strerror(rte_errno));
1266*3dfa7877SKiran Vedere 	}
1267*3dfa7877SKiran Vedere }
1268*3dfa7877SKiran Vedere 
1269*3dfa7877SKiran Vedere cmdline_parse_inst_t mlx5_cmd_dump_sq_context_options = {
1270*3dfa7877SKiran Vedere 	.f = mlx5_cmd_dump_sq_context_options_parsed,
1271*3dfa7877SKiran Vedere 	.data = NULL,
1272*3dfa7877SKiran Vedere 	.help_str = "mlx5 port <port_id> queue <queue_id> dump sq_context <file_name>",
1273*3dfa7877SKiran Vedere 	.tokens = {
1274*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_mlx5,
1275*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_port,
1276*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_port_id,
1277*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_queue,
1278*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_queue_id,
1279*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_dump,
1280*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_sq_context,
1281*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_sq_context_options_file_name,
1282*3dfa7877SKiran Vedere 		NULL,
1283*3dfa7877SKiran Vedere 	}
1284*3dfa7877SKiran Vedere };
1285*3dfa7877SKiran Vedere 
1286*3dfa7877SKiran Vedere /* Dump RQ Context for a given port/queue*/
1287*3dfa7877SKiran Vedere struct mlx5_cmd_dump_rq_context_options {
1288*3dfa7877SKiran Vedere 	cmdline_fixed_string_t mlx5;
1289*3dfa7877SKiran Vedere 	cmdline_fixed_string_t port;
1290*3dfa7877SKiran Vedere 	portid_t port_id;
1291*3dfa7877SKiran Vedere 	cmdline_fixed_string_t queue;
1292*3dfa7877SKiran Vedere 	queueid_t queue_id;
1293*3dfa7877SKiran Vedere 	cmdline_fixed_string_t dump;
1294*3dfa7877SKiran Vedere 	cmdline_fixed_string_t rq_context;
1295*3dfa7877SKiran Vedere 	cmdline_fixed_string_t file_name;
1296*3dfa7877SKiran Vedere };
1297*3dfa7877SKiran Vedere 
1298*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_mlx5 =
1299*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, mlx5,
1300*3dfa7877SKiran Vedere 				 "mlx5");
1301*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_port =
1302*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, port,
1303*3dfa7877SKiran Vedere 				 "port");
1304*3dfa7877SKiran Vedere cmdline_parse_token_num_t mlx5_cmd_dump_rq_context_options_port_id =
1305*3dfa7877SKiran Vedere 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, port_id,
1306*3dfa7877SKiran Vedere 			      RTE_UINT16);
1307*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_queue =
1308*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, queue,
1309*3dfa7877SKiran Vedere 				 "queue");
1310*3dfa7877SKiran Vedere cmdline_parse_token_num_t mlx5_cmd_dump_rq_context_options_queue_id =
1311*3dfa7877SKiran Vedere 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, queue_id,
1312*3dfa7877SKiran Vedere 			      RTE_UINT16);
1313*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_dump =
1314*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, dump,
1315*3dfa7877SKiran Vedere 				 "dump");
1316*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_rq_context =
1317*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, rq_context,
1318*3dfa7877SKiran Vedere 				 "rq_context");
1319*3dfa7877SKiran Vedere cmdline_parse_token_string_t mlx5_cmd_dump_rq_context_options_file_name =
1320*3dfa7877SKiran Vedere 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_dump_rq_context_options, file_name,
1321*3dfa7877SKiran Vedere 				 NULL);
1322*3dfa7877SKiran Vedere 
1323*3dfa7877SKiran Vedere static void
mlx5_cmd_dump_rq_context_options_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)1324*3dfa7877SKiran Vedere mlx5_cmd_dump_rq_context_options_parsed(void *parsed_result,
1325*3dfa7877SKiran Vedere 				    __rte_unused struct cmdline *cl,
1326*3dfa7877SKiran Vedere 				    __rte_unused void *data)
1327*3dfa7877SKiran Vedere {
1328*3dfa7877SKiran Vedere 	struct mlx5_cmd_dump_rq_context_options *res = parsed_result;
1329*3dfa7877SKiran Vedere 	int ret;
1330*3dfa7877SKiran Vedere 
1331*3dfa7877SKiran Vedere 	ret = rte_pmd_mlx5_rxq_dump_contexts(res->port_id, res->queue_id, res->file_name);
1332*3dfa7877SKiran Vedere 
1333*3dfa7877SKiran Vedere 	switch (ret) {
1334*3dfa7877SKiran Vedere 	case 0:
1335*3dfa7877SKiran Vedere 		break;
1336*3dfa7877SKiran Vedere 	case -EINVAL:
1337*3dfa7877SKiran Vedere 		fprintf(stderr, "invalid queue index (%u), out of range\n",
1338*3dfa7877SKiran Vedere 			res->queue_id);
1339*3dfa7877SKiran Vedere 		break;
1340*3dfa7877SKiran Vedere 	case -ENODEV:
1341*3dfa7877SKiran Vedere 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
1342*3dfa7877SKiran Vedere 		break;
1343*3dfa7877SKiran Vedere 	case -EIO:
1344*3dfa7877SKiran Vedere 		fprintf(stderr, "File Access Error (%s)\n", strerror(rte_errno));
1345*3dfa7877SKiran Vedere 		break;
1346*3dfa7877SKiran Vedere 	default:
1347*3dfa7877SKiran Vedere 		fprintf(stderr, "Unable to dump RQ/CQ HW Context (%s)\n", strerror(rte_errno));
1348*3dfa7877SKiran Vedere 	}
1349*3dfa7877SKiran Vedere }
1350*3dfa7877SKiran Vedere 
1351*3dfa7877SKiran Vedere cmdline_parse_inst_t mlx5_cmd_dump_rq_context_options = {
1352*3dfa7877SKiran Vedere 	.f = mlx5_cmd_dump_rq_context_options_parsed,
1353*3dfa7877SKiran Vedere 	.data = NULL,
1354*3dfa7877SKiran Vedere 	.help_str = "mlx5 port <port_id> queue <queue_id> dump rq_context <file_name>",
1355*3dfa7877SKiran Vedere 	.tokens = {
1356*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_mlx5,
1357*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_port,
1358*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_port_id,
1359*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_queue,
1360*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_queue_id,
1361*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_dump,
1362*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_rq_context,
1363*3dfa7877SKiran Vedere 		(void *)&mlx5_cmd_dump_rq_context_options_file_name,
1364*3dfa7877SKiran Vedere 		NULL,
1365*3dfa7877SKiran Vedere 	}
1366*3dfa7877SKiran Vedere };
1367*3dfa7877SKiran Vedere 
1368f41a5092SSpike Du static struct testpmd_driver_commands mlx5_driver_cmds = {
1369f41a5092SSpike Du 	.commands = {
1370f41a5092SSpike Du 		{
1371f41a5092SSpike Du 			.ctx = &mlx5_test_cmd_port_host_shaper,
1372f41a5092SSpike Du 			.help = "mlx5 set port (port_id) host_shaper avail_thresh_triggered (on|off)"
1373f41a5092SSpike Du 				"rate (rate_num):\n"
1374f41a5092SSpike Du 				"    Set HOST_SHAPER avail_thresh_triggered and rate with port_id\n\n",
1375f41a5092SSpike Du 		},
137685d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
137785d9252eSMichael Baum 		{
137885d9252eSMichael Baum 			.ctx = &mlx5_cmd_operate_attach_port,
137985d9252eSMichael Baum 			.help = "mlx5 port attach (ident) socket=(path)\n"
138085d9252eSMichael Baum 				"    Attach physical or virtual dev by pci address or virtual device name "
138185d9252eSMichael Baum 				"and add \"cmd_fd\" and \"pd_handle\" devargs before attaching\n\n",
138285d9252eSMichael Baum 		},
138385d9252eSMichael Baum #endif
1384f41a5092SSpike Du 		{
1385740a2836SMichael Baum 			.ctx = &mlx5_cmd_map_ext_rxq,
1386740a2836SMichael Baum 			.help = "mlx5 port (port_id) ext_rxq map (sw_queue_id) (hw_queue_id)\n"
1387740a2836SMichael Baum 				"    Map HW queue index (32-bit) to ethdev"
1388740a2836SMichael Baum 				" queue index (16-bit) for external RxQ\n\n",
1389740a2836SMichael Baum 		},
1390740a2836SMichael Baum 		{
1391740a2836SMichael Baum 			.ctx = &mlx5_cmd_unmap_ext_rxq,
1392740a2836SMichael Baum 			.help = "mlx5 port (port_id) ext_rxq unmap (sw_queue_id)\n"
1393740a2836SMichael Baum 				"    Unmap external Rx queue ethdev index mapping\n\n",
1394740a2836SMichael Baum 		},
1395740a2836SMichael Baum 		{
1396baafc81eSRongwei Liu 			.ctx = &mlx5_cmd_set_flow_engine_mode,
1397baafc81eSRongwei Liu 			.help = "mlx5 set flow_engine (active|standby) [(flag)]\n"
1398baafc81eSRongwei Liu 				"    Set flow_engine to the specific mode with flag.\n\n"
1399baafc81eSRongwei Liu 		},
1400baafc81eSRongwei Liu 		{
14010683c002SMichael Baum 			.ctx = &mlx5_cmd_set_tlv_option,
14020683c002SMichael Baum 			.help = "mlx5 set tlv_option class (class_id) type "
14030683c002SMichael Baum 				"(type_id) len (option_length) offset "
14040683c002SMichael Baum 				"(sample_offset) sample_len (sample_length) "
14050683c002SMichael Baum 				"class_mode (ignored|fixed|matchable) "
14060683c002SMichael Baum 				"data (mask1) [(mask2) [...]]\n"
14070683c002SMichael Baum 				"    Set single GENEVE TLV option inside global list "
14080683c002SMichael Baum 				"using later by apply command\n\n",
14090683c002SMichael Baum 		},
14100683c002SMichael Baum 		{
14110683c002SMichael Baum 			.ctx = &mlx5_cmd_list_tlv_options,
14120683c002SMichael Baum 			.help = "mlx5 list tlv_options\n"
14130683c002SMichael Baum 				"    Print all GENEVE TLV options which are configured "
14140683c002SMichael Baum 				"so far by TLV option set command\n\n",
14150683c002SMichael Baum 		},
14160683c002SMichael Baum 		{
14170683c002SMichael Baum 			.ctx = &mlx5_cmd_flush_tlv_options,
14180683c002SMichael Baum 			.help = "mlx5 flush tlv_options [max (number options)]\n"
14190683c002SMichael Baum 				"    Clear all GENEVE TLV options which are configured "
14200683c002SMichael Baum 				"so far by TLV option set command\n\n",
14210683c002SMichael Baum 		},
14220683c002SMichael Baum 		{
14230683c002SMichael Baum 			.ctx = &mlx5_cmd_apply_tlv_options,
14240683c002SMichael Baum 			.help = "mlx5 port (port_id) apply tlv_options\n"
14250683c002SMichael Baum 				"    Create GENEVE TLV parser using option list which is "
14260683c002SMichael Baum 				"configured before by TLV option set command\n\n",
14270683c002SMichael Baum 		},
14280683c002SMichael Baum 		{
14290683c002SMichael Baum 			.ctx = &mlx5_cmd_destroy_tlv_options,
14300683c002SMichael Baum 			.help = "mlx5 port (port_id) destroy tlv_options\n"
14310683c002SMichael Baum 				"    Destroy GENEVE TLV parser\n\n",
14320683c002SMichael Baum 		},
14330683c002SMichael Baum 		{
1434*3dfa7877SKiran Vedere 			.ctx = &mlx5_cmd_dump_sq_context_options,
1435*3dfa7877SKiran Vedere 			.help = "mlx5 port (port_id) queue (queue_id) dump sq_context (file_name)\n"
1436*3dfa7877SKiran Vedere 				"    Dump mlx5 SQ Context\n\n",
1437*3dfa7877SKiran Vedere 		},
1438*3dfa7877SKiran Vedere 		{
1439*3dfa7877SKiran Vedere 			.ctx = &mlx5_cmd_dump_rq_context_options,
1440*3dfa7877SKiran Vedere 			.help = "mlx5 port (port_id) queue (queue_id) dump rq_context (file_name)\n"
1441*3dfa7877SKiran Vedere 				"    Dump mlx5 RQ Context\n\n",
1442*3dfa7877SKiran Vedere 		},
1443*3dfa7877SKiran Vedere 		{
1444f41a5092SSpike Du 			.ctx = NULL,
1445f41a5092SSpike Du 		},
1446f41a5092SSpike Du 	}
1447f41a5092SSpike Du };
1448f41a5092SSpike Du TESTPMD_ADD_DRIVER_COMMANDS(mlx5_driver_cmds);
1449