blob: 6ebb364803a2be681fc605a4ed41d0b32776475d [file] [log] [blame]
Ben Hutchingsf2686c12012-02-17 22:17:41 +00001/****************************************************************************
2 * Test cases for ethtool features
3 * Copyright 2012 Solarflare Communications Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation, incorporated herein by reference.
8 */
9
Ben Hutchings60428042012-06-01 23:08:32 +010010#include <errno.h>
Ben Hutchingsf2686c12012-02-17 22:17:41 +000011#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#define TEST_NO_WRAPPERS
15#include "internal.h"
16
Ben Hutchings60428042012-06-01 23:08:32 +010017static const struct {
18 struct ethtool_sset_info cmd;
19 u32 data[1];
20}
Maciej Żenczykowski42517712016-03-11 09:58:20 -080021cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, { 34 } };
Ben Hutchings60428042012-06-01 23:08:32 +010022
Ben Hutchingsf2686c12012-02-17 22:17:41 +000023static const struct ethtool_value
24cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
25cmd_grxcsum_on = { ETHTOOL_GRXCSUM, 1 },
26cmd_srxcsum_off = { ETHTOOL_SRXCSUM, 0 },
27cmd_srxcsum_on = { ETHTOOL_SRXCSUM, 1 },
28cmd_gtxcsum_off = { ETHTOOL_GTXCSUM, 0 },
29cmd_gtxcsum_on = { ETHTOOL_GTXCSUM, 1 },
30cmd_stxcsum_off = { ETHTOOL_STXCSUM, 0 },
31cmd_stxcsum_on = { ETHTOOL_STXCSUM, 1 },
32cmd_gsg_off = { ETHTOOL_GSG, 0 },
33cmd_gsg_on = { ETHTOOL_GSG, 1 },
34cmd_ssg_off = { ETHTOOL_SSG, 0 },
35cmd_ssg_on = { ETHTOOL_SSG, 1 },
36cmd_gtso_off = { ETHTOOL_GTSO, 0 },
37cmd_gtso_on = { ETHTOOL_GTSO, 1 },
38cmd_stso_off = { ETHTOOL_STSO, 0 },
39cmd_stso_on = { ETHTOOL_STSO, 1 },
40cmd_gufo_off = { ETHTOOL_GUFO, 0 },
41cmd_gufo_on = { ETHTOOL_GUFO, 1 },
42cmd_sufo_off = { ETHTOOL_SUFO, 0 },
43cmd_sufo_on = { ETHTOOL_SUFO, 1 },
44cmd_ggso_off = { ETHTOOL_GGSO, 0 },
45cmd_ggso_on = { ETHTOOL_GGSO, 1 },
46cmd_sgso_off = { ETHTOOL_SGSO, 0 },
47cmd_sgso_on = { ETHTOOL_SGSO, 1 },
48cmd_ggro_off = { ETHTOOL_GGRO, 0 },
49cmd_ggro_on = { ETHTOOL_GGRO, 1 },
50cmd_sgro_off = { ETHTOOL_SGRO, 0 },
51cmd_sgro_on = { ETHTOOL_SGRO, 1 },
52cmd_gflags_off = { ETHTOOL_GFLAGS, 0 },
53cmd_gflags_on = { ETHTOOL_GFLAGS,
54 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
55 ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH },
56cmd_sflags_off = { ETHTOOL_SFLAGS, 0 },
57cmd_sflags_ntuple = { ETHTOOL_GFLAGS, ETH_FLAG_NTUPLE },
58cmd_sflags_on = { ETHTOOL_SFLAGS,
59 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
60 ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH },
61cmd_sflags_not_rxhash = { ETHTOOL_SFLAGS,
62 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
63 ETH_FLAG_NTUPLE };
64
Ben Hutchings60428042012-06-01 23:08:32 +010065static const struct cmd_expect cmd_expect_get_strings_old[] = {
66 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
67 { 0, 0, 0, 0, 0 }
68};
69
70static const struct cmd_expect cmd_expect_get_features_off_old[] = {
71 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
Ben Hutchingsf2686c12012-02-17 22:17:41 +000072 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
73 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
74 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
75 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
76 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
77 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +000078 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
Ben Hutchingse5c984a2011-05-13 23:25:26 +010079 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +000080 { 0, 0, 0, 0, 0 }
81};
82
Ben Hutchings1eef6772012-06-13 00:57:06 +010083static const struct cmd_expect cmd_expect_get_features_off_old_some_unsup[] = {
84 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
85 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
86 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
87 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
88 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
89 { &cmd_gufo_off, 4, -EOPNOTSUPP },
90 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
91 { &cmd_ggro_off, 4, -EOPNOTSUPP },
92 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
93 { 0, 0, 0, 0, 0 }
94};
95
96static const struct cmd_expect cmd_expect_get_features_off_old_some_priv[] = {
97 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EPERM },
98 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
99 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
100 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
101 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
102 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
103 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
104 { &cmd_ggro_off, 4, -EPERM },
105 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
106 { 0, 0, 0, 0, 0 }
107};
108
Ben Hutchings60428042012-06-01 23:08:32 +0100109static const struct cmd_expect cmd_expect_set_features_off_old[] = {
110 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100111 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
112 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
113 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
114 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
115 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
116 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
117 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
118 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000119 { &cmd_srxcsum_off, sizeof(cmd_srxcsum_off), 0, 0, 0 },
120 { &cmd_stxcsum_off, sizeof(cmd_stxcsum_off), 0, 0, 0 },
121 { &cmd_ssg_off, sizeof(cmd_ssg_off), 0, 0, 0 },
122 { &cmd_stso_off, sizeof(cmd_stso_off), 0, 0, 0 },
123 { &cmd_sufo_off, sizeof(cmd_sufo_off), 0, 0, 0 },
124 { &cmd_sgso_off, sizeof(cmd_sgso_off), 0, 0, 0 },
Ben Hutchingse5c984a2011-05-13 23:25:26 +0100125 { &cmd_sgro_off, sizeof(cmd_sgro_off), 0, 0, 0 },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000126 { &cmd_sflags_off, sizeof(cmd_sflags_off), 0, 0, 0 },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100127 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
128 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
129 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
130 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
131 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
132 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
133 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
134 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_sflags_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000135 { 0, 0, 0, 0, 0 }
136};
137
Ben Hutchings60428042012-06-01 23:08:32 +0100138static const struct cmd_expect cmd_expect_set_features_on_old[] = {
139 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100140 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
141 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
142 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
143 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
144 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
145 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
146 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
147 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000148 { &cmd_srxcsum_on, sizeof(cmd_srxcsum_on), 0, 0, 0 },
149 { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), 0, 0, 0 },
150 { &cmd_ssg_on, sizeof(cmd_ssg_on), 0, 0, 0 },
151 { &cmd_stso_on, sizeof(cmd_stso_on), 0, 0, 0 },
152 { &cmd_sufo_on, sizeof(cmd_sufo_on), 0, 0, 0 },
153 { &cmd_sgso_on, sizeof(cmd_sgso_on), 0, 0, 0 },
Ben Hutchingse5c984a2011-05-13 23:25:26 +0100154 { &cmd_sgro_on, sizeof(cmd_sgro_on), 0, 0, 0 },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000155 { &cmd_sflags_on, sizeof(cmd_sflags_on), 0, 0, 0 },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100156 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
157 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
158 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
159 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
160 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
161 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
162 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
163 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000164 { 0, 0, 0, 0, 0 }
165};
166
Ben Hutchings60428042012-06-01 23:08:32 +0100167static const struct cmd_expect cmd_expect_set_features_unsup_on_old[] = {
168 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
169 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
170 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
171 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
172 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
173 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
174 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
175 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
176 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
177 { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), -EOPNOTSUPP },
178 { 0, 0, 0, 0, 0 }
179};
180
181static const struct {
182 struct ethtool_gstrings cmd;
183 u8 data[34][ETH_GSTRING_LEN];
184}
185cmd_gstrings = {
186 { ETHTOOL_GSTRINGS, ETH_SS_FEATURES, 34 },
187 {
188 "tx-scatter-gather",
189 "tx-checksum-ipv4",
190 "",
191 "tx-checksum-ip-generic",
192 "tx-checksum-ipv6",
193 "highdma",
194 "tx-scatter-gather-fraglist",
195 "tx-vlan-hw-insert",
196 "rx-vlan-hw-parse",
197 "rx-vlan-filter",
198 "vlan-challenged",
199 "tx-generic-segmentation",
200 "tx-lockless",
201 "netns-local",
202 "rx-gro",
203 "rx-lro",
204 "tx-tcp-segmentation",
205 "tx-udp-fragmentation",
206 "tx-gso-robust",
207 "tx-tcp-ecn-segmentation",
208 "tx-tcp6-segmentation",
209 "tx-fcoe-segmentation",
210 "",
211 "",
212 "tx-checksum-fcoe-crc",
213 "tx-checksum-sctp",
214 "fcoe-mtu",
215 "rx-ntuple-filter",
216 "rx-hashing",
217 "rx-checksum",
218 "tx-nocache-copy",
219 "loopback",
220 "rx-fcs",
221 "rx-all",
222 }
223};
224
225static const struct {
226 struct ethtool_gfeatures cmd;
227 struct ethtool_get_features_block data[2];
228}
229 /* available requested active never_changed */
230/* minimal: only GRO and GSO are available (and GSO won't work) */
231cmd_gfeatures_min_off = { { ETHTOOL_GFEATURES, 2 },
232 {{ 0x00004800, 0x00000000, 0x00000000, 0x00003400},
233 { 0x00000000, 0x00000000, 0x00000000, 0x00000000}}
234},
235cmd_gfeatures_min_on = { { ETHTOOL_GFEATURES, 2 },
236 {{ 0x00004800, 0x00004800, 0x00004000, 0x00003400},
237 { 0x00000000, 0x00000000, 0x00000000, 0x00000000}}
238},
239/* maximal: everything that isn't never-changed is available */
240cmd_gfeatures_max_off = { { ETHTOOL_GFEATURES, 2 },
241 {{ 0xffffcbff, 0x00000000, 0x00000000, 0x00003400 },
242 { 0x00000003, 0x00000000, 0x00000000, 0x00000000 }}
243},
244cmd_gfeatures_max_on = { { ETHTOOL_GFEATURES, 2 },
245 {{ 0xffffcbff, 0xffffcbff, 0xffffcbff, 0x00003400 },
246 { 0x00000003, 0x00000003, 0x00000003, 0x00000000 }}
247},
248/* IPv4: GRO, GSO, SG and some IPv4-specific offloads are available */
249cmd_gfeatures_ipv4_off = { { ETHTOOL_GFEATURES, 2 },
250 {{ 0x00014803, 0x00000000, 0x00000000, 0x00003400 },
251 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }}
252},
253cmd_gfeatures_ipv4_on = { { ETHTOOL_GFEATURES, 2 },
254 {{ 0x00014803, 0x00014803, 0x00014803, 0x00003400 },
255 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }}
256};
257
258static const struct {
259 struct ethtool_sfeatures cmd;
260 struct ethtool_set_features_block data[2];
261}
262 /* valid requested */
263cmd_sfeatures_min_on = { { ETHTOOL_SFEATURES, 2 },
264 {{ 0x00004800, 0x00004800 },
265 { 0x00000000, 0x00000000 }} },
266cmd_sfeatures_min_off = { { ETHTOOL_SFEATURES, 2 },
267 {{ 0x00004800, 0x00000000 },
268 { 0x00000000, 0x00000000 }} },
269cmd_sfeatures_noop = { { ETHTOOL_SFEATURES, 2 },
270 {{ 0x00000000, 0x00000000 },
271 { 0x00000000, 0x00000000 }} },
272cmd_sfeatures_ipv4_on = { { ETHTOOL_SFEATURES, 2 },
273 {{ 0x00014803, 0x00014803 },
274 { 0x00000000, 0x00000000 }} };
275
276static const struct cmd_expect cmd_expect_get_strings[] = {
277 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
278 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
279 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
280 0, &cmd_gstrings, sizeof(cmd_gstrings) },
281 { 0, 0, 0, 0, 0 }
282};
283
284static const struct cmd_expect cmd_expect_get_features_min_off[] = {
285 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
286 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
287 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
288 0, &cmd_gstrings, sizeof(cmd_gstrings) },
289 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
290 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
291 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
292 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
293 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
294 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
295 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
296 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
297 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
298 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
299 { 0, 0, 0, 0, 0 }
300};
301
302static const struct cmd_expect cmd_expect_get_features_max_on[] = {
303 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
304 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
305 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
306 0, &cmd_gstrings, sizeof(cmd_gstrings) },
307 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
308 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
309 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
310 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
311 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
312 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
313 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
314 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
315 { &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on.cmd),
316 0, &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on) },
317 { 0, 0, 0, 0, 0 }
318};
319
320static const struct cmd_expect cmd_expect_set_features_min_off_min_on[] = {
321 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
322 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
323 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
324 0, &cmd_gstrings, sizeof(cmd_gstrings) },
325 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
326 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
327 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
328 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
329 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
330 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
331 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
332 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
333 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
334 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
335 { &cmd_sfeatures_min_on, sizeof(cmd_sfeatures_min_on),
336 ETHTOOL_F_WISH, 0, 0 },
337 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
338 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
339 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
340 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
341 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
342 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
343 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
344 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
345 { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd),
346 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) },
347 { 0, 0, 0, 0, 0 }
348};
349
350static const struct cmd_expect cmd_expect_set_features_min_off_min_off[] = {
351 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
352 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
353 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
354 0, &cmd_gstrings, sizeof(cmd_gstrings) },
355 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
356 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
357 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
358 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
359 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
360 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
361 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
362 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
363 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
364 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
365 { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 },
366 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
367 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
368 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
369 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
370 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
371 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
372 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
373 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
374 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
375 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
376 { 0, 0, 0, 0, 0 }
377};
378
379static const struct cmd_expect cmd_expect_set_features_min_on_min_off[] = {
380 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
381 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
382 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
383 0, &cmd_gstrings, sizeof(cmd_gstrings) },
384 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
385 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
386 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
387 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
388 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
389 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
390 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
391 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
392 { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd),
393 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) },
394 { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 },
395 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
396 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
397 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
398 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
399 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
400 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
401 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
402 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
403 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
404 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
405 { 0, 0, 0, 0, 0 }
406};
407
408static const struct cmd_expect cmd_expect_set_features_min_off_unsup_on[] = {
409 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
410 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
411 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
412 0, &cmd_gstrings, sizeof(cmd_gstrings) },
413 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
414 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
415 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
416 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
417 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
418 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
419 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
420 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
421 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
422 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
423 { &cmd_sfeatures_noop, sizeof(cmd_sfeatures_noop), 0, 0, 0 },
424 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
425 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
426 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
427 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
428 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
429 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
430 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
431 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
432 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
433 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
434 { 0, 0, 0, 0, 0 }
435};
436
437static const struct cmd_expect cmd_expect_set_features_ipv4_off_many_on[] = {
438 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
439 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
440 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
441 0, &cmd_gstrings, sizeof(cmd_gstrings) },
442 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
443 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
444 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
445 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
446 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
447 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
448 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
449 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
450 { &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off.cmd),
451 0, &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off) },
452 { &cmd_sfeatures_ipv4_on, sizeof(cmd_sfeatures_ipv4_on), 0, 0, 0 },
453 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
454 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
455 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
456 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
457 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
458 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
459 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
460 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
461 { &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on.cmd),
462 0, &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on) },
463 { 0, 0, 0, 0, 0 }
464};
465
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000466static struct test_case {
467 int rc;
468 const char *args;
469 const struct cmd_expect *expect;
470} const test_cases[] = {
Ben Hutchings60428042012-06-01 23:08:32 +0100471 { 0, "-k devname", cmd_expect_get_features_off_old },
Ben Hutchings1eef6772012-06-13 00:57:06 +0100472 { 0, "-k dev_unsup", cmd_expect_get_features_off_old_some_unsup },
473 { 0, "-k dev_priv", cmd_expect_get_features_off_old_some_priv },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000474 { 0, "-K devname rx off tx off sg off tso off ufo off gso off lro off rxvlan off txvlan off ntuple off rxhash off gro off",
Ben Hutchings60428042012-06-01 23:08:32 +0100475 cmd_expect_set_features_off_old },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000476 { 0, "-K devname rx on tx on sg on tso on ufo on gso on lro on rxvlan on txvlan on ntuple on rxhash on gro on",
Ben Hutchings60428042012-06-01 23:08:32 +0100477 cmd_expect_set_features_on_old },
478 { 1, "-K devname tx on sg on", cmd_expect_set_features_unsup_on_old },
479 { 0, "--show-offload devname", cmd_expect_get_features_min_off },
480 { 0, "--show-features devname", cmd_expect_get_features_max_on },
481 { 0, "-K devname rx on tx on sg on tso on ufo on gso on gro on",
482 cmd_expect_set_features_min_off_min_on },
483 { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off",
484 cmd_expect_set_features_min_off_min_off },
485 { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off",
486 cmd_expect_set_features_min_on_min_off },
487 { 1, "-K devname tx on sg on",
488 cmd_expect_set_features_min_off_unsup_on },
489 { 0, "--features devname rx on tx on sg on tso on gso on gro on",
490 cmd_expect_set_features_ipv4_off_many_on },
491 { 1, "-K devname rx foo", cmd_expect_get_strings_old },
492 { 1, "-K devname rx foo", cmd_expect_get_strings },
493 { 1, "--offload devname rx", cmd_expect_get_strings_old },
494 { 1, "--features devname rx", cmd_expect_get_strings },
495 { 1, "--features devname foo on", cmd_expect_get_strings_old },
496 { 1, "--offload devname foo on", cmd_expect_get_strings },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000497};
498
499static int expect_matched;
500static const struct cmd_expect *expect_next;
501
502int send_ioctl(struct cmd_context *ctx, void *cmd)
503{
504 int rc = test_ioctl(expect_next, cmd);
505
506 if (rc == TEST_IOCTL_MISMATCH) {
507 expect_matched = 0;
508 test_exit(0);
509 }
510 expect_next++;
511 return rc;
512}
513
514int main(void)
515{
516 const struct test_case *tc;
517 int test_rc;
518 int rc = 0;
519
520 for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) {
521 if (getenv("ETHTOOL_TEST_VERBOSE"))
522 printf("I: Test command line: ethtool %s\n", tc->args);
523 expect_matched = 1;
524 expect_next = tc->expect;
525 test_rc = test_cmdline(tc->args);
526
527 /* If we found a mismatch, or there is still another
528 * expected ioctl to match, the test failed.
529 */
530 if (!expect_matched || expect_next->cmd) {
531 fprintf(stderr,
532 "E: ethtool %s deviated from the expected "
533 "ioctl sequence after %zu calls\n",
534 tc->args, expect_next - tc->expect);
535 rc = 1;
536 } else if (test_rc != tc->rc) {
537 fprintf(stderr, "E: ethtool %s returns %d\n",
538 tc->args, test_rc);
539 rc = 1;
540 }
541 }
542
543 return rc;
544}