blob: a48c70155997998dc162f307c866752aba0956fe [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}
21cmd_gssetinfo = { { ETHTOOL_GSSET_INFO, 0, 1ULL << ETH_SS_FEATURES }, 34 };
22
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 Hutchings60428042012-06-01 23:08:32 +010083static const struct cmd_expect cmd_expect_set_features_off_old[] = {
84 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +010085 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
86 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
87 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
88 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
89 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
90 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
91 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
92 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +000093 { &cmd_srxcsum_off, sizeof(cmd_srxcsum_off), 0, 0, 0 },
94 { &cmd_stxcsum_off, sizeof(cmd_stxcsum_off), 0, 0, 0 },
95 { &cmd_ssg_off, sizeof(cmd_ssg_off), 0, 0, 0 },
96 { &cmd_stso_off, sizeof(cmd_stso_off), 0, 0, 0 },
97 { &cmd_sufo_off, sizeof(cmd_sufo_off), 0, 0, 0 },
98 { &cmd_sgso_off, sizeof(cmd_sgso_off), 0, 0, 0 },
Ben Hutchingse5c984a2011-05-13 23:25:26 +010099 { &cmd_sgro_off, sizeof(cmd_sgro_off), 0, 0, 0 },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000100 { &cmd_sflags_off, sizeof(cmd_sflags_off), 0, 0, 0 },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100101 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
102 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
103 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
104 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
105 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
106 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
107 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
108 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_sflags_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000109 { 0, 0, 0, 0, 0 }
110};
111
Ben Hutchings60428042012-06-01 23:08:32 +0100112static const struct cmd_expect cmd_expect_set_features_on_old[] = {
113 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100114 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
115 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
116 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
117 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
118 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
119 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
120 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
121 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000122 { &cmd_srxcsum_on, sizeof(cmd_srxcsum_on), 0, 0, 0 },
123 { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), 0, 0, 0 },
124 { &cmd_ssg_on, sizeof(cmd_ssg_on), 0, 0, 0 },
125 { &cmd_stso_on, sizeof(cmd_stso_on), 0, 0, 0 },
126 { &cmd_sufo_on, sizeof(cmd_sufo_on), 0, 0, 0 },
127 { &cmd_sgso_on, sizeof(cmd_sgso_on), 0, 0, 0 },
Ben Hutchingse5c984a2011-05-13 23:25:26 +0100128 { &cmd_sgro_on, sizeof(cmd_sgro_on), 0, 0, 0 },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000129 { &cmd_sflags_on, sizeof(cmd_sflags_on), 0, 0, 0 },
Ben Hutchings5bebf1e2011-10-27 14:17:59 +0100130 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
131 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
132 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
133 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
134 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
135 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
136 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
137 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000138 { 0, 0, 0, 0, 0 }
139};
140
Ben Hutchings60428042012-06-01 23:08:32 +0100141static const struct cmd_expect cmd_expect_set_features_unsup_on_old[] = {
142 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd), -EINVAL },
143 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
144 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
145 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
146 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
147 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
148 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
149 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
150 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
151 { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), -EOPNOTSUPP },
152 { 0, 0, 0, 0, 0 }
153};
154
155static const struct {
156 struct ethtool_gstrings cmd;
157 u8 data[34][ETH_GSTRING_LEN];
158}
159cmd_gstrings = {
160 { ETHTOOL_GSTRINGS, ETH_SS_FEATURES, 34 },
161 {
162 "tx-scatter-gather",
163 "tx-checksum-ipv4",
164 "",
165 "tx-checksum-ip-generic",
166 "tx-checksum-ipv6",
167 "highdma",
168 "tx-scatter-gather-fraglist",
169 "tx-vlan-hw-insert",
170 "rx-vlan-hw-parse",
171 "rx-vlan-filter",
172 "vlan-challenged",
173 "tx-generic-segmentation",
174 "tx-lockless",
175 "netns-local",
176 "rx-gro",
177 "rx-lro",
178 "tx-tcp-segmentation",
179 "tx-udp-fragmentation",
180 "tx-gso-robust",
181 "tx-tcp-ecn-segmentation",
182 "tx-tcp6-segmentation",
183 "tx-fcoe-segmentation",
184 "",
185 "",
186 "tx-checksum-fcoe-crc",
187 "tx-checksum-sctp",
188 "fcoe-mtu",
189 "rx-ntuple-filter",
190 "rx-hashing",
191 "rx-checksum",
192 "tx-nocache-copy",
193 "loopback",
194 "rx-fcs",
195 "rx-all",
196 }
197};
198
199static const struct {
200 struct ethtool_gfeatures cmd;
201 struct ethtool_get_features_block data[2];
202}
203 /* available requested active never_changed */
204/* minimal: only GRO and GSO are available (and GSO won't work) */
205cmd_gfeatures_min_off = { { ETHTOOL_GFEATURES, 2 },
206 {{ 0x00004800, 0x00000000, 0x00000000, 0x00003400},
207 { 0x00000000, 0x00000000, 0x00000000, 0x00000000}}
208},
209cmd_gfeatures_min_on = { { ETHTOOL_GFEATURES, 2 },
210 {{ 0x00004800, 0x00004800, 0x00004000, 0x00003400},
211 { 0x00000000, 0x00000000, 0x00000000, 0x00000000}}
212},
213/* maximal: everything that isn't never-changed is available */
214cmd_gfeatures_max_off = { { ETHTOOL_GFEATURES, 2 },
215 {{ 0xffffcbff, 0x00000000, 0x00000000, 0x00003400 },
216 { 0x00000003, 0x00000000, 0x00000000, 0x00000000 }}
217},
218cmd_gfeatures_max_on = { { ETHTOOL_GFEATURES, 2 },
219 {{ 0xffffcbff, 0xffffcbff, 0xffffcbff, 0x00003400 },
220 { 0x00000003, 0x00000003, 0x00000003, 0x00000000 }}
221},
222/* IPv4: GRO, GSO, SG and some IPv4-specific offloads are available */
223cmd_gfeatures_ipv4_off = { { ETHTOOL_GFEATURES, 2 },
224 {{ 0x00014803, 0x00000000, 0x00000000, 0x00003400 },
225 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }}
226},
227cmd_gfeatures_ipv4_on = { { ETHTOOL_GFEATURES, 2 },
228 {{ 0x00014803, 0x00014803, 0x00014803, 0x00003400 },
229 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }}
230};
231
232static const struct {
233 struct ethtool_sfeatures cmd;
234 struct ethtool_set_features_block data[2];
235}
236 /* valid requested */
237cmd_sfeatures_min_on = { { ETHTOOL_SFEATURES, 2 },
238 {{ 0x00004800, 0x00004800 },
239 { 0x00000000, 0x00000000 }} },
240cmd_sfeatures_min_off = { { ETHTOOL_SFEATURES, 2 },
241 {{ 0x00004800, 0x00000000 },
242 { 0x00000000, 0x00000000 }} },
243cmd_sfeatures_noop = { { ETHTOOL_SFEATURES, 2 },
244 {{ 0x00000000, 0x00000000 },
245 { 0x00000000, 0x00000000 }} },
246cmd_sfeatures_ipv4_on = { { ETHTOOL_SFEATURES, 2 },
247 {{ 0x00014803, 0x00014803 },
248 { 0x00000000, 0x00000000 }} };
249
250static const struct cmd_expect cmd_expect_get_strings[] = {
251 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
252 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
253 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
254 0, &cmd_gstrings, sizeof(cmd_gstrings) },
255 { 0, 0, 0, 0, 0 }
256};
257
258static const struct cmd_expect cmd_expect_get_features_min_off[] = {
259 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
260 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
261 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
262 0, &cmd_gstrings, sizeof(cmd_gstrings) },
263 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
264 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
265 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
266 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
267 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
268 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
269 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
270 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
271 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
272 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
273 { 0, 0, 0, 0, 0 }
274};
275
276static const struct cmd_expect cmd_expect_get_features_max_on[] = {
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 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
282 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
283 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
284 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
285 { &cmd_gufo_on, 4, 0, &cmd_gufo_on, sizeof(cmd_gufo_on) },
286 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
287 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
288 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
289 { &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on.cmd),
290 0, &cmd_gfeatures_max_on, sizeof(cmd_gfeatures_max_on) },
291 { 0, 0, 0, 0, 0 }
292};
293
294static const struct cmd_expect cmd_expect_set_features_min_off_min_on[] = {
295 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
296 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
297 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
298 0, &cmd_gstrings, sizeof(cmd_gstrings) },
299 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
300 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
301 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
302 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
303 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
304 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
305 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
306 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
307 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
308 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
309 { &cmd_sfeatures_min_on, sizeof(cmd_sfeatures_min_on),
310 ETHTOOL_F_WISH, 0, 0 },
311 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
312 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
313 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
314 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
315 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
316 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
317 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
318 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
319 { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd),
320 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) },
321 { 0, 0, 0, 0, 0 }
322};
323
324static const struct cmd_expect cmd_expect_set_features_min_off_min_off[] = {
325 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
326 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
327 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
328 0, &cmd_gstrings, sizeof(cmd_gstrings) },
329 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
330 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
331 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
332 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
333 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
334 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
335 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
336 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
337 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
338 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
339 { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 },
340 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
341 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
342 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
343 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
344 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
345 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
346 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
347 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
348 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
349 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
350 { 0, 0, 0, 0, 0 }
351};
352
353static const struct cmd_expect cmd_expect_set_features_min_on_min_off[] = {
354 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
355 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
356 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
357 0, &cmd_gstrings, sizeof(cmd_gstrings) },
358 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
359 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
360 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
361 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
362 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
363 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
364 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
365 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
366 { &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on.cmd),
367 0, &cmd_gfeatures_min_on, sizeof(cmd_gfeatures_min_on) },
368 { &cmd_sfeatures_min_off, sizeof(cmd_sfeatures_min_off), 0, 0, 0 },
369 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
370 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
371 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
372 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
373 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
374 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
375 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
376 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
377 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
378 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
379 { 0, 0, 0, 0, 0 }
380};
381
382static const struct cmd_expect cmd_expect_set_features_min_off_unsup_on[] = {
383 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
384 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
385 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
386 0, &cmd_gstrings, sizeof(cmd_gstrings) },
387 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
388 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
389 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
390 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
391 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
392 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
393 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
394 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
395 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
396 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
397 { &cmd_sfeatures_noop, sizeof(cmd_sfeatures_noop), 0, 0, 0 },
398 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
399 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
400 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
401 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
402 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
403 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
404 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
405 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
406 { &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off.cmd),
407 0, &cmd_gfeatures_min_off, sizeof(cmd_gfeatures_min_off) },
408 { 0, 0, 0, 0, 0 }
409};
410
411static const struct cmd_expect cmd_expect_set_features_ipv4_off_many_on[] = {
412 { &cmd_gssetinfo, sizeof(cmd_gssetinfo.cmd),
413 0, &cmd_gssetinfo, sizeof(cmd_gssetinfo) },
414 { &cmd_gstrings, sizeof(cmd_gstrings.cmd),
415 0, &cmd_gstrings, sizeof(cmd_gstrings) },
416 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
417 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
418 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
419 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
420 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
421 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
422 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
423 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
424 { &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off.cmd),
425 0, &cmd_gfeatures_ipv4_off, sizeof(cmd_gfeatures_ipv4_off) },
426 { &cmd_sfeatures_ipv4_on, sizeof(cmd_sfeatures_ipv4_on), 0, 0, 0 },
427 { &cmd_grxcsum_on, 4, 0, &cmd_grxcsum_on, sizeof(cmd_grxcsum_on) },
428 { &cmd_gtxcsum_on, 4, 0, &cmd_gtxcsum_on, sizeof(cmd_gtxcsum_on) },
429 { &cmd_gsg_on, 4, 0, &cmd_gsg_on, sizeof(cmd_gsg_on) },
430 { &cmd_gtso_on, 4, 0, &cmd_gtso_on, sizeof(cmd_gtso_on) },
431 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
432 { &cmd_ggso_on, 4, 0, &cmd_ggso_on, sizeof(cmd_ggso_on) },
433 { &cmd_ggro_on, 4,0, &cmd_ggro_on, sizeof(cmd_ggro_on) },
434 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
435 { &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on.cmd),
436 0, &cmd_gfeatures_ipv4_on, sizeof(cmd_gfeatures_ipv4_on) },
437 { 0, 0, 0, 0, 0 }
438};
439
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000440static struct test_case {
441 int rc;
442 const char *args;
443 const struct cmd_expect *expect;
444} const test_cases[] = {
Ben Hutchings60428042012-06-01 23:08:32 +0100445 { 0, "-k devname", cmd_expect_get_features_off_old },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000446 { 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 +0100447 cmd_expect_set_features_off_old },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000448 { 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 +0100449 cmd_expect_set_features_on_old },
450 { 1, "-K devname tx on sg on", cmd_expect_set_features_unsup_on_old },
451 { 0, "--show-offload devname", cmd_expect_get_features_min_off },
452 { 0, "--show-features devname", cmd_expect_get_features_max_on },
453 { 0, "-K devname rx on tx on sg on tso on ufo on gso on gro on",
454 cmd_expect_set_features_min_off_min_on },
455 { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off",
456 cmd_expect_set_features_min_off_min_off },
457 { 0, "-K devname rx off tx off sg off tso off ufo off gso off gro off",
458 cmd_expect_set_features_min_on_min_off },
459 { 1, "-K devname tx on sg on",
460 cmd_expect_set_features_min_off_unsup_on },
461 { 0, "--features devname rx on tx on sg on tso on gso on gro on",
462 cmd_expect_set_features_ipv4_off_many_on },
463 { 1, "-K devname rx foo", cmd_expect_get_strings_old },
464 { 1, "-K devname rx foo", cmd_expect_get_strings },
465 { 1, "--offload devname rx", cmd_expect_get_strings_old },
466 { 1, "--features devname rx", cmd_expect_get_strings },
467 { 1, "--features devname foo on", cmd_expect_get_strings_old },
468 { 1, "--offload devname foo on", cmd_expect_get_strings },
Ben Hutchingsf2686c12012-02-17 22:17:41 +0000469};
470
471static int expect_matched;
472static const struct cmd_expect *expect_next;
473
474int send_ioctl(struct cmd_context *ctx, void *cmd)
475{
476 int rc = test_ioctl(expect_next, cmd);
477
478 if (rc == TEST_IOCTL_MISMATCH) {
479 expect_matched = 0;
480 test_exit(0);
481 }
482 expect_next++;
483 return rc;
484}
485
486int main(void)
487{
488 const struct test_case *tc;
489 int test_rc;
490 int rc = 0;
491
492 for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) {
493 if (getenv("ETHTOOL_TEST_VERBOSE"))
494 printf("I: Test command line: ethtool %s\n", tc->args);
495 expect_matched = 1;
496 expect_next = tc->expect;
497 test_rc = test_cmdline(tc->args);
498
499 /* If we found a mismatch, or there is still another
500 * expected ioctl to match, the test failed.
501 */
502 if (!expect_matched || expect_next->cmd) {
503 fprintf(stderr,
504 "E: ethtool %s deviated from the expected "
505 "ioctl sequence after %zu calls\n",
506 tc->args, expect_next - tc->expect);
507 rc = 1;
508 } else if (test_rc != tc->rc) {
509 fprintf(stderr, "E: ethtool %s returns %d\n",
510 tc->args, test_rc);
511 rc = 1;
512 }
513 }
514
515 return rc;
516}