uboot/test/dm/eth.c
<<
>>
Prefs
   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
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23#define DM_TEST_ETH_NUM         4
  24
  25static int dm_test_eth(struct unit_test_state *uts)
  26{
  27        net_ping_ip = string_to_ip("1.1.2.2");
  28
  29        env_set("ethact", "eth@10002000");
  30        ut_assertok(net_loop(PING));
  31        ut_asserteq_str("eth@10002000", env_get("ethact"));
  32
  33        env_set("ethact", "eth@10003000");
  34        ut_assertok(net_loop(PING));
  35        ut_asserteq_str("eth@10003000", env_get("ethact"));
  36
  37        env_set("ethact", "eth@10004000");
  38        ut_assertok(net_loop(PING));
  39        ut_asserteq_str("eth@10004000", env_get("ethact"));
  40
  41        return 0;
  42}
  43DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
  44
  45static int dm_test_eth_alias(struct unit_test_state *uts)
  46{
  47        net_ping_ip = string_to_ip("1.1.2.2");
  48        env_set("ethact", "eth0");
  49        ut_assertok(net_loop(PING));
  50        ut_asserteq_str("eth@10002000", env_get("ethact"));
  51
  52        env_set("ethact", "eth1");
  53        ut_assertok(net_loop(PING));
  54        ut_asserteq_str("eth@10004000", env_get("ethact"));
  55
  56        /* Expected to fail since eth2 is not defined in the device tree */
  57        env_set("ethact", "eth2");
  58        ut_assertok(net_loop(PING));
  59        ut_asserteq_str("eth@10002000", env_get("ethact"));
  60
  61        env_set("ethact", "eth5");
  62        ut_assertok(net_loop(PING));
  63        ut_asserteq_str("eth@10003000", env_get("ethact"));
  64
  65        return 0;
  66}
  67DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
  68
  69static 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        env_set("ethact", NULL);
  75        env_set("ethprime", "eth5");
  76        ut_assertok(net_loop(PING));
  77        ut_asserteq_str("eth@10003000", env_get("ethact"));
  78
  79        /* Expected to be "eth@10002000" because it is first */
  80        env_set("ethact", NULL);
  81        env_set("ethprime", NULL);
  82        ut_assertok(net_loop(PING));
  83        ut_asserteq_str("eth@10002000", env_get("ethact"));
  84
  85        return 0;
  86}
  87DM_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 */
 103static 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        memset(ethaddr, '\0', sizeof(ethaddr));
 114        net_ping_ip = string_to_ip("1.1.2.2");
 115
 116        /* Prepare the test scenario */
 117        for (i = 0; i < DM_TEST_ETH_NUM; i++) {
 118                ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
 119                                                       ethname[i], &dev[i]));
 120                ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
 121
 122                /* Invalidate MAC address */
 123                strncpy(ethaddr[i], env_get(addrname[i]), 17);
 124                /* Must disable access protection for ethaddr before clearing */
 125                env_set(".flags", addrname[i]);
 126                env_set(addrname[i], NULL);
 127        }
 128
 129        /* Set ethact to "eth@10002000" */
 130        env_set("ethact", ethname[0]);
 131
 132        /* Segment fault might happen if something is wrong */
 133        ut_asserteq(-ENODEV, net_loop(PING));
 134
 135        for (i = 0; i < DM_TEST_ETH_NUM; i++) {
 136                /* Restore the env */
 137                env_set(".flags", addrname[i]);
 138                env_set(addrname[i], ethaddr[i]);
 139
 140                /* Probe the device again */
 141                ut_assertok(device_probe(dev[i]));
 142        }
 143        env_set(".flags", NULL);
 144        env_set("ethact", NULL);
 145
 146        return 0;
 147}
 148DM_TEST(dm_test_eth_act, DM_TESTF_SCAN_FDT);
 149
 150/* The asserts include a return on fail; cleanup in the caller */
 151static int _dm_test_eth_rotate1(struct unit_test_state *uts)
 152{
 153        /* Make sure that the default is to rotate to the next interface */
 154        env_set("ethact", "eth@10004000");
 155        ut_assertok(net_loop(PING));
 156        ut_asserteq_str("eth@10002000", env_get("ethact"));
 157
 158        /* If ethrotate is no, then we should fail on a bad MAC */
 159        env_set("ethact", "eth@10004000");
 160        env_set("ethrotate", "no");
 161        ut_asserteq(-EINVAL, net_loop(PING));
 162        ut_asserteq_str("eth@10004000", env_get("ethact"));
 163
 164        return 0;
 165}
 166
 167static int _dm_test_eth_rotate2(struct unit_test_state *uts)
 168{
 169        /* Make sure we can skip invalid devices */
 170        env_set("ethact", "eth@10004000");
 171        ut_assertok(net_loop(PING));
 172        ut_asserteq_str("eth@10004000", env_get("ethact"));
 173
 174        /* Make sure we can handle device name which is not eth# */
 175        env_set("ethact", "sbe5");
 176        ut_assertok(net_loop(PING));
 177        ut_asserteq_str("sbe5", env_get("ethact"));
 178
 179        return 0;
 180}
 181
 182static int dm_test_eth_rotate(struct unit_test_state *uts)
 183{
 184        char ethaddr[18];
 185        int retval;
 186
 187        /* Set target IP to mock ping */
 188        net_ping_ip = string_to_ip("1.1.2.2");
 189
 190        /* Invalidate eth1's MAC address */
 191        memset(ethaddr, '\0', sizeof(ethaddr));
 192        strncpy(ethaddr, env_get("eth1addr"), 17);
 193        /* Must disable access protection for eth1addr before clearing */
 194        env_set(".flags", "eth1addr");
 195        env_set("eth1addr", NULL);
 196
 197        retval = _dm_test_eth_rotate1(uts);
 198
 199        /* Restore the env */
 200        env_set("eth1addr", ethaddr);
 201        env_set("ethrotate", NULL);
 202
 203        if (!retval) {
 204                /* Invalidate eth0's MAC address */
 205                strncpy(ethaddr, env_get("ethaddr"), 17);
 206                /* Must disable access protection for ethaddr before clearing */
 207                env_set(".flags", "ethaddr");
 208                env_set("ethaddr", NULL);
 209
 210                retval = _dm_test_eth_rotate2(uts);
 211
 212                /* Restore the env */
 213                env_set("ethaddr", ethaddr);
 214        }
 215        /* Restore the env */
 216        env_set(".flags", NULL);
 217
 218        return retval;
 219}
 220DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT);
 221
 222/* The asserts include a return on fail; cleanup in the caller */
 223static int _dm_test_net_retry(struct unit_test_state *uts)
 224{
 225        /*
 226         * eth1 is disabled and netretry is yes, so the ping should succeed and
 227         * the active device should be eth0
 228         */
 229        sandbox_eth_disable_response(1, true);
 230        env_set("ethact", "eth@10004000");
 231        env_set("netretry", "yes");
 232        sandbox_eth_skip_timeout();
 233        ut_assertok(net_loop(PING));
 234        ut_asserteq_str("eth@10002000", env_get("ethact"));
 235
 236        /*
 237         * eth1 is disabled and netretry is no, so the ping should fail and the
 238         * active device should be eth1
 239         */
 240        env_set("ethact", "eth@10004000");
 241        env_set("netretry", "no");
 242        sandbox_eth_skip_timeout();
 243        ut_asserteq(-ETIMEDOUT, net_loop(PING));
 244        ut_asserteq_str("eth@10004000", env_get("ethact"));
 245
 246        return 0;
 247}
 248
 249static int dm_test_net_retry(struct unit_test_state *uts)
 250{
 251        int retval;
 252
 253        net_ping_ip = string_to_ip("1.1.2.2");
 254
 255        retval = _dm_test_net_retry(uts);
 256
 257        /* Restore the env */
 258        env_set("netretry", NULL);
 259        sandbox_eth_disable_response(1, false);
 260
 261        return retval;
 262}
 263DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
 264