1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2015 National Instruments
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2015
5*4882a593Smuzhiyun * Joe Hershberger <joe.hershberger@ni.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <fdtdec.h>
13*4882a593Smuzhiyun #include <malloc.h>
14*4882a593Smuzhiyun #include <net.h>
15*4882a593Smuzhiyun #include <dm/test.h>
16*4882a593Smuzhiyun #include <dm/device-internal.h>
17*4882a593Smuzhiyun #include <dm/uclass-internal.h>
18*4882a593Smuzhiyun #include <asm/eth.h>
19*4882a593Smuzhiyun #include <test/ut.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define DM_TEST_ETH_NUM 4
24*4882a593Smuzhiyun
dm_test_eth(struct unit_test_state * uts)25*4882a593Smuzhiyun static int dm_test_eth(struct unit_test_state *uts)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun env_set("ethact", "eth@10002000");
30*4882a593Smuzhiyun ut_assertok(net_loop(PING));
31*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun env_set("ethact", "eth@10003000");
34*4882a593Smuzhiyun ut_assertok(net_loop(PING));
35*4882a593Smuzhiyun ut_asserteq_str("eth@10003000", env_get("ethact"));
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
38*4882a593Smuzhiyun ut_assertok(net_loop(PING));
39*4882a593Smuzhiyun ut_asserteq_str("eth@10004000", env_get("ethact"));
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun return 0;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
44*4882a593Smuzhiyun
dm_test_eth_alias(struct unit_test_state * uts)45*4882a593Smuzhiyun static int dm_test_eth_alias(struct unit_test_state *uts)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
48*4882a593Smuzhiyun env_set("ethact", "eth0");
49*4882a593Smuzhiyun ut_assertok(net_loop(PING));
50*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun env_set("ethact", "eth1");
53*4882a593Smuzhiyun ut_assertok(net_loop(PING));
54*4882a593Smuzhiyun ut_asserteq_str("eth@10004000", env_get("ethact"));
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /* Expected to fail since eth2 is not defined in the device tree */
57*4882a593Smuzhiyun env_set("ethact", "eth2");
58*4882a593Smuzhiyun ut_assertok(net_loop(PING));
59*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun env_set("ethact", "eth5");
62*4882a593Smuzhiyun ut_assertok(net_loop(PING));
63*4882a593Smuzhiyun ut_asserteq_str("eth@10003000", env_get("ethact"));
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun return 0;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
68*4882a593Smuzhiyun
dm_test_eth_prime(struct unit_test_state * uts)69*4882a593Smuzhiyun static int dm_test_eth_prime(struct unit_test_state *uts)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /* Expected to be "eth@10003000" because of ethprime variable */
74*4882a593Smuzhiyun env_set("ethact", NULL);
75*4882a593Smuzhiyun env_set("ethprime", "eth5");
76*4882a593Smuzhiyun ut_assertok(net_loop(PING));
77*4882a593Smuzhiyun ut_asserteq_str("eth@10003000", env_get("ethact"));
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /* Expected to be "eth@10002000" because it is first */
80*4882a593Smuzhiyun env_set("ethact", NULL);
81*4882a593Smuzhiyun env_set("ethprime", NULL);
82*4882a593Smuzhiyun ut_assertok(net_loop(PING));
83*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /**
90*4882a593Smuzhiyun * This test case is trying to test the following scenario:
91*4882a593Smuzhiyun * - All ethernet devices are not probed
92*4882a593Smuzhiyun * - "ethaddr" for all ethernet devices are not set
93*4882a593Smuzhiyun * - "ethact" is set to a valid ethernet device name
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * With Sandbox default test configuration, all ethernet devices are
96*4882a593Smuzhiyun * probed after power-up, so we have to manually create such scenario:
97*4882a593Smuzhiyun * - Remove all ethernet devices
98*4882a593Smuzhiyun * - Remove all "ethaddr" environment variables
99*4882a593Smuzhiyun * - Set "ethact" to the first ethernet device
100*4882a593Smuzhiyun *
101*4882a593Smuzhiyun * Do a ping test to see if anything goes wrong.
102*4882a593Smuzhiyun */
dm_test_eth_act(struct unit_test_state * uts)103*4882a593Smuzhiyun static int dm_test_eth_act(struct unit_test_state *uts)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun struct udevice *dev[DM_TEST_ETH_NUM];
106*4882a593Smuzhiyun const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
107*4882a593Smuzhiyun "sbe5", "eth@10004000"};
108*4882a593Smuzhiyun const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
109*4882a593Smuzhiyun "eth3addr", "eth1addr"};
110*4882a593Smuzhiyun char ethaddr[DM_TEST_ETH_NUM][18];
111*4882a593Smuzhiyun int i;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* Prepare the test scenario */
116*4882a593Smuzhiyun for (i = 0; i < DM_TEST_ETH_NUM; i++) {
117*4882a593Smuzhiyun ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
118*4882a593Smuzhiyun ethname[i], &dev[i]));
119*4882a593Smuzhiyun ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* Invalidate MAC address */
122*4882a593Smuzhiyun strcpy(ethaddr[i], env_get(addrname[i]));
123*4882a593Smuzhiyun /* Must disable access protection for ethaddr before clearing */
124*4882a593Smuzhiyun env_set(".flags", addrname[i]);
125*4882a593Smuzhiyun env_set(addrname[i], NULL);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /* Set ethact to "eth@10002000" */
129*4882a593Smuzhiyun env_set("ethact", ethname[0]);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /* Segment fault might happen if something is wrong */
132*4882a593Smuzhiyun ut_asserteq(-ENODEV, net_loop(PING));
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun for (i = 0; i < DM_TEST_ETH_NUM; i++) {
135*4882a593Smuzhiyun /* Restore the env */
136*4882a593Smuzhiyun env_set(".flags", addrname[i]);
137*4882a593Smuzhiyun env_set(addrname[i], ethaddr[i]);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun /* Probe the device again */
140*4882a593Smuzhiyun ut_assertok(device_probe(dev[i]));
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun env_set(".flags", NULL);
143*4882a593Smuzhiyun env_set("ethact", NULL);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun return 0;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun DM_TEST(dm_test_eth_act, DM_TESTF_SCAN_FDT);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* The asserts include a return on fail; cleanup in the caller */
_dm_test_eth_rotate1(struct unit_test_state * uts)150*4882a593Smuzhiyun static int _dm_test_eth_rotate1(struct unit_test_state *uts)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun /* Make sure that the default is to rotate to the next interface */
153*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
154*4882a593Smuzhiyun ut_assertok(net_loop(PING));
155*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /* If ethrotate is no, then we should fail on a bad MAC */
158*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
159*4882a593Smuzhiyun env_set("ethrotate", "no");
160*4882a593Smuzhiyun ut_asserteq(-EINVAL, net_loop(PING));
161*4882a593Smuzhiyun ut_asserteq_str("eth@10004000", env_get("ethact"));
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
_dm_test_eth_rotate2(struct unit_test_state * uts)166*4882a593Smuzhiyun static int _dm_test_eth_rotate2(struct unit_test_state *uts)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun /* Make sure we can skip invalid devices */
169*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
170*4882a593Smuzhiyun ut_assertok(net_loop(PING));
171*4882a593Smuzhiyun ut_asserteq_str("eth@10004000", env_get("ethact"));
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* Make sure we can handle device name which is not eth# */
174*4882a593Smuzhiyun env_set("ethact", "sbe5");
175*4882a593Smuzhiyun ut_assertok(net_loop(PING));
176*4882a593Smuzhiyun ut_asserteq_str("sbe5", env_get("ethact"));
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun return 0;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
dm_test_eth_rotate(struct unit_test_state * uts)181*4882a593Smuzhiyun static int dm_test_eth_rotate(struct unit_test_state *uts)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun char ethaddr[18];
184*4882a593Smuzhiyun int retval;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun /* Set target IP to mock ping */
187*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun /* Invalidate eth1's MAC address */
190*4882a593Smuzhiyun strcpy(ethaddr, env_get("eth1addr"));
191*4882a593Smuzhiyun /* Must disable access protection for eth1addr before clearing */
192*4882a593Smuzhiyun env_set(".flags", "eth1addr");
193*4882a593Smuzhiyun env_set("eth1addr", NULL);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun retval = _dm_test_eth_rotate1(uts);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /* Restore the env */
198*4882a593Smuzhiyun env_set("eth1addr", ethaddr);
199*4882a593Smuzhiyun env_set("ethrotate", NULL);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun if (!retval) {
202*4882a593Smuzhiyun /* Invalidate eth0's MAC address */
203*4882a593Smuzhiyun strcpy(ethaddr, env_get("ethaddr"));
204*4882a593Smuzhiyun /* Must disable access protection for ethaddr before clearing */
205*4882a593Smuzhiyun env_set(".flags", "ethaddr");
206*4882a593Smuzhiyun env_set("ethaddr", NULL);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun retval = _dm_test_eth_rotate2(uts);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /* Restore the env */
211*4882a593Smuzhiyun env_set("ethaddr", ethaddr);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun /* Restore the env */
214*4882a593Smuzhiyun env_set(".flags", NULL);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun return retval;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT);
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* The asserts include a return on fail; cleanup in the caller */
_dm_test_net_retry(struct unit_test_state * uts)221*4882a593Smuzhiyun static int _dm_test_net_retry(struct unit_test_state *uts)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun /*
224*4882a593Smuzhiyun * eth1 is disabled and netretry is yes, so the ping should succeed and
225*4882a593Smuzhiyun * the active device should be eth0
226*4882a593Smuzhiyun */
227*4882a593Smuzhiyun sandbox_eth_disable_response(1, true);
228*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
229*4882a593Smuzhiyun env_set("netretry", "yes");
230*4882a593Smuzhiyun sandbox_eth_skip_timeout();
231*4882a593Smuzhiyun ut_assertok(net_loop(PING));
232*4882a593Smuzhiyun ut_asserteq_str("eth@10002000", env_get("ethact"));
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /*
235*4882a593Smuzhiyun * eth1 is disabled and netretry is no, so the ping should fail and the
236*4882a593Smuzhiyun * active device should be eth1
237*4882a593Smuzhiyun */
238*4882a593Smuzhiyun env_set("ethact", "eth@10004000");
239*4882a593Smuzhiyun env_set("netretry", "no");
240*4882a593Smuzhiyun sandbox_eth_skip_timeout();
241*4882a593Smuzhiyun ut_asserteq(-ETIMEDOUT, net_loop(PING));
242*4882a593Smuzhiyun ut_asserteq_str("eth@10004000", env_get("ethact"));
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun return 0;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
dm_test_net_retry(struct unit_test_state * uts)247*4882a593Smuzhiyun static int dm_test_net_retry(struct unit_test_state *uts)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun int retval;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun net_ping_ip = string_to_ip("1.1.2.2");
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun retval = _dm_test_net_retry(uts);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /* Restore the env */
256*4882a593Smuzhiyun env_set("netretry", NULL);
257*4882a593Smuzhiyun sandbox_eth_disable_response(1, false);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun return retval;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
262