xref: /dpdk/drivers/net/mlx5/mlx5_testpmd.c (revision f41a5092e6ae655954bf14f33f54ddf4c83e1cc0)
1*f41a5092SSpike Du /* SPDX-License-Identifier: BSD-3-Clause
2*f41a5092SSpike Du  * Copyright 2021 6WIND S.A.
3*f41a5092SSpike Du  * Copyright 2021 Mellanox Technologies, Ltd
4*f41a5092SSpike Du  */
5*f41a5092SSpike Du 
6*f41a5092SSpike Du #include <stdint.h>
7*f41a5092SSpike Du #include <string.h>
8*f41a5092SSpike Du #include <stdlib.h>
9*f41a5092SSpike Du 
10*f41a5092SSpike Du #include <rte_prefetch.h>
11*f41a5092SSpike Du #include <rte_common.h>
12*f41a5092SSpike Du #include <rte_branch_prediction.h>
13*f41a5092SSpike Du #include <rte_ether.h>
14*f41a5092SSpike Du #include <rte_alarm.h>
15*f41a5092SSpike Du #include <rte_pmd_mlx5.h>
16*f41a5092SSpike Du #include <rte_ethdev.h>
17*f41a5092SSpike Du #include "mlx5_testpmd.h"
18*f41a5092SSpike Du #include "testpmd.h"
19*f41a5092SSpike Du 
20*f41a5092SSpike Du static uint8_t host_shaper_avail_thresh_triggered[RTE_MAX_ETHPORTS];
21*f41a5092SSpike Du #define SHAPER_DISABLE_DELAY_US 100000 /* 100ms */
22*f41a5092SSpike Du 
23*f41a5092SSpike Du /**
24*f41a5092SSpike Du  * Disable the host shaper and re-arm available descriptor threshold event.
25*f41a5092SSpike Du  *
26*f41a5092SSpike Du  * @param[in] args
27*f41a5092SSpike Du  *   uint32_t integer combining port_id and rxq_id.
28*f41a5092SSpike Du  */
29*f41a5092SSpike Du static void
30*f41a5092SSpike Du mlx5_test_host_shaper_disable(void *args)
31*f41a5092SSpike Du {
32*f41a5092SSpike Du 	uint32_t port_rxq_id = (uint32_t)(uintptr_t)args;
33*f41a5092SSpike Du 	uint16_t port_id = port_rxq_id & 0xffff;
34*f41a5092SSpike Du 	uint16_t qid = (port_rxq_id >> 16) & 0xffff;
35*f41a5092SSpike Du 	struct rte_eth_rxq_info qinfo;
36*f41a5092SSpike Du 
37*f41a5092SSpike Du 	printf("%s disable shaper\n", __func__);
38*f41a5092SSpike Du 	if (rte_eth_rx_queue_info_get(port_id, qid, &qinfo)) {
39*f41a5092SSpike Du 		printf("rx_queue_info_get returns error\n");
40*f41a5092SSpike Du 		return;
41*f41a5092SSpike Du 	}
42*f41a5092SSpike Du 	/* Rearm the available descriptor threshold event. */
43*f41a5092SSpike Du 	if (rte_eth_rx_avail_thresh_set(port_id, qid, qinfo.avail_thresh)) {
44*f41a5092SSpike Du 		printf("config avail_thresh returns error\n");
45*f41a5092SSpike Du 		return;
46*f41a5092SSpike Du 	}
47*f41a5092SSpike Du 	/* Only disable the shaper when avail_thresh_triggered is set. */
48*f41a5092SSpike Du 	if (host_shaper_avail_thresh_triggered[port_id] &&
49*f41a5092SSpike Du 	    rte_pmd_mlx5_host_shaper_config(port_id, 0, 0))
50*f41a5092SSpike Du 		printf("%s disable shaper returns error\n", __func__);
51*f41a5092SSpike Du }
52*f41a5092SSpike Du 
53*f41a5092SSpike Du void
54*f41a5092SSpike Du mlx5_test_avail_thresh_event_handler(uint16_t port_id, uint16_t rxq_id)
55*f41a5092SSpike Du {
56*f41a5092SSpike Du 	struct rte_eth_dev_info dev_info;
57*f41a5092SSpike Du 	uint32_t port_rxq_id = port_id | (rxq_id << 16);
58*f41a5092SSpike Du 
59*f41a5092SSpike Du 	/* Ensure it's MLX5 port. */
60*f41a5092SSpike Du 	if (rte_eth_dev_info_get(port_id, &dev_info) != 0 ||
61*f41a5092SSpike Du 	    (strncmp(dev_info.driver_name, "mlx5", 4) != 0))
62*f41a5092SSpike Du 		return;
63*f41a5092SSpike Du 	rte_eal_alarm_set(SHAPER_DISABLE_DELAY_US,
64*f41a5092SSpike Du 			  mlx5_test_host_shaper_disable,
65*f41a5092SSpike Du 			  (void *)(uintptr_t)port_rxq_id);
66*f41a5092SSpike Du 	printf("%s port_id:%u rxq_id:%u\n", __func__, port_id, rxq_id);
67*f41a5092SSpike Du }
68*f41a5092SSpike Du 
69*f41a5092SSpike Du /**
70*f41a5092SSpike Du  * Configure host shaper's avail_thresh_triggered and current rate.
71*f41a5092SSpike Du  *
72*f41a5092SSpike Du  * @param[in] avail_thresh_triggered
73*f41a5092SSpike Du  *   Disable/enable avail_thresh_triggered.
74*f41a5092SSpike Du  * @param[in] rate
75*f41a5092SSpike Du  *   Configure current host shaper rate.
76*f41a5092SSpike Du  * @return
77*f41a5092SSpike Du  *   On success, returns 0.
78*f41a5092SSpike Du  *   On failure, returns < 0.
79*f41a5092SSpike Du  */
80*f41a5092SSpike Du static int
81*f41a5092SSpike Du mlx5_test_set_port_host_shaper(uint16_t port_id, uint16_t avail_thresh_triggered, uint8_t rate)
82*f41a5092SSpike Du {
83*f41a5092SSpike Du 	struct rte_eth_link link;
84*f41a5092SSpike Du 	bool port_id_valid = false;
85*f41a5092SSpike Du 	uint16_t pid;
86*f41a5092SSpike Du 	int ret;
87*f41a5092SSpike Du 
88*f41a5092SSpike Du 	RTE_ETH_FOREACH_DEV(pid)
89*f41a5092SSpike Du 		if (port_id == pid) {
90*f41a5092SSpike Du 			port_id_valid = true;
91*f41a5092SSpike Du 			break;
92*f41a5092SSpike Du 		}
93*f41a5092SSpike Du 	if (!port_id_valid)
94*f41a5092SSpike Du 		return -EINVAL;
95*f41a5092SSpike Du 	ret = rte_eth_link_get_nowait(port_id, &link);
96*f41a5092SSpike Du 	if (ret < 0)
97*f41a5092SSpike Du 		return ret;
98*f41a5092SSpike Du 	host_shaper_avail_thresh_triggered[port_id] = avail_thresh_triggered ? 1 : 0;
99*f41a5092SSpike Du 	if (!avail_thresh_triggered) {
100*f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 0,
101*f41a5092SSpike Du 		RTE_BIT32(MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
102*f41a5092SSpike Du 	} else {
103*f41a5092SSpike Du 		ret = rte_pmd_mlx5_host_shaper_config(port_id, 1,
104*f41a5092SSpike Du 		RTE_BIT32(MLX5_HOST_SHAPER_FLAG_AVAIL_THRESH_TRIGGERED));
105*f41a5092SSpike Du 	}
106*f41a5092SSpike Du 	if (ret)
107*f41a5092SSpike Du 		return ret;
108*f41a5092SSpike Du 	ret = rte_pmd_mlx5_host_shaper_config(port_id, rate, 0);
109*f41a5092SSpike Du 	if (ret)
110*f41a5092SSpike Du 		return ret;
111*f41a5092SSpike Du 	return 0;
112*f41a5092SSpike Du }
113*f41a5092SSpike Du 
114*f41a5092SSpike Du /* *** SET HOST_SHAPER FOR A PORT *** */
115*f41a5092SSpike Du struct cmd_port_host_shaper_result {
116*f41a5092SSpike Du 	cmdline_fixed_string_t mlx5;
117*f41a5092SSpike Du 	cmdline_fixed_string_t set;
118*f41a5092SSpike Du 	cmdline_fixed_string_t port;
119*f41a5092SSpike Du 	uint16_t port_num;
120*f41a5092SSpike Du 	cmdline_fixed_string_t host_shaper;
121*f41a5092SSpike Du 	cmdline_fixed_string_t avail_thresh_triggered;
122*f41a5092SSpike Du 	uint16_t fr;
123*f41a5092SSpike Du 	cmdline_fixed_string_t rate;
124*f41a5092SSpike Du 	uint8_t rate_num;
125*f41a5092SSpike Du };
126*f41a5092SSpike Du 
127*f41a5092SSpike Du static void cmd_port_host_shaper_parsed(void *parsed_result,
128*f41a5092SSpike Du 		__rte_unused struct cmdline *cl,
129*f41a5092SSpike Du 		__rte_unused void *data)
130*f41a5092SSpike Du {
131*f41a5092SSpike Du 	struct cmd_port_host_shaper_result *res = parsed_result;
132*f41a5092SSpike Du 	int ret = 0;
133*f41a5092SSpike Du 
134*f41a5092SSpike Du 	if ((strcmp(res->mlx5, "mlx5") == 0) &&
135*f41a5092SSpike Du 	    (strcmp(res->set, "set") == 0) &&
136*f41a5092SSpike Du 	    (strcmp(res->port, "port") == 0) &&
137*f41a5092SSpike Du 	    (strcmp(res->host_shaper, "host_shaper") == 0) &&
138*f41a5092SSpike Du 	    (strcmp(res->avail_thresh_triggered, "avail_thresh_triggered") == 0) &&
139*f41a5092SSpike Du 	    (strcmp(res->rate, "rate") == 0))
140*f41a5092SSpike Du 		ret = mlx5_test_set_port_host_shaper(res->port_num, res->fr,
141*f41a5092SSpike Du 					   res->rate_num);
142*f41a5092SSpike Du 	if (ret < 0)
143*f41a5092SSpike Du 		printf("cmd_port_host_shaper error: (%s)\n", strerror(-ret));
144*f41a5092SSpike Du }
145*f41a5092SSpike Du 
146*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_mlx5 =
147*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
148*f41a5092SSpike Du 				mlx5, "mlx5");
149*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_set =
150*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
151*f41a5092SSpike Du 				set, "set");
152*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_port =
153*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
154*f41a5092SSpike Du 				port, "port");
155*f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_portnum =
156*f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
157*f41a5092SSpike Du 				port_num, RTE_UINT16);
158*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_host_shaper =
159*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
160*f41a5092SSpike Du 				 host_shaper, "host_shaper");
161*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_avail_thresh_triggered =
162*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
163*f41a5092SSpike Du 				 avail_thresh_triggered, "avail_thresh_triggered");
164*f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_fr =
165*f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
166*f41a5092SSpike Du 			      fr, RTE_UINT16);
167*f41a5092SSpike Du static cmdline_parse_token_string_t cmd_port_host_shaper_rate =
168*f41a5092SSpike Du 	TOKEN_STRING_INITIALIZER(struct cmd_port_host_shaper_result,
169*f41a5092SSpike Du 				 rate, "rate");
170*f41a5092SSpike Du static cmdline_parse_token_num_t cmd_port_host_shaper_rate_num =
171*f41a5092SSpike Du 	TOKEN_NUM_INITIALIZER(struct cmd_port_host_shaper_result,
172*f41a5092SSpike Du 			      rate_num, RTE_UINT8);
173*f41a5092SSpike Du static cmdline_parse_inst_t mlx5_test_cmd_port_host_shaper = {
174*f41a5092SSpike Du 	.f = cmd_port_host_shaper_parsed,
175*f41a5092SSpike Du 	.data = (void *)0,
176*f41a5092SSpike Du 	.help_str = "mlx5 set port <port_id> host_shaper avail_thresh_triggered <0|1> "
177*f41a5092SSpike Du 	"rate <rate_num>: Set HOST_SHAPER avail_thresh_triggered and rate with port_id",
178*f41a5092SSpike Du 	.tokens = {
179*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_mlx5,
180*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_set,
181*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_port,
182*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_portnum,
183*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_host_shaper,
184*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_avail_thresh_triggered,
185*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_fr,
186*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate,
187*f41a5092SSpike Du 		(void *)&cmd_port_host_shaper_rate_num,
188*f41a5092SSpike Du 		NULL,
189*f41a5092SSpike Du 	}
190*f41a5092SSpike Du };
191*f41a5092SSpike Du 
192*f41a5092SSpike Du static struct testpmd_driver_commands mlx5_driver_cmds = {
193*f41a5092SSpike Du 	.commands = {
194*f41a5092SSpike Du 		{
195*f41a5092SSpike Du 			.ctx = &mlx5_test_cmd_port_host_shaper,
196*f41a5092SSpike Du 			.help = "mlx5 set port (port_id) host_shaper avail_thresh_triggered (on|off)"
197*f41a5092SSpike Du 				"rate (rate_num):\n"
198*f41a5092SSpike Du 				"    Set HOST_SHAPER avail_thresh_triggered and rate with port_id\n\n",
199*f41a5092SSpike Du 		},
200*f41a5092SSpike Du 		{
201*f41a5092SSpike Du 			.ctx = NULL,
202*f41a5092SSpike Du 		},
203*f41a5092SSpike Du 	}
204*f41a5092SSpike Du };
205*f41a5092SSpike Du TESTPMD_ADD_DRIVER_COMMANDS(mlx5_driver_cmds);
206