xref: /rk3399_rockchip-uboot/test/dm/eth.c (revision 706865afe54eee83c1f3d7e9ea2f51db8e986d7b)
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 
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 
29bfacad7dSJoe Hershberger 	setenv("ethact", "eth@10002000");
30bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
31bfacad7dSJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("ethact"));
32bfacad7dSJoe Hershberger 
33bfacad7dSJoe Hershberger 	setenv("ethact", "eth@10003000");
34bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
35bfacad7dSJoe Hershberger 	ut_asserteq_str("eth@10003000", getenv("ethact"));
36bfacad7dSJoe Hershberger 
37bfacad7dSJoe Hershberger 	setenv("ethact", "eth@10004000");
38bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
39bfacad7dSJoe Hershberger 	ut_asserteq_str("eth@10004000", getenv("ethact"));
40bfacad7dSJoe Hershberger 
41bfacad7dSJoe Hershberger 	return 0;
42bfacad7dSJoe Hershberger }
43bfacad7dSJoe Hershberger DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
44e58780dcSJoe Hershberger 
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");
48e58780dcSJoe Hershberger 	setenv("ethact", "eth0");
49bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
50e58780dcSJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("ethact"));
51e58780dcSJoe Hershberger 
52e58780dcSJoe Hershberger 	setenv("ethact", "eth1");
53bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
54e58780dcSJoe Hershberger 	ut_asserteq_str("eth@10004000", getenv("ethact"));
55e58780dcSJoe Hershberger 
56e58780dcSJoe Hershberger 	/* Expected to fail since eth2 is not defined in the device tree */
57e58780dcSJoe Hershberger 	setenv("ethact", "eth2");
58bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
59e58780dcSJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("ethact"));
60e58780dcSJoe Hershberger 
61e58780dcSJoe Hershberger 	setenv("ethact", "eth5");
62bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
63e58780dcSJoe Hershberger 	ut_asserteq_str("eth@10003000", getenv("ethact"));
64e58780dcSJoe Hershberger 
65e58780dcSJoe Hershberger 	return 0;
66e58780dcSJoe Hershberger }
67e58780dcSJoe Hershberger DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
686536b9bbSJoe Hershberger 
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 */
746536b9bbSJoe Hershberger 	setenv("ethact", NULL);
756536b9bbSJoe Hershberger 	setenv("ethprime", "eth5");
76bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
776536b9bbSJoe Hershberger 	ut_asserteq_str("eth@10003000", getenv("ethact"));
786536b9bbSJoe Hershberger 
796536b9bbSJoe Hershberger 	/* Expected to be "eth@10002000" because it is first */
806536b9bbSJoe Hershberger 	setenv("ethact", NULL);
816536b9bbSJoe Hershberger 	setenv("ethprime", NULL);
82bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
836536b9bbSJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("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  */
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]));
119*706865afSStefan Roese 		ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
1206d9764c2SBin Meng 
1216d9764c2SBin Meng 		/* Invalidate MAC address */
1226d9764c2SBin Meng 		strcpy(ethaddr[i], getenv(addrname[i]));
1236d9764c2SBin Meng 		/* Must disable access protection for ethaddr before clearing */
1246d9764c2SBin Meng 		setenv(".flags", addrname[i]);
1256d9764c2SBin Meng 		setenv(addrname[i], NULL);
1266d9764c2SBin Meng 	}
1276d9764c2SBin Meng 
1286d9764c2SBin Meng 	/* Set ethact to "eth@10002000" */
1296d9764c2SBin Meng 	setenv("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 */
1366d9764c2SBin Meng 		setenv(".flags", addrname[i]);
1376d9764c2SBin Meng 		setenv(addrname[i], ethaddr[i]);
1386d9764c2SBin Meng 
1396d9764c2SBin Meng 		/* Probe the device again */
1406d9764c2SBin Meng 		ut_assertok(device_probe(dev[i]));
1416d9764c2SBin Meng 	}
1426d9764c2SBin Meng 	setenv(".flags", NULL);
1436d9764c2SBin Meng 	setenv("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 */
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 */
1537d104eabSJoe Hershberger 	setenv("ethact", "eth@10004000");
154bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
1557d104eabSJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("ethact"));
1567d104eabSJoe Hershberger 
1577d104eabSJoe Hershberger 	/* If ethrotate is no, then we should fail on a bad MAC */
1587d104eabSJoe Hershberger 	setenv("ethact", "eth@10004000");
1597d104eabSJoe Hershberger 	setenv("ethrotate", "no");
160bc0571fcSJoe Hershberger 	ut_asserteq(-EINVAL, net_loop(PING));
1617d104eabSJoe Hershberger 	ut_asserteq_str("eth@10004000", getenv("ethact"));
1627d104eabSJoe Hershberger 
16309129becSJoe Hershberger 	return 0;
16409129becSJoe Hershberger }
16509129becSJoe Hershberger 
16609129becSJoe Hershberger static int _dm_test_eth_rotate2(struct unit_test_state *uts)
16709129becSJoe Hershberger {
16809129becSJoe Hershberger 	/* Make sure we can skip invalid devices */
16909129becSJoe Hershberger 	setenv("ethact", "eth@10004000");
17009129becSJoe Hershberger 	ut_assertok(net_loop(PING));
17109129becSJoe Hershberger 	ut_asserteq_str("eth@10004000", getenv("ethact"));
17209129becSJoe Hershberger 
17371d7971fSBin Meng 	/* Make sure we can handle device name which is not eth# */
17471d7971fSBin Meng 	setenv("ethact", "sbe5");
17571d7971fSBin Meng 	ut_assertok(net_loop(PING));
17671d7971fSBin Meng 	ut_asserteq_str("sbe5", getenv("ethact"));
17771d7971fSBin Meng 
17809129becSJoe Hershberger 	return 0;
17909129becSJoe Hershberger }
18009129becSJoe Hershberger 
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 */
19009129becSJoe Hershberger 	strcpy(ethaddr, getenv("eth1addr"));
19109129becSJoe Hershberger 	/* Must disable access protection for eth1addr before clearing */
19209129becSJoe Hershberger 	setenv(".flags", "eth1addr");
19309129becSJoe Hershberger 	setenv("eth1addr", NULL);
19409129becSJoe Hershberger 
19509129becSJoe Hershberger 	retval = _dm_test_eth_rotate1(uts);
19609129becSJoe Hershberger 
1977d104eabSJoe Hershberger 	/* Restore the env */
1987d104eabSJoe Hershberger 	setenv("eth1addr", ethaddr);
1997d104eabSJoe Hershberger 	setenv("ethrotate", NULL);
2007d104eabSJoe Hershberger 
20109129becSJoe Hershberger 	if (!retval) {
2027d104eabSJoe Hershberger 		/* Invalidate eth0's MAC address */
2037d104eabSJoe Hershberger 		strcpy(ethaddr, getenv("ethaddr"));
20473c2bbeeSJoe Hershberger 		/* Must disable access protection for ethaddr before clearing */
2057d104eabSJoe Hershberger 		setenv(".flags", "ethaddr");
2067d104eabSJoe Hershberger 		setenv("ethaddr", NULL);
2077d104eabSJoe Hershberger 
20809129becSJoe Hershberger 		retval = _dm_test_eth_rotate2(uts);
2097d104eabSJoe Hershberger 
2107d104eabSJoe Hershberger 		/* Restore the env */
2117d104eabSJoe Hershberger 		setenv("ethaddr", ethaddr);
21209129becSJoe Hershberger 	}
21309129becSJoe Hershberger 	/* Restore the env */
2147d104eabSJoe Hershberger 	setenv(".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 */
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);
2287ece1c61SJoe Hershberger 	setenv("ethact", "eth@10004000");
2297ece1c61SJoe Hershberger 	setenv("netretry", "yes");
230172a31bfSJoe Hershberger 	sandbox_eth_skip_timeout();
231bc0571fcSJoe Hershberger 	ut_assertok(net_loop(PING));
2327ece1c61SJoe Hershberger 	ut_asserteq_str("eth@10002000", getenv("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 	 */
2387ece1c61SJoe Hershberger 	setenv("ethact", "eth@10004000");
2397ece1c61SJoe Hershberger 	setenv("netretry", "no");
240172a31bfSJoe Hershberger 	sandbox_eth_skip_timeout();
241bc0571fcSJoe Hershberger 	ut_asserteq(-ETIMEDOUT, net_loop(PING));
2427ece1c61SJoe Hershberger 	ut_asserteq_str("eth@10004000", getenv("ethact"));
2437ece1c61SJoe Hershberger 
24409129becSJoe Hershberger 	return 0;
24509129becSJoe Hershberger }
24609129becSJoe Hershberger 
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 */
2567ece1c61SJoe Hershberger 	setenv("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