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