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