xref: /rk3399_rockchip-uboot/test/dm/eth.c (revision 00caae6d47645e68d6e5277aceb69592b49381a6)
1bfacad7dSJoe Hershberger /*
2bfacad7dSJoe Hershberger  * Copyright (c) 2015 National Instruments
3bfacad7dSJoe Hershberger  *
4bfacad7dSJoe Hershberger  * (C) Copyright 2015
5bfacad7dSJoe Hershberger  * Joe Hershberger <joe.hershberger@ni.com>
6bfacad7dSJoe Hershberger  *
7bfacad7dSJoe Hershberger  * SPDX-License-Identifier:	GPL-2.0
8bfacad7dSJoe Hershberger  */
9bfacad7dSJoe Hershberger 
10bfacad7dSJoe Hershberger #include <common.h>
11bfacad7dSJoe Hershberger #include <dm.h>
12bfacad7dSJoe Hershberger #include <fdtdec.h>
13bfacad7dSJoe Hershberger #include <malloc.h>
14bfacad7dSJoe Hershberger #include <net.h>
15e721b882SJoe Hershberger #include <dm/test.h>
166d9764c2SBin Meng #include <dm/device-internal.h>
176d9764c2SBin Meng #include <dm/uclass-internal.h>
187ece1c61SJoe Hershberger #include <asm/eth.h>
19e721b882SJoe Hershberger #include <test/ut.h>
20bfacad7dSJoe Hershberger 
21bfacad7dSJoe Hershberger DECLARE_GLOBAL_DATA_PTR;
22bfacad7dSJoe Hershberger 
236d9764c2SBin Meng #define DM_TEST_ETH_NUM		4
246d9764c2SBin Meng 
dm_test_eth(struct unit_test_state * uts)25e721b882SJoe Hershberger static int dm_test_eth(struct unit_test_state *uts)
26bfacad7dSJoe Hershberger {
27049a95a7SJoe Hershberger 	net_ping_ip = string_to_ip("1.1.2.2");
28bfacad7dSJoe Hershberger 
29382bee57SSimon Glass 	env_set("ethact", "eth@10002000");
30bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
31*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
32bfacad7dSJoe Hershberger 
33382bee57SSimon Glass 	env_set("ethact", "eth@10003000");
34bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
35*00caae6dSSimon Glass 	ut_asserteq_str("eth@10003000", env_get("ethact"));
36bfacad7dSJoe Hershberger 
37382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
38bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
39*00caae6dSSimon Glass 	ut_asserteq_str("eth@10004000", env_get("ethact"));
40bfacad7dSJoe Hershberger 
41bfacad7dSJoe Hershberger 	return 0;
42bfacad7dSJoe Hershberger }
43bfacad7dSJoe Hershberger DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
44e58780dcSJoe Hershberger 
dm_test_eth_alias(struct unit_test_state * uts)45e721b882SJoe Hershberger static int dm_test_eth_alias(struct unit_test_state *uts)
46e58780dcSJoe Hershberger {
47049a95a7SJoe Hershberger 	net_ping_ip = string_to_ip("1.1.2.2");
48382bee57SSimon Glass 	env_set("ethact", "eth0");
49bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
50*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
51e58780dcSJoe Hershberger 
52382bee57SSimon Glass 	env_set("ethact", "eth1");
53bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
54*00caae6dSSimon Glass 	ut_asserteq_str("eth@10004000", env_get("ethact"));
55e58780dcSJoe Hershberger 
56e58780dcSJoe Hershberger 	/* Expected to fail since eth2 is not defined in the device tree */
57382bee57SSimon Glass 	env_set("ethact", "eth2");
58bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
59*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
60e58780dcSJoe Hershberger 
61382bee57SSimon Glass 	env_set("ethact", "eth5");
62bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
63*00caae6dSSimon Glass 	ut_asserteq_str("eth@10003000", env_get("ethact"));
64e58780dcSJoe Hershberger 
65e58780dcSJoe Hershberger 	return 0;
66e58780dcSJoe Hershberger }
67e58780dcSJoe Hershberger DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
686536b9bbSJoe Hershberger 
dm_test_eth_prime(struct unit_test_state * uts)69e721b882SJoe Hershberger static int dm_test_eth_prime(struct unit_test_state *uts)
706536b9bbSJoe Hershberger {
71049a95a7SJoe Hershberger 	net_ping_ip = string_to_ip("1.1.2.2");
726536b9bbSJoe Hershberger 
736536b9bbSJoe Hershberger 	/* Expected to be "eth@10003000" because of ethprime variable */
74382bee57SSimon Glass 	env_set("ethact", NULL);
75382bee57SSimon Glass 	env_set("ethprime", "eth5");
76bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
77*00caae6dSSimon Glass 	ut_asserteq_str("eth@10003000", env_get("ethact"));
786536b9bbSJoe Hershberger 
796536b9bbSJoe Hershberger 	/* Expected to be "eth@10002000" because it is first */
80382bee57SSimon Glass 	env_set("ethact", NULL);
81382bee57SSimon Glass 	env_set("ethprime", NULL);
82bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
83*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
846536b9bbSJoe Hershberger 
856536b9bbSJoe Hershberger 	return 0;
866536b9bbSJoe Hershberger }
876536b9bbSJoe Hershberger DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
887d104eabSJoe Hershberger 
896d9764c2SBin Meng /**
906d9764c2SBin Meng  * This test case is trying to test the following scenario:
916d9764c2SBin Meng  *	- All ethernet devices are not probed
926d9764c2SBin Meng  *	- "ethaddr" for all ethernet devices are not set
936d9764c2SBin Meng  *	- "ethact" is set to a valid ethernet device name
946d9764c2SBin Meng  *
956d9764c2SBin Meng  * With Sandbox default test configuration, all ethernet devices are
966d9764c2SBin Meng  * probed after power-up, so we have to manually create such scenario:
976d9764c2SBin Meng  *	- Remove all ethernet devices
986d9764c2SBin Meng  *	- Remove all "ethaddr" environment variables
996d9764c2SBin Meng  *	- Set "ethact" to the first ethernet device
1006d9764c2SBin Meng  *
1016d9764c2SBin Meng  * Do a ping test to see if anything goes wrong.
1026d9764c2SBin Meng  */
dm_test_eth_act(struct unit_test_state * uts)1036d9764c2SBin Meng static int dm_test_eth_act(struct unit_test_state *uts)
1046d9764c2SBin Meng {
1056d9764c2SBin Meng 	struct udevice *dev[DM_TEST_ETH_NUM];
1066d9764c2SBin Meng 	const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
1076d9764c2SBin Meng 						"sbe5", "eth@10004000"};
1086d9764c2SBin Meng 	const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
1096d9764c2SBin Meng 						 "eth3addr", "eth1addr"};
1106d9764c2SBin Meng 	char ethaddr[DM_TEST_ETH_NUM][18];
1116d9764c2SBin Meng 	int i;
1126d9764c2SBin Meng 
1136d9764c2SBin Meng 	net_ping_ip = string_to_ip("1.1.2.2");
1146d9764c2SBin Meng 
1156d9764c2SBin Meng 	/* Prepare the test scenario */
1166d9764c2SBin Meng 	for (i = 0; i < DM_TEST_ETH_NUM; i++) {
1176d9764c2SBin Meng 		ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
1186d9764c2SBin Meng 						       ethname[i], &dev[i]));
119706865afSStefan Roese 		ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
1206d9764c2SBin Meng 
1216d9764c2SBin Meng 		/* Invalidate MAC address */
122*00caae6dSSimon Glass 		strcpy(ethaddr[i], env_get(addrname[i]));
1236d9764c2SBin Meng 		/* Must disable access protection for ethaddr before clearing */
124382bee57SSimon Glass 		env_set(".flags", addrname[i]);
125382bee57SSimon Glass 		env_set(addrname[i], NULL);
1266d9764c2SBin Meng 	}
1276d9764c2SBin Meng 
1286d9764c2SBin Meng 	/* Set ethact to "eth@10002000" */
129382bee57SSimon Glass 	env_set("ethact", ethname[0]);
1306d9764c2SBin Meng 
1316d9764c2SBin Meng 	/* Segment fault might happen if something is wrong */
1326d9764c2SBin Meng 	ut_asserteq(-ENODEV, net_loop(PING));
1336d9764c2SBin Meng 
1346d9764c2SBin Meng 	for (i = 0; i < DM_TEST_ETH_NUM; i++) {
1356d9764c2SBin Meng 		/* Restore the env */
136382bee57SSimon Glass 		env_set(".flags", addrname[i]);
137382bee57SSimon Glass 		env_set(addrname[i], ethaddr[i]);
1386d9764c2SBin Meng 
1396d9764c2SBin Meng 		/* Probe the device again */
1406d9764c2SBin Meng 		ut_assertok(device_probe(dev[i]));
1416d9764c2SBin Meng 	}
142382bee57SSimon Glass 	env_set(".flags", NULL);
143382bee57SSimon Glass 	env_set("ethact", NULL);
1446d9764c2SBin Meng 
1456d9764c2SBin Meng 	return 0;
1466d9764c2SBin Meng }
1476d9764c2SBin Meng DM_TEST(dm_test_eth_act, DM_TESTF_SCAN_FDT);
1486d9764c2SBin Meng 
14909129becSJoe Hershberger /* The asserts include a return on fail; cleanup in the caller */
_dm_test_eth_rotate1(struct unit_test_state * uts)15009129becSJoe Hershberger static int _dm_test_eth_rotate1(struct unit_test_state *uts)
1517d104eabSJoe Hershberger {
1527d104eabSJoe Hershberger 	/* Make sure that the default is to rotate to the next interface */
153382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
154bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
155*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
1567d104eabSJoe Hershberger 
1577d104eabSJoe Hershberger 	/* If ethrotate is no, then we should fail on a bad MAC */
158382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
159382bee57SSimon Glass 	env_set("ethrotate", "no");
160bc0571fcSJoe Hershberger 	ut_asserteq(-EINVAL, net_loop(PING));
161*00caae6dSSimon Glass 	ut_asserteq_str("eth@10004000", env_get("ethact"));
1627d104eabSJoe Hershberger 
16309129becSJoe Hershberger 	return 0;
16409129becSJoe Hershberger }
16509129becSJoe Hershberger 
_dm_test_eth_rotate2(struct unit_test_state * uts)16609129becSJoe Hershberger static int _dm_test_eth_rotate2(struct unit_test_state *uts)
16709129becSJoe Hershberger {
16809129becSJoe Hershberger 	/* Make sure we can skip invalid devices */
169382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
17009129becSJoe Hershberger 	ut_assertok(net_loop(PING));
171*00caae6dSSimon Glass 	ut_asserteq_str("eth@10004000", env_get("ethact"));
17209129becSJoe Hershberger 
17371d7971fSBin Meng 	/* Make sure we can handle device name which is not eth# */
174382bee57SSimon Glass 	env_set("ethact", "sbe5");
17571d7971fSBin Meng 	ut_assertok(net_loop(PING));
176*00caae6dSSimon Glass 	ut_asserteq_str("sbe5", env_get("ethact"));
17771d7971fSBin Meng 
17809129becSJoe Hershberger 	return 0;
17909129becSJoe Hershberger }
18009129becSJoe Hershberger 
dm_test_eth_rotate(struct unit_test_state * uts)18109129becSJoe Hershberger static int dm_test_eth_rotate(struct unit_test_state *uts)
18209129becSJoe Hershberger {
18309129becSJoe Hershberger 	char ethaddr[18];
18409129becSJoe Hershberger 	int retval;
18509129becSJoe Hershberger 
18609129becSJoe Hershberger 	/* Set target IP to mock ping */
18709129becSJoe Hershberger 	net_ping_ip = string_to_ip("1.1.2.2");
18809129becSJoe Hershberger 
18909129becSJoe Hershberger 	/* Invalidate eth1's MAC address */
190*00caae6dSSimon Glass 	strcpy(ethaddr, env_get("eth1addr"));
19109129becSJoe Hershberger 	/* Must disable access protection for eth1addr before clearing */
192382bee57SSimon Glass 	env_set(".flags", "eth1addr");
193382bee57SSimon Glass 	env_set("eth1addr", NULL);
19409129becSJoe Hershberger 
19509129becSJoe Hershberger 	retval = _dm_test_eth_rotate1(uts);
19609129becSJoe Hershberger 
1977d104eabSJoe Hershberger 	/* Restore the env */
198382bee57SSimon Glass 	env_set("eth1addr", ethaddr);
199382bee57SSimon Glass 	env_set("ethrotate", NULL);
2007d104eabSJoe Hershberger 
20109129becSJoe Hershberger 	if (!retval) {
2027d104eabSJoe Hershberger 		/* Invalidate eth0's MAC address */
203*00caae6dSSimon Glass 		strcpy(ethaddr, env_get("ethaddr"));
20473c2bbeeSJoe Hershberger 		/* Must disable access protection for ethaddr before clearing */
205382bee57SSimon Glass 		env_set(".flags", "ethaddr");
206382bee57SSimon Glass 		env_set("ethaddr", NULL);
2077d104eabSJoe Hershberger 
20809129becSJoe Hershberger 		retval = _dm_test_eth_rotate2(uts);
2097d104eabSJoe Hershberger 
2107d104eabSJoe Hershberger 		/* Restore the env */
211382bee57SSimon Glass 		env_set("ethaddr", ethaddr);
21209129becSJoe Hershberger 	}
21309129becSJoe Hershberger 	/* Restore the env */
214382bee57SSimon Glass 	env_set(".flags", NULL);
2157d104eabSJoe Hershberger 
21609129becSJoe Hershberger 	return retval;
2177d104eabSJoe Hershberger }
2187d104eabSJoe Hershberger DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT);
2197ece1c61SJoe Hershberger 
22009129becSJoe Hershberger /* The asserts include a return on fail; cleanup in the caller */
_dm_test_net_retry(struct unit_test_state * uts)22109129becSJoe Hershberger static int _dm_test_net_retry(struct unit_test_state *uts)
2227ece1c61SJoe Hershberger {
2237ece1c61SJoe Hershberger 	/*
2247ece1c61SJoe Hershberger 	 * eth1 is disabled and netretry is yes, so the ping should succeed and
2257ece1c61SJoe Hershberger 	 * the active device should be eth0
2267ece1c61SJoe Hershberger 	 */
2277ece1c61SJoe Hershberger 	sandbox_eth_disable_response(1, true);
228382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
229382bee57SSimon Glass 	env_set("netretry", "yes");
230172a31bfSJoe Hershberger 	sandbox_eth_skip_timeout();
231bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
232*00caae6dSSimon Glass 	ut_asserteq_str("eth@10002000", env_get("ethact"));
2337ece1c61SJoe Hershberger 
2347ece1c61SJoe Hershberger 	/*
2357ece1c61SJoe Hershberger 	 * eth1 is disabled and netretry is no, so the ping should fail and the
2367ece1c61SJoe Hershberger 	 * active device should be eth1
2377ece1c61SJoe Hershberger 	 */
238382bee57SSimon Glass 	env_set("ethact", "eth@10004000");
239382bee57SSimon Glass 	env_set("netretry", "no");
240172a31bfSJoe Hershberger 	sandbox_eth_skip_timeout();
241bc0571fcSJoe Hershberger 	ut_asserteq(-ETIMEDOUT, net_loop(PING));
242*00caae6dSSimon Glass 	ut_asserteq_str("eth@10004000", env_get("ethact"));
2437ece1c61SJoe Hershberger 
24409129becSJoe Hershberger 	return 0;
24509129becSJoe Hershberger }
24609129becSJoe Hershberger 
dm_test_net_retry(struct unit_test_state * uts)24709129becSJoe Hershberger static int dm_test_net_retry(struct unit_test_state *uts)
24809129becSJoe Hershberger {
24909129becSJoe Hershberger 	int retval;
25009129becSJoe Hershberger 
25109129becSJoe Hershberger 	net_ping_ip = string_to_ip("1.1.2.2");
25209129becSJoe Hershberger 
25309129becSJoe Hershberger 	retval = _dm_test_net_retry(uts);
25409129becSJoe Hershberger 
2557ece1c61SJoe Hershberger 	/* Restore the env */
256382bee57SSimon Glass 	env_set("netretry", NULL);
2577ece1c61SJoe Hershberger 	sandbox_eth_disable_response(1, false);
2587ece1c61SJoe Hershberger 
25909129becSJoe Hershberger 	return retval;
2607ece1c61SJoe Hershberger }
2617ece1c61SJoe Hershberger DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
262