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