xref: /OK3568_Linux_fs/u-boot/test/dm/eth.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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