blob: ebf01d8cf38763d67a9ab29620ef0dbfbce5a869 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershberger4c197242015-03-22 17:09:15 -05002/*
3 * Copyright (c) 2015 National Instruments
4 *
5 * (C) Copyright 2015
6 * Joe Hershberger <joe.hershberger@ni.com>
Joe Hershberger4c197242015-03-22 17:09:15 -05007 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060011#include <env.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050012#include <fdtdec.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050014#include <malloc.h>
15#include <net.h>
Viacheslav Mitrofanovf96b1092022-12-02 12:18:09 +030016#include <net6.h>
Simon Glass75c4d412020-07-19 10:15:37 -060017#include <asm/eth.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050018#include <dm/test.h>
Bin Meng111473a2015-10-07 21:45:43 -070019#include <dm/device-internal.h>
20#include <dm/uclass-internal.h>
Simon Glass75c4d412020-07-19 10:15:37 -060021#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050022#include <test/ut.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050023
Bin Meng111473a2015-10-07 21:45:43 -070024#define DM_TEST_ETH_NUM 4
25
Viacheslav Mitrofanovf96b1092022-12-02 12:18:09 +030026#if IS_ENABLED(CONFIG_IPV6)
27static int dm_test_string_to_ip6(struct unit_test_state *uts)
28{
29 char *str;
30 struct test_ip6_pair {
31 char *string_addr;
32 struct in6_addr ip6_addr;
33 };
34
35 struct in6_addr ip6 = {0};
36
37 /* Correct statements */
38 struct test_ip6_pair test_suite[] = {
39 {"2001:db8::0:1234:1", {.s6_addr32[0] = 0xb80d0120,
40 .s6_addr32[1] = 0x00000000,
41 .s6_addr32[2] = 0x00000000,
42 .s6_addr32[3] = 0x01003412}},
43 {"2001:0db8:0000:0000:0000:0000:1234:0001",
44 {.s6_addr32[0] = 0xb80d0120,
45 .s6_addr32[1] = 0x00000000,
46 .s6_addr32[2] = 0x00000000,
47 .s6_addr32[3] = 0x01003412}},
48 {"::1", {.s6_addr32[0] = 0x00000000,
49 .s6_addr32[1] = 0x00000000,
50 .s6_addr32[2] = 0x00000000,
51 .s6_addr32[3] = 0x01000000}},
52 {"::ffff:192.168.1.1", {.s6_addr32[0] = 0x00000000,
53 .s6_addr32[1] = 0x00000000,
54 .s6_addr32[2] = 0xffff0000,
55 .s6_addr32[3] = 0x0101a8c0}},
56 };
57
58 for (int i = 0; i < ARRAY_SIZE(test_suite); ++i) {
59 ut_assertok(string_to_ip6(test_suite[i].string_addr,
60 strlen(test_suite[i].string_addr), &ip6));
61 ut_asserteq_mem(&ip6, &test_suite[i].ip6_addr,
62 sizeof(struct in6_addr));
63 }
64
65 /* Incorrect statements */
66 str = "hello:world";
67 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
68 str = "2001:db8::0::0";
69 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
70 str = "2001:db8:192.168.1.1::1";
71 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
72 str = "192.168.1.1";
73 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
74
75 return 0;
76}
77DM_TEST(dm_test_string_to_ip6, 0);
Viacheslav Mitrofanov224f5632022-12-02 12:18:10 +030078
79static int dm_test_csum_ipv6_magic(struct unit_test_state *uts)
80{
81 unsigned short csum = 0xbeef;
82 /* Predefined correct parameters */
83 unsigned short correct_csum = 0xd8ac;
84 struct in6_addr saddr = {.s6_addr32[0] = 0x000080fe,
85 .s6_addr32[1] = 0x00000000,
86 .s6_addr32[2] = 0xffe9f242,
87 .s6_addr32[3] = 0xe8f66dfe};
88 struct in6_addr daddr = {.s6_addr32[0] = 0x000080fe,
89 .s6_addr32[1] = 0x00000000,
90 .s6_addr32[2] = 0xffd5b372,
91 .s6_addr32[3] = 0x3ef692fe};
92 u16 len = 1460;
93 unsigned short proto = 17;
94 unsigned int head_csum = 0x91f0;
95
96 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
97 ut_asserteq(csum, correct_csum);
98
99 /* Broke a parameter */
100 proto--;
101 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
102 ut_assert(csum != correct_csum);
103
104 return 0;
105}
106DM_TEST(dm_test_csum_ipv6_magic, 0);
Viacheslav Mitrofanovac6a9ce2022-12-02 12:18:11 +0300107
108static int dm_test_ip6_addr_in_subnet(struct unit_test_state *uts)
109{
110 struct in6_addr our = {.s6_addr32[0] = 0x000080fe,
111 .s6_addr32[1] = 0x00000000,
112 .s6_addr32[2] = 0xffe9f242,
113 .s6_addr32[3] = 0xe8f66dfe};
114 struct in6_addr neigh1 = {.s6_addr32[0] = 0x000080fe,
115 .s6_addr32[1] = 0x00000000,
116 .s6_addr32[2] = 0xffd5b372,
117 .s6_addr32[3] = 0x3ef692fe};
118 struct in6_addr neigh2 = {.s6_addr32[0] = 0x60480120,
119 .s6_addr32[1] = 0x00006048,
120 .s6_addr32[2] = 0x00000000,
121 .s6_addr32[3] = 0x00008888};
122
123 /* in */
124 ut_assert(ip6_addr_in_subnet(&our, &neigh1, 64));
125 /* outside */
126 ut_assert(!ip6_addr_in_subnet(&our, &neigh2, 64));
127 ut_assert(!ip6_addr_in_subnet(&our, &neigh1, 128));
128
129 return 0;
130}
131DM_TEST(dm_test_ip6_addr_in_subnet, 0);
Viacheslav Mitrofanov3b673c02022-12-02 12:18:12 +0300132
133static int dm_test_ip6_make_snma(struct unit_test_state *uts)
134{
135 struct in6_addr mult = {0};
136 struct in6_addr correct_addr = {
137 .s6_addr32[0] = 0x000002ff,
138 .s6_addr32[1] = 0x00000000,
139 .s6_addr32[2] = 0x01000000,
140 .s6_addr32[3] = 0xe8f66dff};
141 struct in6_addr addr = { .s6_addr32[0] = 0x000080fe,
142 .s6_addr32[1] = 0x00000000,
143 .s6_addr32[2] = 0xffe9f242,
144 .s6_addr32[3] = 0xe8f66dfe};
145
146 ip6_make_snma(&mult, &addr);
147 ut_asserteq_mem(&mult, &correct_addr, sizeof(struct in6_addr));
148
149 return 0;
150}
151DM_TEST(dm_test_ip6_make_snma, 0);
Viacheslav Mitrofanov5c8e0a62022-12-02 12:18:13 +0300152
153static int dm_test_ip6_make_lladdr(struct unit_test_state *uts)
154{
155 struct in6_addr generated_lladdr = {0};
156 struct in6_addr correct_lladdr = {
157 .s6_addr32[0] = 0x000080fe,
158 .s6_addr32[1] = 0x00000000,
159 .s6_addr32[2] = 0xffabf33a,
160 .s6_addr32[3] = 0xfbb352fe};
161 const unsigned char mac[6] = {0x38, 0xf3, 0xab, 0x52, 0xb3, 0xfb};
162
163 ip6_make_lladdr(&generated_lladdr, mac);
164 ut_asserteq_mem(&generated_lladdr, &correct_lladdr,
165 sizeof(struct in6_addr));
166
167 return 0;
168}
169DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT);
Viacheslav Mitrofanovf96b1092022-12-02 12:18:09 +0300170#endif
171
Joe Hershberger3a77be52015-05-20 14:27:27 -0500172static int dm_test_eth(struct unit_test_state *uts)
Joe Hershberger4c197242015-03-22 17:09:15 -0500173{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500174 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershberger4c197242015-03-22 17:09:15 -0500175
Simon Glass6a38e412017-08-03 12:22:09 -0600176 env_set("ethact", "eth@10002000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500177 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600178 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500179
Simon Glass6a38e412017-08-03 12:22:09 -0600180 env_set("ethact", "eth@10003000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500181 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600182 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500183
Simon Glass6a38e412017-08-03 12:22:09 -0600184 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500185 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600186 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500187
188 return 0;
189}
Simon Glass974dccd2020-07-28 19:41:12 -0600190DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
Joe Hershberger279d2f62015-03-22 17:09:16 -0500191
Joe Hershberger3a77be52015-05-20 14:27:27 -0500192static int dm_test_eth_alias(struct unit_test_state *uts)
Joe Hershberger279d2f62015-03-22 17:09:16 -0500193{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500194 net_ping_ip = string_to_ip("1.1.2.2");
Simon Glass6a38e412017-08-03 12:22:09 -0600195 env_set("ethact", "eth0");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500196 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600197 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500198
Michael Walle7c41a222020-06-02 01:47:09 +0200199 env_set("ethact", "eth6");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500200 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600201 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500202
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800203 /* Expected to fail since eth1 is not defined in the device tree */
204 env_set("ethact", "eth1");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500205 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600206 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500207
Simon Glass6a38e412017-08-03 12:22:09 -0600208 env_set("ethact", "eth5");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500209 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600210 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500211
212 return 0;
213}
Simon Glass974dccd2020-07-28 19:41:12 -0600214DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500215
Joe Hershberger3a77be52015-05-20 14:27:27 -0500216static int dm_test_eth_prime(struct unit_test_state *uts)
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500217{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500218 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500219
220 /* Expected to be "eth@10003000" because of ethprime variable */
Simon Glass6a38e412017-08-03 12:22:09 -0600221 env_set("ethact", NULL);
222 env_set("ethprime", "eth5");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500223 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600224 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500225
226 /* Expected to be "eth@10002000" because it is first */
Simon Glass6a38e412017-08-03 12:22:09 -0600227 env_set("ethact", NULL);
228 env_set("ethprime", NULL);
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500229 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600230 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500231
232 return 0;
233}
Simon Glass974dccd2020-07-28 19:41:12 -0600234DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
Joe Hershbergerf340e542015-03-22 17:09:18 -0500235
Bin Meng111473a2015-10-07 21:45:43 -0700236/**
237 * This test case is trying to test the following scenario:
238 * - All ethernet devices are not probed
239 * - "ethaddr" for all ethernet devices are not set
240 * - "ethact" is set to a valid ethernet device name
241 *
242 * With Sandbox default test configuration, all ethernet devices are
243 * probed after power-up, so we have to manually create such scenario:
244 * - Remove all ethernet devices
245 * - Remove all "ethaddr" environment variables
246 * - Set "ethact" to the first ethernet device
247 *
248 * Do a ping test to see if anything goes wrong.
249 */
250static int dm_test_eth_act(struct unit_test_state *uts)
251{
252 struct udevice *dev[DM_TEST_ETH_NUM];
253 const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
254 "sbe5", "eth@10004000"};
255 const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
Michael Walle7c41a222020-06-02 01:47:09 +0200256 "eth3addr", "eth6addr"};
Bin Meng111473a2015-10-07 21:45:43 -0700257 char ethaddr[DM_TEST_ETH_NUM][18];
258 int i;
259
Tom Rini0ac17d82017-09-26 14:08:30 -0400260 memset(ethaddr, '\0', sizeof(ethaddr));
Bin Meng111473a2015-10-07 21:45:43 -0700261 net_ping_ip = string_to_ip("1.1.2.2");
262
263 /* Prepare the test scenario */
264 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
265 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
266 ethname[i], &dev[i]));
Stefan Roese80b5bc92017-03-20 12:51:48 +0100267 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
Bin Meng111473a2015-10-07 21:45:43 -0700268
269 /* Invalidate MAC address */
Tom Rini0ac17d82017-09-26 14:08:30 -0400270 strncpy(ethaddr[i], env_get(addrname[i]), 17);
Bin Meng111473a2015-10-07 21:45:43 -0700271 /* Must disable access protection for ethaddr before clearing */
Simon Glass6a38e412017-08-03 12:22:09 -0600272 env_set(".flags", addrname[i]);
273 env_set(addrname[i], NULL);
Bin Meng111473a2015-10-07 21:45:43 -0700274 }
275
276 /* Set ethact to "eth@10002000" */
Simon Glass6a38e412017-08-03 12:22:09 -0600277 env_set("ethact", ethname[0]);
Bin Meng111473a2015-10-07 21:45:43 -0700278
279 /* Segment fault might happen if something is wrong */
280 ut_asserteq(-ENODEV, net_loop(PING));
281
282 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
283 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600284 env_set(".flags", addrname[i]);
285 env_set(addrname[i], ethaddr[i]);
Bin Meng111473a2015-10-07 21:45:43 -0700286
287 /* Probe the device again */
288 ut_assertok(device_probe(dev[i]));
289 }
Simon Glass6a38e412017-08-03 12:22:09 -0600290 env_set(".flags", NULL);
291 env_set("ethact", NULL);
Bin Meng111473a2015-10-07 21:45:43 -0700292
293 return 0;
294}
Simon Glass974dccd2020-07-28 19:41:12 -0600295DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
Bin Meng111473a2015-10-07 21:45:43 -0700296
Sean Anderson86f5cc72022-05-05 13:11:32 -0400297/* Ensure that all addresses are loaded properly */
298static int dm_test_ethaddr(struct unit_test_state *uts)
299{
300 static const char *const addr[] = {
301 "02:00:11:22:33:44",
302 "02:00:11:22:33:48", /* dsa slave */
303 "02:00:11:22:33:45",
304 "02:00:11:22:33:48", /* dsa master */
305 "02:00:11:22:33:46",
306 "02:00:11:22:33:47",
307 "02:00:11:22:33:48", /* dsa slave */
308 "02:00:11:22:33:49",
309 };
310 int i;
311
312 for (i = 0; i < ARRAY_SIZE(addr); i++) {
313 char addrname[10];
314
315 if (i)
316 snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
317 else
318 strcpy(addrname, "ethaddr");
319 ut_asserteq_str(addr[i], env_get(addrname));
320 }
321
322 return 0;
323}
324DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
325
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500326/* The asserts include a return on fail; cleanup in the caller */
327static int _dm_test_eth_rotate1(struct unit_test_state *uts)
Joe Hershbergerf340e542015-03-22 17:09:18 -0500328{
Joe Hershbergerf340e542015-03-22 17:09:18 -0500329 /* Make sure that the default is to rotate to the next interface */
Simon Glass6a38e412017-08-03 12:22:09 -0600330 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500331 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600332 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500333
334 /* If ethrotate is no, then we should fail on a bad MAC */
Simon Glass6a38e412017-08-03 12:22:09 -0600335 env_set("ethact", "eth@10004000");
336 env_set("ethrotate", "no");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500337 ut_asserteq(-EINVAL, net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600338 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500339
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500340 return 0;
341}
Joe Hershbergerf340e542015-03-22 17:09:18 -0500342
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500343static int _dm_test_eth_rotate2(struct unit_test_state *uts)
344{
Joe Hershbergerf340e542015-03-22 17:09:18 -0500345 /* Make sure we can skip invalid devices */
Simon Glass6a38e412017-08-03 12:22:09 -0600346 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500347 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600348 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500349
Bin Meng04a11cb2015-08-27 22:25:53 -0700350 /* Make sure we can handle device name which is not eth# */
Simon Glass6a38e412017-08-03 12:22:09 -0600351 env_set("ethact", "sbe5");
Bin Meng04a11cb2015-08-27 22:25:53 -0700352 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600353 ut_asserteq_str("sbe5", env_get("ethact"));
Bin Meng04a11cb2015-08-27 22:25:53 -0700354
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500355 return 0;
356}
357
358static int dm_test_eth_rotate(struct unit_test_state *uts)
359{
360 char ethaddr[18];
361 int retval;
362
363 /* Set target IP to mock ping */
364 net_ping_ip = string_to_ip("1.1.2.2");
365
366 /* Invalidate eth1's MAC address */
Tom Rini0ac17d82017-09-26 14:08:30 -0400367 memset(ethaddr, '\0', sizeof(ethaddr));
Michael Walle7c41a222020-06-02 01:47:09 +0200368 strncpy(ethaddr, env_get("eth6addr"), 17);
369 /* Must disable access protection for eth6addr before clearing */
370 env_set(".flags", "eth6addr");
371 env_set("eth6addr", NULL);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500372
373 retval = _dm_test_eth_rotate1(uts);
374
Joe Hershbergerf340e542015-03-22 17:09:18 -0500375 /* Restore the env */
Michael Walle7c41a222020-06-02 01:47:09 +0200376 env_set("eth6addr", ethaddr);
Simon Glass6a38e412017-08-03 12:22:09 -0600377 env_set("ethrotate", NULL);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500378
379 if (!retval) {
380 /* Invalidate eth0's MAC address */
Tom Rini0ac17d82017-09-26 14:08:30 -0400381 strncpy(ethaddr, env_get("ethaddr"), 17);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500382 /* Must disable access protection for ethaddr before clearing */
Simon Glass6a38e412017-08-03 12:22:09 -0600383 env_set(".flags", "ethaddr");
384 env_set("ethaddr", NULL);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500385
386 retval = _dm_test_eth_rotate2(uts);
387
388 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600389 env_set("ethaddr", ethaddr);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500390 }
391 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600392 env_set(".flags", NULL);
Joe Hershbergerf340e542015-03-22 17:09:18 -0500393
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500394 return retval;
Joe Hershbergerf340e542015-03-22 17:09:18 -0500395}
Simon Glass974dccd2020-07-28 19:41:12 -0600396DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
Joe Hershbergerf933a932015-03-22 17:09:20 -0500397
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500398/* The asserts include a return on fail; cleanup in the caller */
399static int _dm_test_net_retry(struct unit_test_state *uts)
Joe Hershbergerf933a932015-03-22 17:09:20 -0500400{
Joe Hershbergerf933a932015-03-22 17:09:20 -0500401 /*
402 * eth1 is disabled and netretry is yes, so the ping should succeed and
403 * the active device should be eth0
404 */
405 sandbox_eth_disable_response(1, true);
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800406 env_set("ethact", "lan1");
Simon Glass6a38e412017-08-03 12:22:09 -0600407 env_set("netretry", "yes");
Joe Hershberger6901f432015-04-21 13:57:20 -0500408 sandbox_eth_skip_timeout();
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500409 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600410 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerf933a932015-03-22 17:09:20 -0500411
412 /*
413 * eth1 is disabled and netretry is no, so the ping should fail and the
414 * active device should be eth1
415 */
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800416 env_set("ethact", "lan1");
Simon Glass6a38e412017-08-03 12:22:09 -0600417 env_set("netretry", "no");
Joe Hershberger6901f432015-04-21 13:57:20 -0500418 sandbox_eth_skip_timeout();
Thomas RIENOESSL2dee4192018-11-21 15:56:07 +0100419 ut_asserteq(-ENONET, net_loop(PING));
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800420 ut_asserteq_str("lan1", env_get("ethact"));
Joe Hershbergerf933a932015-03-22 17:09:20 -0500421
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500422 return 0;
423}
424
425static int dm_test_net_retry(struct unit_test_state *uts)
426{
427 int retval;
428
429 net_ping_ip = string_to_ip("1.1.2.2");
430
431 retval = _dm_test_net_retry(uts);
432
Joe Hershbergerf933a932015-03-22 17:09:20 -0500433 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600434 env_set("netretry", NULL);
Joe Hershbergerf933a932015-03-22 17:09:20 -0500435 sandbox_eth_disable_response(1, false);
436
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500437 return retval;
Joe Hershbergerf933a932015-03-22 17:09:20 -0500438}
Simon Glass974dccd2020-07-28 19:41:12 -0600439DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
Joe Hershberger54418d02018-09-26 16:49:00 -0500440
441static int sb_check_arp_reply(struct udevice *dev, void *packet,
442 unsigned int len)
443{
444 struct eth_sandbox_priv *priv = dev_get_priv(dev);
445 struct ethernet_hdr *eth = packet;
446 struct arp_hdr *arp;
447 /* Used by all of the ut_assert macros */
448 struct unit_test_state *uts = priv->priv;
449
450 if (ntohs(eth->et_protlen) != PROT_ARP)
451 return 0;
452
453 arp = packet + ETHER_HDR_SIZE;
454
455 if (ntohs(arp->ar_op) != ARPOP_REPLY)
456 return 0;
457
458 /* This test would be worthless if we are not waiting */
459 ut_assert(arp_is_waiting());
460
461 /* Validate response */
Simon Glassa3186e62020-05-10 12:52:45 -0600462 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
463 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger54418d02018-09-26 16:49:00 -0500464 ut_assert(eth->et_protlen == htons(PROT_ARP));
465
466 ut_assert(arp->ar_hrd == htons(ARP_ETHER));
467 ut_assert(arp->ar_pro == htons(PROT_IP));
468 ut_assert(arp->ar_hln == ARP_HLEN);
469 ut_assert(arp->ar_pln == ARP_PLEN);
Simon Glassa3186e62020-05-10 12:52:45 -0600470 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
Joe Hershberger54418d02018-09-26 16:49:00 -0500471 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
Simon Glassa3186e62020-05-10 12:52:45 -0600472 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger54418d02018-09-26 16:49:00 -0500473 ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
474 string_to_ip("1.1.2.4").s_addr);
475
476 return 0;
477}
478
479static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
480 unsigned int len)
481{
482 struct eth_sandbox_priv *priv = dev_get_priv(dev);
483 struct ethernet_hdr *eth = packet;
484 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
485 int ret;
486
487 /*
488 * If we are about to generate a reply to ARP, first inject a request
489 * from another host
490 */
491 if (ntohs(eth->et_protlen) == PROT_ARP &&
492 ntohs(arp->ar_op) == ARPOP_REQUEST) {
493 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
494 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
495
496 ret = sandbox_eth_recv_arp_req(dev);
497 if (ret)
498 return ret;
499 }
500
501 sandbox_eth_arp_req_to_reply(dev, packet, len);
502 sandbox_eth_ping_req_to_reply(dev, packet, len);
503
504 return sb_check_arp_reply(dev, packet, len);
505}
506
507static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
508{
509 net_ping_ip = string_to_ip("1.1.2.2");
510
511 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
512 /* Used by all of the ut_assert macros in the tx_handler */
513 sandbox_eth_set_priv(0, uts);
Joe Hershberger54418d02018-09-26 16:49:00 -0500514
515 env_set("ethact", "eth@10002000");
Joe Hershbergere79a5182018-09-26 16:49:02 -0500516 ut_assertok(net_loop(PING));
Joe Hershberger54418d02018-09-26 16:49:00 -0500517 ut_asserteq_str("eth@10002000", env_get("ethact"));
518
519 sandbox_eth_set_tx_handler(0, NULL);
520
521 return 0;
522}
523
Simon Glass974dccd2020-07-28 19:41:12 -0600524DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500525
526static int sb_check_ping_reply(struct udevice *dev, void *packet,
527 unsigned int len)
528{
529 struct eth_sandbox_priv *priv = dev_get_priv(dev);
530 struct ethernet_hdr *eth = packet;
531 struct ip_udp_hdr *ip;
532 struct icmp_hdr *icmp;
533 /* Used by all of the ut_assert macros */
534 struct unit_test_state *uts = priv->priv;
535
536 if (ntohs(eth->et_protlen) != PROT_IP)
537 return 0;
538
539 ip = packet + ETHER_HDR_SIZE;
540
541 if (ip->ip_p != IPPROTO_ICMP)
542 return 0;
543
544 icmp = (struct icmp_hdr *)&ip->udp_src;
545
546 if (icmp->type != ICMP_ECHO_REPLY)
547 return 0;
548
549 /* This test would be worthless if we are not waiting */
550 ut_assert(arp_is_waiting());
551
552 /* Validate response */
Simon Glassa3186e62020-05-10 12:52:45 -0600553 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
554 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500555 ut_assert(eth->et_protlen == htons(PROT_IP));
556
557 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
558 ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
559 string_to_ip("1.1.2.4").s_addr);
560
561 return 0;
562}
563
564static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
565 unsigned int len)
566{
567 struct eth_sandbox_priv *priv = dev_get_priv(dev);
568 struct ethernet_hdr *eth = packet;
569 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
570 int ret;
571
572 /*
573 * If we are about to generate a reply to ARP, first inject a request
574 * from another host
575 */
576 if (ntohs(eth->et_protlen) == PROT_ARP &&
577 ntohs(arp->ar_op) == ARPOP_REQUEST) {
578 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
579 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
580
581 ret = sandbox_eth_recv_ping_req(dev);
582 if (ret)
583 return ret;
584 }
585
586 sandbox_eth_arp_req_to_reply(dev, packet, len);
587 sandbox_eth_ping_req_to_reply(dev, packet, len);
588
589 return sb_check_ping_reply(dev, packet, len);
590}
591
592static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
593{
594 net_ping_ip = string_to_ip("1.1.2.2");
595
596 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
597 /* Used by all of the ut_assert macros in the tx_handler */
598 sandbox_eth_set_priv(0, uts);
Joe Hershberger9716dc12018-09-26 16:49:01 -0500599
600 env_set("ethact", "eth@10002000");
Joe Hershbergere79a5182018-09-26 16:49:02 -0500601 ut_assertok(net_loop(PING));
Joe Hershberger9716dc12018-09-26 16:49:01 -0500602 ut_asserteq_str("eth@10002000", env_get("ethact"));
603
604 sandbox_eth_set_tx_handler(0, NULL);
605
606 return 0;
607}
608
Simon Glass974dccd2020-07-28 19:41:12 -0600609DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);