summaryrefslogtreecommitdiffstats
path: root/dcb/dcb_maxrate.c
blob: 1538c6d7c4cfa20b9d5382031b80ed99a1733fcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// SPDX-License-Identifier: GPL-2.0+

#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <linux/dcbnl.h>

#include "dcb.h"
#include "utils.h"

static void dcb_maxrate_help_set(void)
{
	fprintf(stderr,
		"Usage: dcb maxrate set dev STRING\n"
		"           [ tc-maxrate RATE-MAP ]\n"
		"\n"
		" where RATE-MAP := [ RATE-MAP ] RATE-MAPPING\n"
		"       RATE-MAPPING := { all | TC }:RATE\n"
		"       TC := { 0 .. 7 }\n"
		"\n"
	);
}

static void dcb_maxrate_help_show(void)
{
	fprintf(stderr,
		"Usage: dcb [ -i ] maxrate show dev STRING\n"
		"           [ tc-maxrate ]\n"
		"\n"
	);
}

static void dcb_maxrate_help(void)
{
	fprintf(stderr,
		"Usage: dcb maxrate help\n"
		"\n"
	);
	dcb_maxrate_help_show();
	dcb_maxrate_help_set();
}

static int dcb_maxrate_parse_mapping_tc_maxrate(__u32 key, char *value, void *data)
{
	__u64 rate;

	if (get_rate64(&rate, value))
		return -EINVAL;

	return dcb_parse_mapping("TC", key, IEEE_8021QAZ_MAX_TCS - 1,
				 "RATE", rate, -1,
				 dcb_set_u64, data);
}

static void dcb_maxrate_print_tc_maxrate(struct dcb *dcb, const struct ieee_maxrate *maxrate)
{
	size_t size = ARRAY_SIZE(maxrate->tc_maxrate);
	SPRINT_BUF(b);
	size_t i;

	open_json_array(PRINT_JSON, "tc_maxrate");
	print_string(PRINT_FP, NULL, "tc-maxrate ", NULL);

	for (i = 0; i < size; i++) {
		snprintf(b, sizeof(b), "%zd:%%s ", i);
		print_rate(dcb->use_iec, PRINT_ANY, NULL, b, maxrate->tc_maxrate[i]);
	}

	close_json_array(PRINT_JSON, "tc_maxrate");
}

static void dcb_maxrate_print(struct dcb *dcb, const struct ieee_maxrate *maxrate)
{
	dcb_maxrate_print_tc_maxrate(dcb, maxrate);
	print_nl();
}

static int dcb_maxrate_get(struct dcb *dcb, const char *dev, struct ieee_maxrate *maxrate)
{
	return dcb_get_attribute(dcb, dev, DCB_ATTR_IEEE_MAXRATE, maxrate, sizeof(*maxrate));
}

static int dcb_maxrate_set(struct dcb *dcb, const char *dev, const struct ieee_maxrate *maxrate)
{
	return dcb_set_attribute(dcb, dev, DCB_ATTR_IEEE_MAXRATE, maxrate, sizeof(*maxrate));
}

static int dcb_cmd_maxrate_set(struct dcb *dcb, const char *dev, int argc, char **argv)
{
	struct ieee_maxrate maxrate;
	int ret;

	if (!argc) {
		dcb_maxrate_help_set();
		return 0;
	}

	ret = dcb_maxrate_get(dcb, dev, &maxrate);
	if (ret)
		return ret;

	do {
		if (matches(*argv, "help") == 0) {
			dcb_maxrate_help_set();
			return 0;
		} else if (matches(*argv, "tc-maxrate") == 0) {
			NEXT_ARG();
			ret = parse_mapping(&argc, &argv, true,
					    &dcb_maxrate_parse_mapping_tc_maxrate, &maxrate);
			if (ret) {
				fprintf(stderr, "Invalid mapping %s\n", *argv);
				return ret;
			}
			continue;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			dcb_maxrate_help_set();
			return -EINVAL;
		}

		NEXT_ARG_FWD();
	} while (argc > 0);

	return dcb_maxrate_set(dcb, dev, &maxrate);
}

static int dcb_cmd_maxrate_show(struct dcb *dcb, const char *dev, int argc, char **argv)
{
	struct ieee_maxrate maxrate;
	int ret;

	ret = dcb_maxrate_get(dcb, dev, &maxrate);
	if (ret)
		return ret;

	open_json_object(NULL);

	if (!argc) {
		dcb_maxrate_print(dcb, &maxrate);
		goto out;
	}

	do {
		if (matches(*argv, "help") == 0) {
			dcb_maxrate_help_show();
			return 0;
		} else if (matches(*argv, "tc-maxrate") == 0) {
			dcb_maxrate_print_tc_maxrate(dcb, &maxrate);
			print_nl();
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			dcb_maxrate_help_show();
			return -EINVAL;
		}

		NEXT_ARG_FWD();
	} while (argc > 0);

out:
	close_json_object();
	return 0;
}

int dcb_cmd_maxrate(struct dcb *dcb, int argc, char **argv)
{
	if (!argc || matches(*argv, "help") == 0) {
		dcb_maxrate_help();
		return 0;
	} else if (matches(*argv, "show") == 0) {
		NEXT_ARG_FWD();
		return dcb_cmd_parse_dev(dcb, argc, argv,
					 dcb_cmd_maxrate_show, dcb_maxrate_help_show);
	} else if (matches(*argv, "set") == 0) {
		NEXT_ARG_FWD();
		return dcb_cmd_parse_dev(dcb, argc, argv,
					 dcb_cmd_maxrate_set, dcb_maxrate_help_set);
	} else {
		fprintf(stderr, "What is \"%s\"?\n", *argv);
		dcb_maxrate_help();
		return -EINVAL;
	}
}