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 262 static int sb_check_arp_reply(struct udevice *dev, void *packet, 263 unsigned int len) 264 { 265 struct eth_sandbox_priv *priv = dev_get_priv(dev); 266 struct ethernet_hdr *eth = packet; 267 struct arp_hdr *arp; 268 /* Used by all of the ut_assert macros */ 269 struct unit_test_state *uts = priv->priv; 270 271 if (ntohs(eth->et_protlen) != PROT_ARP) 272 return 0; 273 274 arp = packet + ETHER_HDR_SIZE; 275 276 if (ntohs(arp->ar_op) != ARPOP_REPLY) 277 return 0; 278 279 /* This test would be worthless if we are not waiting */ 280 ut_assert(arp_is_waiting()); 281 282 /* Validate response */ 283 ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0); 284 ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0); 285 ut_assert(eth->et_protlen == htons(PROT_ARP)); 286 287 ut_assert(arp->ar_hrd == htons(ARP_ETHER)); 288 ut_assert(arp->ar_pro == htons(PROT_IP)); 289 ut_assert(arp->ar_hln == ARP_HLEN); 290 ut_assert(arp->ar_pln == ARP_PLEN); 291 ut_assert(memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) == 0); 292 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr); 293 ut_assert(memcmp(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN) == 0); 294 ut_assert(net_read_ip(&arp->ar_tpa).s_addr == 295 string_to_ip("1.1.2.4").s_addr); 296 297 return 0; 298 } 299 300 static int sb_with_async_arp_handler(struct udevice *dev, void *packet, 301 unsigned int len) 302 { 303 struct eth_sandbox_priv *priv = dev_get_priv(dev); 304 struct ethernet_hdr *eth = packet; 305 struct arp_hdr *arp = packet + ETHER_HDR_SIZE; 306 int ret; 307 308 /* 309 * If we are about to generate a reply to ARP, first inject a request 310 * from another host 311 */ 312 if (ntohs(eth->et_protlen) == PROT_ARP && 313 ntohs(arp->ar_op) == ARPOP_REQUEST) { 314 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */ 315 priv->fake_host_ipaddr = string_to_ip("1.1.2.4"); 316 317 ret = sandbox_eth_recv_arp_req(dev); 318 if (ret) 319 return ret; 320 } 321 322 sandbox_eth_arp_req_to_reply(dev, packet, len); 323 sandbox_eth_ping_req_to_reply(dev, packet, len); 324 325 return sb_check_arp_reply(dev, packet, len); 326 } 327 328 static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) 329 { 330 net_ping_ip = string_to_ip("1.1.2.2"); 331 332 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler); 333 /* Used by all of the ut_assert macros in the tx_handler */ 334 sandbox_eth_set_priv(0, uts); 335 336 env_set("ethact", "eth@10002000"); 337 ut_assertok(net_loop(PING)); 338 ut_asserteq_str("eth@10002000", env_get("ethact")); 339 340 sandbox_eth_set_tx_handler(0, NULL); 341 342 return 0; 343 } 344 345 DM_TEST(dm_test_eth_async_arp_reply, DM_TESTF_SCAN_FDT); 346 347 static int sb_check_ping_reply(struct udevice *dev, void *packet, 348 unsigned int len) 349 { 350 struct eth_sandbox_priv *priv = dev_get_priv(dev); 351 struct ethernet_hdr *eth = packet; 352 struct ip_udp_hdr *ip; 353 struct icmp_hdr *icmp; 354 /* Used by all of the ut_assert macros */ 355 struct unit_test_state *uts = priv->priv; 356 357 if (ntohs(eth->et_protlen) != PROT_IP) 358 return 0; 359 360 ip = packet + ETHER_HDR_SIZE; 361 362 if (ip->ip_p != IPPROTO_ICMP) 363 return 0; 364 365 icmp = (struct icmp_hdr *)&ip->udp_src; 366 367 if (icmp->type != ICMP_ECHO_REPLY) 368 return 0; 369 370 /* This test would be worthless if we are not waiting */ 371 ut_assert(arp_is_waiting()); 372 373 /* Validate response */ 374 ut_assert(memcmp(eth->et_src, net_ethaddr, ARP_HLEN) == 0); 375 ut_assert(memcmp(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN) == 0); 376 ut_assert(eth->et_protlen == htons(PROT_IP)); 377 378 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr); 379 ut_assert(net_read_ip(&ip->ip_dst).s_addr == 380 string_to_ip("1.1.2.4").s_addr); 381 382 return 0; 383 } 384 385 static int sb_with_async_ping_handler(struct udevice *dev, void *packet, 386 unsigned int len) 387 { 388 struct eth_sandbox_priv *priv = dev_get_priv(dev); 389 struct ethernet_hdr *eth = packet; 390 struct arp_hdr *arp = packet + ETHER_HDR_SIZE; 391 int ret; 392 393 /* 394 * If we are about to generate a reply to ARP, first inject a request 395 * from another host 396 */ 397 if (ntohs(eth->et_protlen) == PROT_ARP && 398 ntohs(arp->ar_op) == ARPOP_REQUEST) { 399 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */ 400 priv->fake_host_ipaddr = string_to_ip("1.1.2.4"); 401 402 ret = sandbox_eth_recv_ping_req(dev); 403 if (ret) 404 return ret; 405 } 406 407 sandbox_eth_arp_req_to_reply(dev, packet, len); 408 sandbox_eth_ping_req_to_reply(dev, packet, len); 409 410 return sb_check_ping_reply(dev, packet, len); 411 } 412 413 static int dm_test_eth_async_ping_reply(struct unit_test_state *uts) 414 { 415 net_ping_ip = string_to_ip("1.1.2.2"); 416 417 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler); 418 /* Used by all of the ut_assert macros in the tx_handler */ 419 sandbox_eth_set_priv(0, uts); 420 421 env_set("ethact", "eth@10002000"); 422 ut_assertok(net_loop(PING)); 423 ut_asserteq_str("eth@10002000", env_get("ethact")); 424 425 sandbox_eth_set_tx_handler(0, NULL); 426 427 return 0; 428 } 429 430 DM_TEST(dm_test_eth_async_ping_reply, DM_TESTF_SCAN_FDT); 431