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