]>
Commit | Line | Data |
---|---|---|
2e36f910 PM |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | ||
3 | #include <errno.h> | |
4 | #include <inttypes.h> | |
5 | #include <stdio.h> | |
6 | #include <linux/dcbnl.h> | |
7 | ||
8 | #include "dcb.h" | |
9 | #include "utils.h" | |
10 | ||
11 | static void dcb_buffer_help_set(void) | |
12 | { | |
13 | fprintf(stderr, | |
14 | "Usage: dcb buffer set dev STRING\n" | |
15 | " [ prio-buffer PRIO-MAP ]\n" | |
16 | " [ buffer-size SIZE-MAP ]\n" | |
17 | "\n" | |
18 | " where PRIO-MAP := [ PRIO-MAP ] PRIO-MAPPING\n" | |
19 | " PRIO-MAPPING := { all | PRIO }:BUFFER\n" | |
20 | " SIZE-MAP := [ SIZE-MAP ] SIZE-MAPPING\n" | |
21 | " SIZE-MAPPING := { all | BUFFER }:INTEGER\n" | |
22 | " PRIO := { 0 .. 7 }\n" | |
23 | " BUFFER := { 0 .. 7 }\n" | |
24 | "\n" | |
25 | ); | |
26 | } | |
27 | ||
28 | static void dcb_buffer_help_show(void) | |
29 | { | |
30 | fprintf(stderr, | |
31 | "Usage: dcb buffer show dev STRING\n" | |
32 | " [ prio-buffer ] [ buffer-size ] [ total-size ]\n" | |
33 | "\n" | |
34 | ); | |
35 | } | |
36 | ||
37 | static void dcb_buffer_help(void) | |
38 | { | |
39 | fprintf(stderr, | |
40 | "Usage: dcb buffer help\n" | |
41 | "\n" | |
42 | ); | |
43 | dcb_buffer_help_show(); | |
44 | dcb_buffer_help_set(); | |
45 | } | |
46 | ||
47 | static int dcb_buffer_parse_mapping_prio_buffer(__u32 key, char *value, void *data) | |
48 | { | |
49 | struct dcbnl_buffer *buffer = data; | |
50 | __u8 buf; | |
51 | ||
52 | if (get_u8(&buf, value, 0)) | |
53 | return -EINVAL; | |
54 | ||
55 | return dcb_parse_mapping("PRIO", key, IEEE_8021Q_MAX_PRIORITIES - 1, | |
56 | "BUFFER", buf, DCBX_MAX_BUFFERS - 1, | |
57 | dcb_set_u8, buffer->prio2buffer); | |
58 | } | |
59 | ||
60 | static int dcb_buffer_parse_mapping_buffer_size(__u32 key, char *value, void *data) | |
61 | { | |
62 | struct dcbnl_buffer *buffer = data; | |
63 | unsigned int size; | |
64 | ||
65 | if (get_size(&size, value)) { | |
66 | fprintf(stderr, "%d:%s: Illegal value for buffer size\n", key, value); | |
67 | return -EINVAL; | |
68 | } | |
69 | ||
70 | return dcb_parse_mapping("BUFFER", key, DCBX_MAX_BUFFERS - 1, | |
71 | "INTEGER", size, -1, | |
72 | dcb_set_u32, buffer->buffer_size); | |
73 | } | |
74 | ||
75 | static void dcb_buffer_print_total_size(const struct dcbnl_buffer *buffer) | |
76 | { | |
77 | print_size(PRINT_ANY, "total_size", "total-size %s ", buffer->total_size); | |
78 | } | |
79 | ||
80 | static void dcb_buffer_print_prio_buffer(const struct dcbnl_buffer *buffer) | |
81 | { | |
82 | dcb_print_named_array("prio_buffer", "prio-buffer", | |
83 | buffer->prio2buffer, ARRAY_SIZE(buffer->prio2buffer), | |
84 | dcb_print_array_u8); | |
85 | } | |
86 | ||
87 | static void dcb_buffer_print_buffer_size(const struct dcbnl_buffer *buffer) | |
88 | { | |
89 | size_t size = ARRAY_SIZE(buffer->buffer_size); | |
90 | SPRINT_BUF(b); | |
91 | size_t i; | |
92 | ||
93 | open_json_array(PRINT_JSON, "buffer_size"); | |
94 | print_string(PRINT_FP, NULL, "buffer-size ", NULL); | |
95 | ||
96 | for (i = 0; i < size; i++) { | |
97 | snprintf(b, sizeof(b), "%zd:%%s ", i); | |
98 | print_size(PRINT_ANY, NULL, b, buffer->buffer_size[i]); | |
99 | } | |
100 | ||
101 | close_json_array(PRINT_JSON, "buffer_size"); | |
102 | } | |
103 | ||
104 | static void dcb_buffer_print(const struct dcbnl_buffer *buffer) | |
105 | { | |
106 | dcb_buffer_print_prio_buffer(buffer); | |
107 | print_nl(); | |
108 | ||
109 | dcb_buffer_print_buffer_size(buffer); | |
110 | print_nl(); | |
111 | ||
112 | dcb_buffer_print_total_size(buffer); | |
113 | print_nl(); | |
114 | } | |
115 | ||
116 | static int dcb_buffer_get(struct dcb *dcb, const char *dev, struct dcbnl_buffer *buffer) | |
117 | { | |
118 | return dcb_get_attribute(dcb, dev, DCB_ATTR_DCB_BUFFER, buffer, sizeof(*buffer)); | |
119 | } | |
120 | ||
121 | static int dcb_buffer_set(struct dcb *dcb, const char *dev, const struct dcbnl_buffer *buffer) | |
122 | { | |
123 | return dcb_set_attribute(dcb, dev, DCB_ATTR_DCB_BUFFER, buffer, sizeof(*buffer)); | |
124 | } | |
125 | ||
126 | static int dcb_cmd_buffer_set(struct dcb *dcb, const char *dev, int argc, char **argv) | |
127 | { | |
128 | struct dcbnl_buffer buffer; | |
129 | int ret; | |
130 | ||
131 | if (!argc) { | |
132 | dcb_buffer_help_set(); | |
133 | return 0; | |
134 | } | |
135 | ||
136 | ret = dcb_buffer_get(dcb, dev, &buffer); | |
137 | if (ret) | |
138 | return ret; | |
139 | ||
140 | do { | |
141 | if (matches(*argv, "help") == 0) { | |
142 | dcb_buffer_help_set(); | |
143 | return 0; | |
144 | } else if (matches(*argv, "prio-buffer") == 0) { | |
145 | NEXT_ARG(); | |
146 | ret = parse_mapping(&argc, &argv, true, | |
147 | &dcb_buffer_parse_mapping_prio_buffer, &buffer); | |
148 | if (ret) { | |
149 | fprintf(stderr, "Invalid priority mapping %s\n", *argv); | |
150 | return ret; | |
151 | } | |
152 | continue; | |
153 | } else if (matches(*argv, "buffer-size") == 0) { | |
154 | NEXT_ARG(); | |
155 | ret = parse_mapping(&argc, &argv, true, | |
156 | &dcb_buffer_parse_mapping_buffer_size, &buffer); | |
157 | if (ret) { | |
158 | fprintf(stderr, "Invalid buffer size mapping %s\n", *argv); | |
159 | return ret; | |
160 | } | |
161 | continue; | |
162 | } else { | |
163 | fprintf(stderr, "What is \"%s\"?\n", *argv); | |
164 | dcb_buffer_help_set(); | |
165 | return -EINVAL; | |
166 | } | |
167 | ||
168 | NEXT_ARG_FWD(); | |
169 | } while (argc > 0); | |
170 | ||
171 | return dcb_buffer_set(dcb, dev, &buffer); | |
172 | } | |
173 | ||
174 | static int dcb_cmd_buffer_show(struct dcb *dcb, const char *dev, int argc, char **argv) | |
175 | { | |
176 | struct dcbnl_buffer buffer; | |
177 | int ret; | |
178 | ||
179 | ret = dcb_buffer_get(dcb, dev, &buffer); | |
180 | if (ret) | |
181 | return ret; | |
182 | ||
183 | open_json_object(NULL); | |
184 | ||
185 | if (!argc) { | |
186 | dcb_buffer_print(&buffer); | |
187 | goto out; | |
188 | } | |
189 | ||
190 | do { | |
191 | if (matches(*argv, "help") == 0) { | |
192 | dcb_buffer_help_show(); | |
193 | return 0; | |
194 | } else if (matches(*argv, "prio-buffer") == 0) { | |
195 | dcb_buffer_print_prio_buffer(&buffer); | |
196 | print_nl(); | |
197 | } else if (matches(*argv, "buffer-size") == 0) { | |
198 | dcb_buffer_print_buffer_size(&buffer); | |
199 | print_nl(); | |
200 | } else if (matches(*argv, "total-size") == 0) { | |
201 | dcb_buffer_print_total_size(&buffer); | |
202 | print_nl(); | |
203 | } else { | |
204 | fprintf(stderr, "What is \"%s\"?\n", *argv); | |
205 | dcb_buffer_help_show(); | |
206 | return -EINVAL; | |
207 | } | |
208 | ||
209 | NEXT_ARG_FWD(); | |
210 | } while (argc > 0); | |
211 | ||
212 | out: | |
213 | close_json_object(); | |
214 | return 0; | |
215 | } | |
216 | ||
217 | int dcb_cmd_buffer(struct dcb *dcb, int argc, char **argv) | |
218 | { | |
219 | if (!argc || matches(*argv, "help") == 0) { | |
220 | dcb_buffer_help(); | |
221 | return 0; | |
222 | } else if (matches(*argv, "show") == 0) { | |
223 | NEXT_ARG_FWD(); | |
224 | return dcb_cmd_parse_dev(dcb, argc, argv, | |
225 | dcb_cmd_buffer_show, dcb_buffer_help_show); | |
226 | } else if (matches(*argv, "set") == 0) { | |
227 | NEXT_ARG_FWD(); | |
228 | return dcb_cmd_parse_dev(dcb, argc, argv, | |
229 | dcb_cmd_buffer_set, dcb_buffer_help_set); | |
230 | } else { | |
231 | fprintf(stderr, "What is \"%s\"?\n", *argv); | |
232 | dcb_buffer_help(); | |
233 | return -EINVAL; | |
234 | } | |
235 | } |