1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2001-2015 4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 5 * Joe Hershberger, National Instruments 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <environment.h> 11 #include <miiphy.h> 12 #include <net.h> 13 #include "eth_internal.h" 14 15 int eth_env_get_enetaddr_by_index(const char *base_name, int index, 16 uchar *enetaddr) 17 { 18 char enetvar[32]; 19 sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index); 20 return eth_env_get_enetaddr(enetvar, enetaddr); 21 } 22 23 int eth_env_set_enetaddr_by_index(const char *base_name, int index, 24 uchar *enetaddr) 25 { 26 char enetvar[32]; 27 sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index); 28 return eth_env_set_enetaddr(enetvar, enetaddr); 29 } 30 31 void eth_common_init(void) 32 { 33 bootstage_mark(BOOTSTAGE_ID_NET_ETH_START); 34 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) 35 miiphy_init(); 36 #endif 37 38 #ifdef CONFIG_PHYLIB 39 phy_init(); 40 #endif 41 } 42 43 int eth_mac_skip(int index) 44 { 45 char enetvar[15]; 46 char *skip_state; 47 48 sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index); 49 skip_state = env_get(enetvar); 50 return skip_state != NULL; 51 } 52 53 void eth_current_changed(void) 54 { 55 char *act = env_get("ethact"); 56 char *ethrotate; 57 58 /* 59 * The call to eth_get_dev() below has a side effect of rotating 60 * ethernet device if uc_priv->current == NULL. This is not what 61 * we want when 'ethrotate' variable is 'no'. 62 */ 63 ethrotate = env_get("ethrotate"); 64 if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) 65 return; 66 67 /* update current ethernet name */ 68 if (eth_get_dev()) { 69 if (act == NULL || strcmp(act, eth_get_name()) != 0) 70 env_set("ethact", eth_get_name()); 71 } 72 /* 73 * remove the variable completely if there is no active 74 * interface 75 */ 76 else if (act != NULL) 77 env_set("ethact", NULL); 78 } 79 80 void eth_try_another(int first_restart) 81 { 82 static void *first_failed; 83 char *ethrotate; 84 85 /* 86 * Do not rotate between network interfaces when 87 * 'ethrotate' variable is set to 'no'. 88 */ 89 ethrotate = env_get("ethrotate"); 90 if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) 91 return; 92 93 if (!eth_get_dev()) 94 return; 95 96 if (first_restart) 97 first_failed = eth_get_dev(); 98 99 eth_set_current_to_next(); 100 101 eth_current_changed(); 102 103 if (first_failed == eth_get_dev()) 104 net_restart_wrap = 1; 105 } 106 107 void eth_set_current(void) 108 { 109 static char *act; 110 static int env_changed_id; 111 int env_id; 112 113 env_id = get_env_id(); 114 if ((act == NULL) || (env_changed_id != env_id)) { 115 act = env_get("ethact"); 116 env_changed_id = env_id; 117 } 118 119 if (act == NULL) { 120 char *ethprime = env_get("ethprime"); 121 void *dev = NULL; 122 123 if (ethprime) 124 dev = eth_get_dev_by_name(ethprime); 125 if (dev) 126 eth_set_dev(dev); 127 else 128 eth_set_dev(NULL); 129 } else { 130 eth_set_dev(eth_get_dev_by_name(act)); 131 } 132 133 eth_current_changed(); 134 } 135 136 const char *eth_get_name(void) 137 { 138 return eth_get_dev() ? eth_get_dev()->name : "unknown"; 139 } 140