xref: /dpdk/drivers/net/mlx5/mlx5_testpmd.c (revision baafc81eb1a9a34a929970fcff3ad525887aa080)
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 static uint8_t host_shaper_avail_thresh_triggered[RTE_MAX_ETHPORTS];
27f41a5092SSpike Du #define SHAPER_DISABLE_DELAY_US 100000 /* 100ms */
28*baafc81eSRongwei Liu #define PARSE_DELIMITER " \f\n\r\t\v"
29*baafc81eSRongwei Liu 
30*baafc81eSRongwei Liu static int
31*baafc81eSRongwei Liu parse_uint(uint64_t *value, const char *str)
32*baafc81eSRongwei Liu {
33*baafc81eSRongwei Liu 	char *next = NULL;
34*baafc81eSRongwei Liu 	uint64_t n;
35*baafc81eSRongwei Liu 
36*baafc81eSRongwei Liu 	errno = 0;
37*baafc81eSRongwei Liu 	/* Parse number string */
38*baafc81eSRongwei Liu 	if (!strncasecmp(str, "0x", 2)) {
39*baafc81eSRongwei Liu 		str += 2;
40*baafc81eSRongwei Liu 		n = strtol(str, &next, 16);
41*baafc81eSRongwei Liu 	} else {
42*baafc81eSRongwei Liu 		n = strtol(str, &next, 10);
43*baafc81eSRongwei Liu 	}
44*baafc81eSRongwei Liu 	if (errno != 0 || str == next || *next != '\0')
45*baafc81eSRongwei Liu 		return -1;
46*baafc81eSRongwei Liu 
47*baafc81eSRongwei Liu 	*value = n;
48*baafc81eSRongwei Liu 
49*baafc81eSRongwei Liu 	return 0;
50*baafc81eSRongwei Liu }
51f41a5092SSpike Du 
52f41a5092SSpike Du /**
53f41a5092SSpike Du  * Disable the host shaper and re-arm available descriptor threshold event.
54f41a5092SSpike Du  *
55f41a5092SSpike Du  * @param[in] args
56f41a5092SSpike Du  *   uint32_t integer combining port_id and rxq_id.
57f41a5092SSpike Du  */
58f41a5092SSpike Du static void
59f41a5092SSpike Du mlx5_test_host_shaper_disable(void *args)
60f41a5092SSpike Du {
61f41a5092SSpike Du 	uint32_t port_rxq_id = (uint32_t)(uintptr_t)args;
62f41a5092SSpike Du 	uint16_t port_id = port_rxq_id & 0xffff;
63f41a5092SSpike Du 	uint16_t qid = (port_rxq_id >> 16) & 0xffff;
64f41a5092SSpike Du 	struct rte_eth_rxq_info qinfo;
650f3ba0d4SSpike Du 	struct rte_port *port;
66f41a5092SSpike Du 
670f3ba0d4SSpike Du 	port = &ports[port_id];
680f3ba0d4SSpike Du 	if (port->port_status != RTE_PORT_STARTED) {
690f3ba0d4SSpike Du 		printf("%s port_status(%d) is incorrect, stop avail_thresh "
700f3ba0d4SSpike Du 		       "event processing.\n",
710f3ba0d4SSpike Du 		       __func__, port->port_status);
720f3ba0d4SSpike Du 		return;
730f3ba0d4SSpike Du 	}
74f41a5092SSpike Du 	printf("%s disable shaper\n", __func__);
75f41a5092SSpike Du 	if (rte_eth_rx_queue_info_get(port_id, qid, &qinfo)) {
76f41a5092SSpike Du 		printf("rx_queue_info_get returns error\n");
77f41a5092SSpike Du 		return;
78f41a5092SSpike Du 	}
79f41a5092SSpike Du 	/* Rearm the available descriptor threshold event. */
80f41a5092SSpike Du 	if (rte_eth_rx_avail_thresh_set(port_id, qid, qinfo.avail_thresh)) {
81f41a5092SSpike Du 		printf("config avail_thresh returns error\n");
82f41a5092SSpike Du 		return;
83f41a5092SSpike Du 	}
84f41a5092SSpike Du 	/* Only disable the shaper when avail_thresh_triggered is set. */
85f41a5092SSpike Du 	if (host_shaper_avail_thresh_triggered[port_id] &&
86f41a5092SSpike Du 	    rte_pmd_mlx5_host_shaper_config(port_id, 0, 0))
87f41a5092SSpike Du 		printf("%s disable shaper returns error\n", __func__);
88f41a5092SSpike Du }
89f41a5092SSpike Du 
90f41a5092SSpike Du void
91f41a5092SSpike Du mlx5_test_avail_thresh_event_handler(uint16_t port_id, uint16_t rxq_id)
92f41a5092SSpike Du {
93f41a5092SSpike Du 	struct rte_eth_dev_info dev_info;
94f41a5092SSpike Du 	uint32_t port_rxq_id = port_id | (rxq_id << 16);
95f41a5092SSpike Du 
96f41a5092SSpike Du 	/* Ensure it's MLX5 port. */
97f41a5092SSpike Du 	if (rte_eth_dev_info_get(port_id, &dev_info) != 0 ||
98f41a5092SSpike Du 	    (strncmp(dev_info.driver_name, "mlx5", 4) != 0))
99f41a5092SSpike Du 		return;
100f41a5092SSpike Du 	rte_eal_alarm_set(SHAPER_DISABLE_DELAY_US,
101f41a5092SSpike Du 			  mlx5_test_host_shaper_disable,
102f41a5092SSpike Du 			  (void *)(uintptr_t)port_rxq_id);
103f41a5092SSpike Du 	printf("%s port_id:%u rxq_id:%u\n", __func__, port_id, rxq_id);
104f41a5092SSpike Du }
105f41a5092SSpike Du 
106f41a5092SSpike Du /**
107f41a5092SSpike Du  * Configure host shaper's avail_thresh_triggered and current rate.
108f41a5092SSpike Du  *
109f41a5092SSpike Du  * @param[in] avail_thresh_triggered
110f41a5092SSpike Du  *   Disable/enable avail_thresh_triggered.
111f41a5092SSpike Du  * @param[in] rate
112f41a5092SSpike Du  *   Configure current host shaper rate.
113f41a5092SSpike Du  * @return
114f41a5092SSpike Du  *   On success, returns 0.
115f41a5092SSpike Du  *   On failure, returns < 0.
116f41a5092SSpike Du  */
117f41a5092SSpike Du static int
118f41a5092SSpike Du mlx5_test_set_port_host_shaper(uint16_t port_id, uint16_t avail_thresh_triggered, uint8_t rate)
119f41a5092SSpike Du {
120f41a5092SSpike Du 	struct rte_eth_link link;
121f41a5092SSpike Du 	bool port_id_valid = false;
122f41a5092SSpike Du 	uint16_t pid;
123f41a5092SSpike Du 	int ret;
124f41a5092SSpike Du 
125f41a5092SSpike Du 	RTE_ETH_FOREACH_DEV(pid)
126f41a5092SSpike Du 		if (port_id == pid) {
127f41a5092SSpike Du 			port_id_valid = true;
128f41a5092SSpike Du 			break;
129f41a5092SSpike Du 		}
130f41a5092SSpike Du 	if (!port_id_valid)
131f41a5092SSpike Du 		return -EINVAL;
132f41a5092SSpike Du 	ret = rte_eth_link_get_nowait(port_id, &link);
133f41a5092SSpike Du 	if (ret < 0)
134f41a5092SSpike Du 		return ret;
135f41a5092SSpike Du 	host_shaper_avail_thresh_triggered[port_id] = avail_thresh_triggered ? 1 : 0;
136f41a5092SSpike Du 	if (!avail_thresh_triggered) {
137f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 0,
138f41a5092SSpike Du 		RTE_BIT32(MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
139f41a5092SSpike Du 	} else {
140f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 1,
141f41a5092SSpike Du 		RTE_BIT32(MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
142f41a5092SSpike Du 	}
143f41a5092SSpike Du 	if (ret)
144f41a5092SSpike Du 		return ret;
145f41a5092SSpike Du 	ret = rte_pmd_mlx5_host_shaper_config(port_id, rate, 0);
146f41a5092SSpike Du 	if (ret)
147f41a5092SSpike Du 		return ret;
148f41a5092SSpike Du 	return 0;
149f41a5092SSpike Du }
150f41a5092SSpike Du 
15185d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
15285d9252eSMichael Baum static const char*
15385d9252eSMichael Baum mlx5_test_get_socket_path(char *extend)
15485d9252eSMichael Baum {
15585d9252eSMichael Baum 	if (strstr(extend, "socket=") == extend) {
15685d9252eSMichael Baum 		const char *socket_path = strchr(extend, '=') + 1;
15785d9252eSMichael Baum 
15885d9252eSMichael Baum 		TESTPMD_LOG(DEBUG, "MLX5 socket path is %s\n", socket_path);
15985d9252eSMichael Baum 		return socket_path;
16085d9252eSMichael Baum 	}
16185d9252eSMichael Baum 
16285d9252eSMichael Baum 	TESTPMD_LOG(ERR, "Failed to extract a valid socket path from %s\n",
16385d9252eSMichael Baum 		    extend);
16485d9252eSMichael Baum 	return NULL;
16585d9252eSMichael Baum }
16685d9252eSMichael Baum 
16785d9252eSMichael Baum static int
16885d9252eSMichael Baum mlx5_test_extend_devargs(char *identifier, char *extend)
16985d9252eSMichael Baum {
17085d9252eSMichael Baum 	struct sockaddr_un un = {
17185d9252eSMichael Baum 		.sun_family = AF_UNIX,
17285d9252eSMichael Baum 	};
17385d9252eSMichael Baum 	int cmd_fd;
17485d9252eSMichael Baum 	int pd_handle;
17585d9252eSMichael Baum 	struct iovec iov = {
17685d9252eSMichael Baum 		.iov_base = &pd_handle,
17785d9252eSMichael Baum 		.iov_len = sizeof(int),
17885d9252eSMichael Baum 	};
17985d9252eSMichael Baum 	union {
18085d9252eSMichael Baum 		char buf[CMSG_SPACE(sizeof(int))];
18185d9252eSMichael Baum 		struct cmsghdr align;
18285d9252eSMichael Baum 	} control;
18385d9252eSMichael Baum 	struct msghdr msgh = {
18485d9252eSMichael Baum 		.msg_iov = NULL,
18585d9252eSMichael Baum 		.msg_iovlen = 0,
18685d9252eSMichael Baum 	};
18785d9252eSMichael Baum 	struct cmsghdr *cmsg;
18885d9252eSMichael Baum 	const char *path = mlx5_test_get_socket_path(extend + 1);
18985d9252eSMichael Baum 	size_t len = 1;
19085d9252eSMichael Baum 	int socket_fd;
19185d9252eSMichael Baum 	int ret;
19285d9252eSMichael Baum 
19385d9252eSMichael Baum 	if (path == NULL) {
19485d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Invalid devargs extension is specified\n");
19585d9252eSMichael Baum 		return -1;
19685d9252eSMichael Baum 	}
19785d9252eSMichael Baum 
19885d9252eSMichael Baum 	/* Initialize IPC channel. */
19985d9252eSMichael Baum 	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
20085d9252eSMichael Baum 	if (socket_fd < 0) {
20185d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to create unix socket: %s\n",
20285d9252eSMichael Baum 			    strerror(errno));
20385d9252eSMichael Baum 		return -1;
20485d9252eSMichael Baum 	}
20585d9252eSMichael Baum 	rte_strlcpy(un.sun_path, path, sizeof(un.sun_path));
20685d9252eSMichael Baum 	if (connect(socket_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
20785d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to connect %s: %s\n", un.sun_path,
20885d9252eSMichael Baum 			    strerror(errno));
20985d9252eSMichael Baum 		close(socket_fd);
21085d9252eSMichael Baum 		return -1;
21185d9252eSMichael Baum 	}
21285d9252eSMichael Baum 
21385d9252eSMichael Baum 	/* Send the request message. */
21485d9252eSMichael Baum 	do {
21585d9252eSMichael Baum 		ret = sendmsg(socket_fd, &msgh, 0);
21685d9252eSMichael Baum 	} while (ret < 0 && errno == EINTR);
21785d9252eSMichael Baum 	if (ret < 0) {
21885d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to send request to (%s): %s\n", path,
21985d9252eSMichael Baum 			    strerror(errno));
22085d9252eSMichael Baum 		close(socket_fd);
22185d9252eSMichael Baum 		return -1;
22285d9252eSMichael Baum 	}
22385d9252eSMichael Baum 
22485d9252eSMichael Baum 	msgh.msg_iov = &iov;
22585d9252eSMichael Baum 	msgh.msg_iovlen = 1;
22685d9252eSMichael Baum 	msgh.msg_control = control.buf;
22785d9252eSMichael Baum 	msgh.msg_controllen = sizeof(control.buf);
22885d9252eSMichael Baum 	do {
22985d9252eSMichael Baum 		ret = recvmsg(socket_fd, &msgh, 0);
23085d9252eSMichael Baum 	} while (ret < 0);
23185d9252eSMichael Baum 	if (ret != sizeof(int) || (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
23285d9252eSMichael Baum 		TESTPMD_LOG(ERR, "truncated msg");
23385d9252eSMichael Baum 		close(socket_fd);
23485d9252eSMichael Baum 		return -1;
23585d9252eSMichael Baum 	}
23685d9252eSMichael Baum 
23785d9252eSMichael Baum 	/* Translate the FD. */
23885d9252eSMichael Baum 	cmsg = CMSG_FIRSTHDR(&msgh);
23985d9252eSMichael Baum 	if (cmsg == NULL || cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
24085d9252eSMichael Baum 	    cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
24185d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Fail to get FD using SCM_RIGHTS mechanism\n");
24285d9252eSMichael Baum 		close(socket_fd);
24385d9252eSMichael Baum 		unlink(un.sun_path);
24485d9252eSMichael Baum 		return -1;
24585d9252eSMichael Baum 	}
24685d9252eSMichael Baum 	memcpy(&cmd_fd, CMSG_DATA(cmsg), sizeof(int));
24785d9252eSMichael Baum 
24885d9252eSMichael Baum 	TESTPMD_LOG(DEBUG, "Command FD (%d) and PD handle (%d) "
24985d9252eSMichael Baum 		    "are successfully imported from remote process\n",
25085d9252eSMichael Baum 		    cmd_fd, pd_handle);
25185d9252eSMichael Baum 
25285d9252eSMichael Baum 	/* Cleanup IPC channel. */
25385d9252eSMichael Baum 	close(socket_fd);
25485d9252eSMichael Baum 
25585d9252eSMichael Baum 	/* Calculate the new length of devargs string. */
25685d9252eSMichael Baum 	len += snprintf(NULL, 0, ",cmd_fd=%d,pd_handle=%d", cmd_fd, pd_handle);
25785d9252eSMichael Baum 	/* Extend the devargs string. */
25885d9252eSMichael Baum 	snprintf(extend, len, ",cmd_fd=%d,pd_handle=%d", cmd_fd, pd_handle);
25985d9252eSMichael Baum 
26085d9252eSMichael Baum 	TESTPMD_LOG(DEBUG, "Attach port with extra devargs %s\n", identifier);
26185d9252eSMichael Baum 	return 0;
26285d9252eSMichael Baum }
26385d9252eSMichael Baum 
26485d9252eSMichael Baum static bool
26585d9252eSMichael Baum is_delimiter_path_spaces(char *extend)
26685d9252eSMichael Baum {
26785d9252eSMichael Baum 	while (*extend != '\0') {
26885d9252eSMichael Baum 		if (*extend != ' ')
26985d9252eSMichael Baum 			return true;
27085d9252eSMichael Baum 		extend++;
27185d9252eSMichael Baum 	}
27285d9252eSMichael Baum 	return false;
27385d9252eSMichael Baum }
27485d9252eSMichael Baum 
27585d9252eSMichael Baum /*
27685d9252eSMichael Baum  * Extend devargs list with "cmd_fd" and "pd_handle" coming from external
27785d9252eSMichael Baum  * process. It happens only in this format:
27885d9252eSMichael Baum  *  testpmd> mlx5 port attach (identifier) socket=<socket path>
27985d9252eSMichael Baum  * all "(identifier) socket=<socket path>" is in the same string pointed
28085d9252eSMichael Baum  * by the input parameter 'identifier'.
28185d9252eSMichael Baum  *
28285d9252eSMichael Baum  * @param identifier
28385d9252eSMichael Baum  *   Identifier of port attach command line.
28485d9252eSMichael Baum  */
28585d9252eSMichael Baum static void
28685d9252eSMichael Baum mlx5_test_attach_port_extend_devargs(char *identifier)
28785d9252eSMichael Baum {
28885d9252eSMichael Baum 	char *extend;
28985d9252eSMichael Baum 
29085d9252eSMichael Baum 	if (identifier == NULL) {
29185d9252eSMichael Baum 		fprintf(stderr, "Invalid parameters are specified\n");
29285d9252eSMichael Baum 		return;
29385d9252eSMichael Baum 	}
29485d9252eSMichael Baum 
29585d9252eSMichael Baum 	extend = strchr(identifier, ' ');
29685d9252eSMichael Baum 	if (extend != NULL && is_delimiter_path_spaces(extend) &&
29785d9252eSMichael Baum 	    mlx5_test_extend_devargs(identifier, extend) < 0) {
29885d9252eSMichael Baum 		TESTPMD_LOG(ERR, "Failed to extend devargs for port %s\n",
29985d9252eSMichael Baum 			    identifier);
30085d9252eSMichael Baum 		return;
30185d9252eSMichael Baum 	}
30285d9252eSMichael Baum 
30385d9252eSMichael Baum 	attach_port(identifier);
30485d9252eSMichael Baum }
30585d9252eSMichael Baum #endif
30685d9252eSMichael Baum 
307f41a5092SSpike Du /* *** SET HOST_SHAPER FOR A PORT *** */
308f41a5092SSpike Du struct cmd_port_host_shaper_result {
309f41a5092SSpike Du 	cmdline_fixed_string_t mlx5;
310f41a5092SSpike Du 	cmdline_fixed_string_t set;
311f41a5092SSpike Du 	cmdline_fixed_string_t port;
312f41a5092SSpike Du 	uint16_t port_num;
313f41a5092SSpike Du 	cmdline_fixed_string_t host_shaper;
314f41a5092SSpike Du 	cmdline_fixed_string_t avail_thresh_triggered;
315f41a5092SSpike Du 	uint16_t fr;
316f41a5092SSpike Du 	cmdline_fixed_string_t rate;
317f41a5092SSpike Du 	uint8_t rate_num;
318f41a5092SSpike Du };
319f41a5092SSpike Du 
320f41a5092SSpike Du static void cmd_port_host_shaper_parsed(void *parsed_result,
321f41a5092SSpike Du 		__rte_unused struct cmdline *cl,
322f41a5092SSpike Du 		__rte_unused void *data)
323f41a5092SSpike Du {
324f41a5092SSpike Du 	struct cmd_port_host_shaper_result *res = parsed_result;
325f41a5092SSpike Du 	int ret = 0;
326f41a5092SSpike Du 
327f41a5092SSpike Du 	if ((strcmp(res->mlx5, "mlx5") == 0) &&
328f41a5092SSpike Du 	    (strcmp(res->set, "set") == 0) &&
329f41a5092SSpike Du 	    (strcmp(res->port, "port") == 0) &&
330f41a5092SSpike Du 	    (strcmp(res->host_shaper, "host_shaper") == 0) &&
331f41a5092SSpike Du 	    (strcmp(res->avail_thresh_triggered, "avail_thresh_triggered") == 0) &&
332f41a5092SSpike Du 	    (strcmp(res->rate, "rate") == 0))
333f41a5092SSpike Du 		ret = mlx5_test_set_port_host_shaper(res->port_num, res->fr,
334f41a5092SSpike Du 					   res->rate_num);
335f41a5092SSpike Du 	if (ret < 0)
336f41a5092SSpike Du 		printf("cmd_port_host_shaper error: (%s)\n", strerror(-ret));
337f41a5092SSpike Du }
338f41a5092SSpike Du 
339f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_mlx5 =
340f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
341f41a5092SSpike Du 				mlx5, "mlx5");
342f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_set =
343f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
344f41a5092SSpike Du 				set, "set");
345f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_port =
346f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
347f41a5092SSpike Du 				port, "port");
348f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_portnum =
349f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
350f41a5092SSpike Du 				port_num, RTE_UINT16);
351f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_host_shaper =
352f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
353f41a5092SSpike Du 				 host_shaper, "host_shaper");
354f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_avail_thresh_triggered =
355f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
356f41a5092SSpike Du 				 avail_thresh_triggered, "avail_thresh_triggered");
357f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_fr =
358f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
359f41a5092SSpike Du 			      fr, RTE_UINT16);
360f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_rate =
361f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
362f41a5092SSpike Du 				 rate, "rate");
363f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_rate_num =
364f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
365f41a5092SSpike Du 			      rate_num, RTE_UINT8);
366f41a5092SSpike Du static cmdline_parse_inst_t mlx5_test_cmd_port_host_shaper = {
367f41a5092SSpike Du 	.f = cmd_port_host_shaper_parsed,
368f41a5092SSpike Du 	.data = (void *)0,
369f41a5092SSpike Du 	.help_str = "mlx5 set port <port_id> host_shaper avail_thresh_triggered <0|1> "
370f41a5092SSpike Du 	"rate <rate_num>: Set HOST_SHAPER avail_thresh_triggered and rate with port_id",
371f41a5092SSpike Du 	.tokens = {
372f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_mlx5,
373f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_set,
374f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_port,
375f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_portnum,
376f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_host_shaper,
377f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_avail_thresh_triggered,
378f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_fr,
379f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate,
380f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate_num,
381f41a5092SSpike Du 		NULL,
382f41a5092SSpike Du 	}
383f41a5092SSpike Du };
384f41a5092SSpike Du 
38585d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
38685d9252eSMichael Baum /* *** attach a specified port *** */
38785d9252eSMichael Baum struct mlx5_cmd_operate_attach_port_result {
38885d9252eSMichael Baum 	cmdline_fixed_string_t mlx5;
38985d9252eSMichael Baum 	cmdline_fixed_string_t port;
39085d9252eSMichael Baum 	cmdline_fixed_string_t keyword;
39185d9252eSMichael Baum 	cmdline_multi_string_t identifier;
39285d9252eSMichael Baum };
39385d9252eSMichael Baum 
39485d9252eSMichael Baum static void mlx5_cmd_operate_attach_port_parsed(void *parsed_result,
39585d9252eSMichael Baum 						__rte_unused struct cmdline *cl,
39685d9252eSMichael Baum 						__rte_unused void *data)
39785d9252eSMichael Baum {
39885d9252eSMichael Baum 	struct mlx5_cmd_operate_attach_port_result *res = parsed_result;
39985d9252eSMichael Baum 
40085d9252eSMichael Baum 	if (!strcmp(res->keyword, "attach"))
40185d9252eSMichael Baum 		mlx5_test_attach_port_extend_devargs(res->identifier);
40285d9252eSMichael Baum 	else
40385d9252eSMichael Baum 		fprintf(stderr, "Unknown parameter\n");
40485d9252eSMichael Baum }
40585d9252eSMichael Baum 
40685d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_mlx5 =
40785d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
40885d9252eSMichael Baum 				 mlx5, "mlx5");
40985d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_port =
41085d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
41185d9252eSMichael Baum 				 port, "port");
41285d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_keyword =
41385d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
41485d9252eSMichael Baum 				 keyword, "attach");
41585d9252eSMichael Baum static cmdline_parse_token_string_t mlx5_cmd_operate_attach_port_identifier =
41685d9252eSMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_operate_attach_port_result,
41785d9252eSMichael Baum 				 identifier, TOKEN_STRING_MULTI);
41885d9252eSMichael Baum 
41985d9252eSMichael Baum static cmdline_parse_inst_t mlx5_cmd_operate_attach_port = {
42085d9252eSMichael Baum 	.f = mlx5_cmd_operate_attach_port_parsed,
42185d9252eSMichael Baum 	.data = NULL,
42285d9252eSMichael Baum 	.help_str = "mlx5 port attach <identifier> socket=<path>: "
42385d9252eSMichael Baum 		"(identifier: pci address or virtual dev name"
42485d9252eSMichael Baum 		", path (optional): socket path to get cmd FD and PD handle)",
42585d9252eSMichael Baum 	.tokens = {
42685d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_mlx5,
42785d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_port,
42885d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_keyword,
42985d9252eSMichael Baum 		(void *)&mlx5_cmd_operate_attach_port_identifier,
43085d9252eSMichael Baum 		NULL,
43185d9252eSMichael Baum 	},
43285d9252eSMichael Baum };
43385d9252eSMichael Baum #endif
43485d9252eSMichael Baum 
435740a2836SMichael Baum /* Map HW queue index to rte queue index. */
436740a2836SMichael Baum struct mlx5_cmd_map_ext_rxq {
437740a2836SMichael Baum 	cmdline_fixed_string_t mlx5;
438740a2836SMichael Baum 	cmdline_fixed_string_t port;
439740a2836SMichael Baum 	portid_t port_id;
440740a2836SMichael Baum 	cmdline_fixed_string_t ext_rxq;
441740a2836SMichael Baum 	cmdline_fixed_string_t map;
442740a2836SMichael Baum 	uint16_t sw_queue_id;
443740a2836SMichael Baum 	uint32_t hw_queue_id;
444740a2836SMichael Baum };
445740a2836SMichael Baum 
446740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_mlx5 =
447740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, mlx5, "mlx5");
448740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_port =
449740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, port, "port");
450740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_port_id =
451740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, port_id, RTE_UINT16);
452740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_ext_rxq =
453740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, ext_rxq,
454740a2836SMichael Baum 				 "ext_rxq");
455740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_map_ext_rxq_map =
456740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_map_ext_rxq, map, "map");
457740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_sw_queue_id =
458740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, sw_queue_id,
459740a2836SMichael Baum 			      RTE_UINT16);
460740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_map_ext_rxq_hw_queue_id =
461740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_map_ext_rxq, hw_queue_id,
462740a2836SMichael Baum 			      RTE_UINT32);
463740a2836SMichael Baum 
464740a2836SMichael Baum static void
465740a2836SMichael Baum mlx5_cmd_map_ext_rxq_parsed(void *parsed_result,
466740a2836SMichael Baum 			    __rte_unused struct cmdline *cl,
467740a2836SMichael Baum 			    __rte_unused void *data)
468740a2836SMichael Baum {
469740a2836SMichael Baum 	struct mlx5_cmd_map_ext_rxq *res = parsed_result;
470740a2836SMichael Baum 	int ret;
471740a2836SMichael Baum 
472740a2836SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
473740a2836SMichael Baum 		return;
474740a2836SMichael Baum 	ret = rte_pmd_mlx5_external_rx_queue_id_map(res->port_id,
475740a2836SMichael Baum 						    res->sw_queue_id,
476740a2836SMichael Baum 						    res->hw_queue_id);
477740a2836SMichael Baum 	switch (ret) {
478740a2836SMichael Baum 	case 0:
479740a2836SMichael Baum 		break;
480740a2836SMichael Baum 	case -EINVAL:
481740a2836SMichael Baum 		fprintf(stderr, "invalid ethdev index (%u), out of range\n",
482740a2836SMichael Baum 			res->sw_queue_id);
483740a2836SMichael Baum 		break;
484740a2836SMichael Baum 	case -ENODEV:
485740a2836SMichael Baum 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
486740a2836SMichael Baum 		break;
487740a2836SMichael Baum 	case -ENOTSUP:
488740a2836SMichael Baum 		fprintf(stderr, "function not implemented or supported\n");
489740a2836SMichael Baum 		break;
490740a2836SMichael Baum 	case -EEXIST:
491740a2836SMichael Baum 		fprintf(stderr, "mapping with index %u already exists\n",
492740a2836SMichael Baum 			res->sw_queue_id);
493740a2836SMichael Baum 		break;
494740a2836SMichael Baum 	default:
495740a2836SMichael Baum 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
496740a2836SMichael Baum 	}
497740a2836SMichael Baum }
498740a2836SMichael Baum 
499740a2836SMichael Baum cmdline_parse_inst_t mlx5_cmd_map_ext_rxq = {
500740a2836SMichael Baum 	.f = mlx5_cmd_map_ext_rxq_parsed,
501740a2836SMichael Baum 	.data = NULL,
502740a2836SMichael Baum 	.help_str = "mlx5 port <port_id> ext_rxq map <sw_queue_id> <hw_queue_id>",
503740a2836SMichael Baum 	.tokens = {
504740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_mlx5,
505740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_port,
506740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_port_id,
507740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_ext_rxq,
508740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_map,
509740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_sw_queue_id,
510740a2836SMichael Baum 		(void *)&mlx5_cmd_map_ext_rxq_hw_queue_id,
511740a2836SMichael Baum 		NULL,
512740a2836SMichael Baum 	}
513740a2836SMichael Baum };
514740a2836SMichael Baum 
515740a2836SMichael Baum /* Unmap HW queue index to rte queue index. */
516740a2836SMichael Baum struct mlx5_cmd_unmap_ext_rxq {
517740a2836SMichael Baum 	cmdline_fixed_string_t mlx5;
518740a2836SMichael Baum 	cmdline_fixed_string_t port;
519740a2836SMichael Baum 	portid_t port_id;
520740a2836SMichael Baum 	cmdline_fixed_string_t ext_rxq;
521740a2836SMichael Baum 	cmdline_fixed_string_t unmap;
522740a2836SMichael Baum 	uint16_t queue_id;
523740a2836SMichael Baum };
524740a2836SMichael Baum 
525740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_mlx5 =
526740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, mlx5, "mlx5");
527740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_port =
528740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, port, "port");
529740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_unmap_ext_rxq_port_id =
530740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, port_id,
531740a2836SMichael Baum 			      RTE_UINT16);
532740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_ext_rxq =
533740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, ext_rxq,
534740a2836SMichael Baum 				 "ext_rxq");
535740a2836SMichael Baum cmdline_parse_token_string_t mlx5_cmd_unmap_ext_rxq_unmap =
536740a2836SMichael Baum 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, unmap, "unmap");
537740a2836SMichael Baum cmdline_parse_token_num_t mlx5_cmd_unmap_ext_rxq_queue_id =
538740a2836SMichael Baum 	TOKEN_NUM_INITIALIZER(struct mlx5_cmd_unmap_ext_rxq, queue_id,
539740a2836SMichael Baum 			      RTE_UINT16);
540740a2836SMichael Baum 
541740a2836SMichael Baum static void
542740a2836SMichael Baum mlx5_cmd_unmap_ext_rxq_parsed(void *parsed_result,
543740a2836SMichael Baum 			      __rte_unused struct cmdline *cl,
544740a2836SMichael Baum 			      __rte_unused void *data)
545740a2836SMichael Baum {
546740a2836SMichael Baum 	struct mlx5_cmd_unmap_ext_rxq *res = parsed_result;
547740a2836SMichael Baum 	int ret;
548740a2836SMichael Baum 
549740a2836SMichael Baum 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
550740a2836SMichael Baum 		return;
551740a2836SMichael Baum 	ret = rte_pmd_mlx5_external_rx_queue_id_unmap(res->port_id,
552740a2836SMichael Baum 						      res->queue_id);
553740a2836SMichael Baum 	switch (ret) {
554740a2836SMichael Baum 	case 0:
555740a2836SMichael Baum 		break;
556740a2836SMichael Baum 	case -EINVAL:
557740a2836SMichael Baum 		fprintf(stderr, "invalid rte_flow index (%u), "
558740a2836SMichael Baum 			"out of range, doesn't exist or still referenced\n",
559740a2836SMichael Baum 			res->queue_id);
560740a2836SMichael Baum 		break;
561740a2836SMichael Baum 	case -ENODEV:
562740a2836SMichael Baum 		fprintf(stderr, "invalid port_id %u\n", res->port_id);
563740a2836SMichael Baum 		break;
564740a2836SMichael Baum 	case -ENOTSUP:
565740a2836SMichael Baum 		fprintf(stderr, "function not implemented or supported\n");
566740a2836SMichael Baum 		break;
567740a2836SMichael Baum 	default:
568740a2836SMichael Baum 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
569740a2836SMichael Baum 	}
570740a2836SMichael Baum }
571740a2836SMichael Baum 
572740a2836SMichael Baum cmdline_parse_inst_t mlx5_cmd_unmap_ext_rxq = {
573740a2836SMichael Baum 	.f = mlx5_cmd_unmap_ext_rxq_parsed,
574740a2836SMichael Baum 	.data = NULL,
575740a2836SMichael Baum 	.help_str = "mlx5 port <port_id> ext_rxq unmap <queue_id>",
576740a2836SMichael Baum 	.tokens = {
577740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_mlx5,
578740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_port,
579740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_port_id,
580740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_ext_rxq,
581740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_unmap,
582740a2836SMichael Baum 		(void *)&mlx5_cmd_unmap_ext_rxq_queue_id,
583740a2836SMichael Baum 		NULL,
584740a2836SMichael Baum 	}
585740a2836SMichael Baum };
586740a2836SMichael Baum 
587*baafc81eSRongwei Liu /* Set flow engine mode with flags command. */
588*baafc81eSRongwei Liu struct mlx5_cmd_set_flow_engine_mode {
589*baafc81eSRongwei Liu 	cmdline_fixed_string_t mlx5;
590*baafc81eSRongwei Liu 	cmdline_fixed_string_t set;
591*baafc81eSRongwei Liu 	cmdline_fixed_string_t flow_engine;
592*baafc81eSRongwei Liu 	cmdline_multi_string_t mode;
593*baafc81eSRongwei Liu };
594*baafc81eSRongwei Liu 
595*baafc81eSRongwei Liu static int
596*baafc81eSRongwei Liu parse_multi_token_flow_engine_mode(char *t_str, enum mlx5_flow_engine_mode *mode,
597*baafc81eSRongwei Liu 				   uint32_t *flag)
598*baafc81eSRongwei Liu {
599*baafc81eSRongwei Liu 	uint64_t val;
600*baafc81eSRongwei Liu 	char *token;
601*baafc81eSRongwei Liu 	int ret;
602*baafc81eSRongwei Liu 
603*baafc81eSRongwei Liu 	*flag = 0;
604*baafc81eSRongwei Liu 	/* First token: mode string */
605*baafc81eSRongwei Liu 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
606*baafc81eSRongwei Liu 	if (token ==  NULL)
607*baafc81eSRongwei Liu 		return -1;
608*baafc81eSRongwei Liu 
609*baafc81eSRongwei Liu 	if (!strcmp(token, "active"))
610*baafc81eSRongwei Liu 		*mode = MLX5_FLOW_ENGINE_MODE_ACTIVE;
611*baafc81eSRongwei Liu 	else if (!strcmp(token, "standby"))
612*baafc81eSRongwei Liu 		*mode = MLX5_FLOW_ENGINE_MODE_STANDBY;
613*baafc81eSRongwei Liu 	else
614*baafc81eSRongwei Liu 		return -1;
615*baafc81eSRongwei Liu 
616*baafc81eSRongwei Liu 	/* Second token: flag */
617*baafc81eSRongwei Liu 	token = strtok_r(t_str, PARSE_DELIMITER, &t_str);
618*baafc81eSRongwei Liu 	if (token == NULL)
619*baafc81eSRongwei Liu 		return 0;
620*baafc81eSRongwei Liu 
621*baafc81eSRongwei Liu 	ret = parse_uint(&val, token);
622*baafc81eSRongwei Liu 	if (ret != 0 || val > UINT32_MAX)
623*baafc81eSRongwei Liu 		return -1;
624*baafc81eSRongwei Liu 
625*baafc81eSRongwei Liu 	*flag = val;
626*baafc81eSRongwei Liu 	return 0;
627*baafc81eSRongwei Liu }
628*baafc81eSRongwei Liu 
629*baafc81eSRongwei Liu static void
630*baafc81eSRongwei Liu mlx5_cmd_set_flow_engine_mode_parsed(void *parsed_result,
631*baafc81eSRongwei Liu 				     __rte_unused struct cmdline *cl,
632*baafc81eSRongwei Liu 				     __rte_unused void *data)
633*baafc81eSRongwei Liu {
634*baafc81eSRongwei Liu 	struct mlx5_cmd_set_flow_engine_mode *res = parsed_result;
635*baafc81eSRongwei Liu 	enum mlx5_flow_engine_mode mode;
636*baafc81eSRongwei Liu 	uint32_t flag;
637*baafc81eSRongwei Liu 	int ret;
638*baafc81eSRongwei Liu 
639*baafc81eSRongwei Liu 	ret = parse_multi_token_flow_engine_mode(res->mode, &mode, &flag);
640*baafc81eSRongwei Liu 
641*baafc81eSRongwei Liu 	if (ret < 0) {
642*baafc81eSRongwei Liu 		fprintf(stderr, "Bad input\n");
643*baafc81eSRongwei Liu 		return;
644*baafc81eSRongwei Liu 	}
645*baafc81eSRongwei Liu 
646*baafc81eSRongwei Liu 	ret = rte_pmd_mlx5_flow_engine_set_mode(mode, flag);
647*baafc81eSRongwei Liu 
648*baafc81eSRongwei Liu 	if (ret < 0)
649*baafc81eSRongwei Liu 		fprintf(stderr, "Fail to set flow_engine to %s mode with flag 0x%x, error %s\n",
650*baafc81eSRongwei Liu 			mode == MLX5_FLOW_ENGINE_MODE_ACTIVE ? "active" : "standby", flag,
651*baafc81eSRongwei Liu 			strerror(-ret));
652*baafc81eSRongwei Liu 	else
653*baafc81eSRongwei Liu 		TESTPMD_LOG(DEBUG, "Set %d ports flow_engine to %s mode with flag 0x%x\n", ret,
654*baafc81eSRongwei Liu 			    mode == MLX5_FLOW_ENGINE_MODE_ACTIVE ? "active" : "standby", flag);
655*baafc81eSRongwei Liu }
656*baafc81eSRongwei Liu 
657*baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_mlx5 =
658*baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, mlx5,
659*baafc81eSRongwei Liu 				 "mlx5");
660*baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_set =
661*baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, set,
662*baafc81eSRongwei Liu 				 "set");
663*baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_flow_engine =
664*baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, flow_engine,
665*baafc81eSRongwei Liu 				 "flow_engine");
666*baafc81eSRongwei Liu cmdline_parse_token_string_t mlx5_cmd_set_flow_engine_mode_mode =
667*baafc81eSRongwei Liu 	TOKEN_STRING_INITIALIZER(struct mlx5_cmd_set_flow_engine_mode, mode,
668*baafc81eSRongwei Liu 				 TOKEN_STRING_MULTI);
669*baafc81eSRongwei Liu 
670*baafc81eSRongwei Liu cmdline_parse_inst_t mlx5_cmd_set_flow_engine_mode = {
671*baafc81eSRongwei Liu 	.f = &mlx5_cmd_set_flow_engine_mode_parsed,
672*baafc81eSRongwei Liu 	.data = NULL,
673*baafc81eSRongwei Liu 	.help_str = "mlx5 set flow_engine <active|standby> [<flag>]",
674*baafc81eSRongwei Liu 	.tokens = {
675*baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_mlx5,
676*baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_set,
677*baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_flow_engine,
678*baafc81eSRongwei Liu 		(void *)&mlx5_cmd_set_flow_engine_mode_mode,
679*baafc81eSRongwei Liu 		NULL,
680*baafc81eSRongwei Liu 	}
681*baafc81eSRongwei Liu };
682*baafc81eSRongwei Liu 
683f41a5092SSpike Du static struct testpmd_driver_commands mlx5_driver_cmds = {
684f41a5092SSpike Du 	.commands = {
685f41a5092SSpike Du 		{
686f41a5092SSpike Du 			.ctx = &mlx5_test_cmd_port_host_shaper,
687f41a5092SSpike Du 			.help = "mlx5 set port (port_id) host_shaper avail_thresh_triggered (on|off)"
688f41a5092SSpike Du 				"rate (rate_num):\n"
689f41a5092SSpike Du 				"    Set HOST_SHAPER avail_thresh_triggered and rate with port_id\n\n",
690f41a5092SSpike Du 		},
69185d9252eSMichael Baum #ifndef RTE_EXEC_ENV_WINDOWS
69285d9252eSMichael Baum 		{
69385d9252eSMichael Baum 			.ctx = &mlx5_cmd_operate_attach_port,
69485d9252eSMichael Baum 			.help = "mlx5 port attach (ident) socket=(path)\n"
69585d9252eSMichael Baum 				"    Attach physical or virtual dev by pci address or virtual device name "
69685d9252eSMichael Baum 				"and add \"cmd_fd\" and \"pd_handle\" devargs before attaching\n\n",
69785d9252eSMichael Baum 		},
69885d9252eSMichael Baum #endif
699f41a5092SSpike Du 		{
700740a2836SMichael Baum 			.ctx = &mlx5_cmd_map_ext_rxq,
701740a2836SMichael Baum 			.help = "mlx5 port (port_id) ext_rxq map (sw_queue_id) (hw_queue_id)\n"
702740a2836SMichael Baum 				"    Map HW queue index (32-bit) to ethdev"
703740a2836SMichael Baum 				" queue index (16-bit) for external RxQ\n\n",
704740a2836SMichael Baum 		},
705740a2836SMichael Baum 		{
706740a2836SMichael Baum 			.ctx = &mlx5_cmd_unmap_ext_rxq,
707740a2836SMichael Baum 			.help = "mlx5 port (port_id) ext_rxq unmap (sw_queue_id)\n"
708740a2836SMichael Baum 				"    Unmap external Rx queue ethdev index mapping\n\n",
709740a2836SMichael Baum 		},
710740a2836SMichael Baum 		{
711*baafc81eSRongwei Liu 			.ctx = &mlx5_cmd_set_flow_engine_mode,
712*baafc81eSRongwei Liu 			.help = "mlx5 set flow_engine (active|standby) [(flag)]\n"
713*baafc81eSRongwei Liu 				"    Set flow_engine to the specific mode with flag.\n\n"
714*baafc81eSRongwei Liu 		},
715*baafc81eSRongwei Liu 		{
716f41a5092SSpike Du 			.ctx = NULL,
717f41a5092SSpike Du 		},
718f41a5092SSpike Du 	}
719f41a5092SSpike Du };
720f41a5092SSpike Du TESTPMD_ADD_DRIVER_COMMANDS(mlx5_driver_cmds);
721