blob: 4d8680ac0e7fe4158c03c868c1468973e5d8120f [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
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#define TEST_NO_WRAPPERS
14#include "internal.h"
15
16static const struct ethtool_value
17cmd_grxcsum_off = { ETHTOOL_GRXCSUM, 0 },
18cmd_grxcsum_on = { ETHTOOL_GRXCSUM, 1 },
19cmd_srxcsum_off = { ETHTOOL_SRXCSUM, 0 },
20cmd_srxcsum_on = { ETHTOOL_SRXCSUM, 1 },
21cmd_gtxcsum_off = { ETHTOOL_GTXCSUM, 0 },
22cmd_gtxcsum_on = { ETHTOOL_GTXCSUM, 1 },
23cmd_stxcsum_off = { ETHTOOL_STXCSUM, 0 },
24cmd_stxcsum_on = { ETHTOOL_STXCSUM, 1 },
25cmd_gsg_off = { ETHTOOL_GSG, 0 },
26cmd_gsg_on = { ETHTOOL_GSG, 1 },
27cmd_ssg_off = { ETHTOOL_SSG, 0 },
28cmd_ssg_on = { ETHTOOL_SSG, 1 },
29cmd_gtso_off = { ETHTOOL_GTSO, 0 },
30cmd_gtso_on = { ETHTOOL_GTSO, 1 },
31cmd_stso_off = { ETHTOOL_STSO, 0 },
32cmd_stso_on = { ETHTOOL_STSO, 1 },
33cmd_gufo_off = { ETHTOOL_GUFO, 0 },
34cmd_gufo_on = { ETHTOOL_GUFO, 1 },
35cmd_sufo_off = { ETHTOOL_SUFO, 0 },
36cmd_sufo_on = { ETHTOOL_SUFO, 1 },
37cmd_ggso_off = { ETHTOOL_GGSO, 0 },
38cmd_ggso_on = { ETHTOOL_GGSO, 1 },
39cmd_sgso_off = { ETHTOOL_SGSO, 0 },
40cmd_sgso_on = { ETHTOOL_SGSO, 1 },
41cmd_ggro_off = { ETHTOOL_GGRO, 0 },
42cmd_ggro_on = { ETHTOOL_GGRO, 1 },
43cmd_sgro_off = { ETHTOOL_SGRO, 0 },
44cmd_sgro_on = { ETHTOOL_SGRO, 1 },
45cmd_gflags_off = { ETHTOOL_GFLAGS, 0 },
46cmd_gflags_on = { ETHTOOL_GFLAGS,
47 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
48 ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH },
49cmd_sflags_off = { ETHTOOL_SFLAGS, 0 },
50cmd_sflags_ntuple = { ETHTOOL_GFLAGS, ETH_FLAG_NTUPLE },
51cmd_sflags_on = { ETHTOOL_SFLAGS,
52 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
53 ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH },
54cmd_sflags_not_rxhash = { ETHTOOL_SFLAGS,
55 ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
56 ETH_FLAG_NTUPLE };
57
58static const struct cmd_expect cmd_expect_get_features_off[] = {
59 { &cmd_grxcsum_off, 4, 0, &cmd_grxcsum_off, sizeof(cmd_grxcsum_off) },
60 { &cmd_gtxcsum_off, 4, 0, &cmd_gtxcsum_off, sizeof(cmd_gtxcsum_off) },
61 { &cmd_gsg_off, 4, 0, &cmd_gsg_off, sizeof(cmd_gsg_off) },
62 { &cmd_gtso_off, 4, 0, &cmd_gtso_off, sizeof(cmd_gtso_off) },
63 { &cmd_gufo_off, 4, 0, &cmd_gufo_off, sizeof(cmd_gufo_off) },
64 { &cmd_ggso_off, 4, 0, &cmd_ggso_off, sizeof(cmd_ggso_off) },
65 { &cmd_gflags_off, 4, 0, &cmd_gflags_off, sizeof(cmd_gflags_off) },
66 { &cmd_ggro_off, 4,0, &cmd_ggro_off, sizeof(cmd_ggro_off) },
67 { 0, 0, 0, 0, 0 }
68};
69
70static const struct cmd_expect cmd_expect_set_features_off[] = {
71 { &cmd_srxcsum_off, sizeof(cmd_srxcsum_off), 0, 0, 0 },
72 { &cmd_stxcsum_off, sizeof(cmd_stxcsum_off), 0, 0, 0 },
73 { &cmd_ssg_off, sizeof(cmd_ssg_off), 0, 0, 0 },
74 { &cmd_stso_off, sizeof(cmd_stso_off), 0, 0, 0 },
75 { &cmd_sufo_off, sizeof(cmd_sufo_off), 0, 0, 0 },
76 { &cmd_sgso_off, sizeof(cmd_sgso_off), 0, 0, 0 },
77 { &cmd_gflags_on, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_on) },
78 { &cmd_sflags_off, sizeof(cmd_sflags_off), 0, 0, 0 },
79 { &cmd_sgro_off, sizeof(cmd_sgro_off), 0, 0, 0 },
80 { 0, 0, 0, 0, 0 }
81};
82
83static const struct cmd_expect cmd_expect_set_features_on[] = {
84 { &cmd_srxcsum_on, sizeof(cmd_srxcsum_on), 0, 0, 0 },
85 { &cmd_stxcsum_on, sizeof(cmd_stxcsum_on), 0, 0, 0 },
86 { &cmd_ssg_on, sizeof(cmd_ssg_on), 0, 0, 0 },
87 { &cmd_stso_on, sizeof(cmd_stso_on), 0, 0, 0 },
88 { &cmd_sufo_on, sizeof(cmd_sufo_on), 0, 0, 0 },
89 { &cmd_sgso_on, sizeof(cmd_sgso_on), 0, 0, 0 },
90 { &cmd_gflags_off, 4, 0, &cmd_gflags_on, sizeof(cmd_sflags_off) },
91 { &cmd_sflags_on, sizeof(cmd_sflags_on), 0, 0, 0 },
92 { &cmd_sgro_on, sizeof(cmd_sgro_on), 0, 0, 0 },
93 { 0, 0, 0, 0, 0 }
94};
95
96static struct test_case {
97 int rc;
98 const char *args;
99 const struct cmd_expect *expect;
100} const test_cases[] = {
101 { 0, "-k devname", cmd_expect_get_features_off },
102 { 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",
103 cmd_expect_set_features_off },
104 { 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",
105 cmd_expect_set_features_on },
106};
107
108static int expect_matched;
109static const struct cmd_expect *expect_next;
110
111int send_ioctl(struct cmd_context *ctx, void *cmd)
112{
113 int rc = test_ioctl(expect_next, cmd);
114
115 if (rc == TEST_IOCTL_MISMATCH) {
116 expect_matched = 0;
117 test_exit(0);
118 }
119 expect_next++;
120 return rc;
121}
122
123int main(void)
124{
125 const struct test_case *tc;
126 int test_rc;
127 int rc = 0;
128
129 for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) {
130 if (getenv("ETHTOOL_TEST_VERBOSE"))
131 printf("I: Test command line: ethtool %s\n", tc->args);
132 expect_matched = 1;
133 expect_next = tc->expect;
134 test_rc = test_cmdline(tc->args);
135
136 /* If we found a mismatch, or there is still another
137 * expected ioctl to match, the test failed.
138 */
139 if (!expect_matched || expect_next->cmd) {
140 fprintf(stderr,
141 "E: ethtool %s deviated from the expected "
142 "ioctl sequence after %zu calls\n",
143 tc->args, expect_next - tc->expect);
144 rc = 1;
145 } else if (test_rc != tc->rc) {
146 fprintf(stderr, "E: ethtool %s returns %d\n",
147 tc->args, test_rc);
148 rc = 1;
149 }
150 }
151
152 return rc;
153}