Blame view
net/eth_legacy.c
8.21 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
c609719b8 Initial revision |
2 |
/* |
05c3e68f8 dm: eth: Add basi... |
3 |
* (C) Copyright 2001-2015 |
c609719b8 Initial revision |
4 |
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
05c3e68f8 dm: eth: Add basi... |
5 |
* Joe Hershberger, National Instruments |
c609719b8 Initial revision |
6 7 8 9 |
*/ #include <common.h> #include <command.h> |
9fb625ce0 env: Move env_set... |
10 |
#include <env.h> |
c609719b8 Initial revision |
11 |
#include <net.h> |
5f184715e Create PHY Lib fo... |
12 |
#include <phy.h> |
1221ce459 treewide: replace... |
13 |
#include <linux/errno.h> |
3eaac6307 net: introduce pa... |
14 |
#include <net/pcap.h> |
818f91eb5 net: Move common ... |
15 |
#include "eth_internal.h" |
c609719b8 Initial revision |
16 |
|
d2eaec600 net: Remove the b... |
17 |
DECLARE_GLOBAL_DATA_PTR; |
3bc427006 dm: net: Use exis... |
18 19 20 21 22 23 24 25 26 27 |
/* * CPU and board-specific Ethernet initializations. Aliased function * signals caller to move on */ static int __def_eth_init(bd_t *bis) { return -1; } int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init"))); int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init"))); |
f85b60710 Introduce new eth... |
28 |
#ifdef CONFIG_API |
f85b60710 Introduce new eth... |
29 30 31 32 |
static struct { uchar data[PKTSIZE]; int length; } eth_rcv_bufs[PKTBUFSRX]; |
66c7385a5 net: cosmetic: et... |
33 |
static unsigned int eth_rcv_current, eth_rcv_last; |
f85b60710 Introduce new eth... |
34 |
#endif |
f8be7d659 net: Improve the ... |
35 36 |
static struct eth_device *eth_devices; struct eth_device *eth_current; |
c609719b8 Initial revision |
37 |
|
8607a6bf7 net: Move remaini... |
38 |
void eth_set_current_to_next(void) |
84eb1fba7 net: Refactor in ... |
39 40 41 |
{ eth_current = eth_current->next; } |
8607a6bf7 net: Move remaini... |
42 |
void eth_set_dev(struct eth_device *dev) |
e58780dcb dm: eth: Add supp... |
43 44 45 |
{ eth_current = dev; } |
d7fb9bcfb Fix compile warni... |
46 |
struct eth_device *eth_get_dev_by_name(const char *devname) |
63ff004c4 Add support for m... |
47 48 |
{ struct eth_device *dev, *target_dev; |
7e7f903fc net/eth.c: throw ... |
49 |
BUG_ON(devname == NULL); |
63ff004c4 Add support for m... |
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
if (!eth_devices) return NULL; dev = eth_devices; target_dev = NULL; do { if (strcmp(devname, dev->name) == 0) { target_dev = dev; break; } dev = dev->next; } while (dev != eth_devices); return target_dev; } |
9e56986a2 Add eth_get_dev_b... |
65 66 67 |
struct eth_device *eth_get_dev_by_index(int index) { struct eth_device *dev, *target_dev; |
9e56986a2 Add eth_get_dev_b... |
68 69 70 71 72 73 74 |
if (!eth_devices) return NULL; dev = eth_devices; target_dev = NULL; do { |
fea7dcae5 net: introduce pe... |
75 |
if (dev->index == index) { |
9e56986a2 Add eth_get_dev_b... |
76 77 78 79 |
target_dev = dev; break; } dev = dev->next; |
9e56986a2 Add eth_get_dev_b... |
80 81 82 83 |
} while (dev != eth_devices); return target_dev; } |
66c7385a5 net: cosmetic: et... |
84 |
int eth_get_dev_index(void) |
c609719b8 Initial revision |
85 |
{ |
66c7385a5 net: cosmetic: et... |
86 |
if (!eth_current) |
fea7dcae5 net: introduce pe... |
87 |
return -1; |
c609719b8 Initial revision |
88 |
|
fea7dcae5 net: introduce pe... |
89 |
return eth_current->index; |
c609719b8 Initial revision |
90 |
} |
6e0d26c05 net: Handle ethad... |
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
static int on_ethaddr(const char *name, const char *value, enum env_op op, int flags) { int index; struct eth_device *dev; if (!eth_devices) return 0; /* look for an index after "eth" */ index = simple_strtoul(name + 3, NULL, 10); dev = eth_devices; do { if (dev->index == index) { switch (op) { case env_op_create: case env_op_overwrite: |
fb8977c5b net: Always build... |
109 |
string_to_enetaddr(value, dev->enetaddr); |
73d570a76 net: write enetad... |
110 |
eth_write_hwaddr(dev, "eth", dev->index); |
6e0d26c05 net: Handle ethad... |
111 112 |
break; case env_op_delete: |
a40db6d51 net: cosmetic: Do... |
113 |
memset(dev->enetaddr, 0, ARP_HLEN); |
6e0d26c05 net: Handle ethad... |
114 115 |
} } |
7aba0f2c2 net/eth: fix a bu... |
116 |
dev = dev->next; |
6e0d26c05 net: Handle ethad... |
117 118 119 120 121 |
} while (dev != eth_devices); return 0; } U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr); |
7616e7850 Add Ethernet hard... |
122 123 124 |
int eth_write_hwaddr(struct eth_device *dev, const char *base_name, int eth_number) { |
a40db6d51 net: cosmetic: Do... |
125 |
unsigned char env_enetaddr[ARP_HLEN]; |
7616e7850 Add Ethernet hard... |
126 |
int ret = 0; |
35affd7a2 env: Rename eth_g... |
127 |
eth_env_get_enetaddr_by_index(base_name, eth_number, env_enetaddr); |
7616e7850 Add Ethernet hard... |
128 |
|
0adb5b761 net: cosmetic: Na... |
129 130 |
if (!is_zero_ethaddr(env_enetaddr)) { if (!is_zero_ethaddr(dev->enetaddr) && |
a40db6d51 net: cosmetic: Do... |
131 |
memcmp(dev->enetaddr, env_enetaddr, ARP_HLEN)) { |
7616e7850 Add Ethernet hard... |
132 133 134 |
printf(" Warning: %s MAC addresses don't match: ", |
ff819a3a3 net: cosmetic: Fi... |
135 |
dev->name); |
7616e7850 Add Ethernet hard... |
136 137 |
printf("Address in SROM is %pM ", |
ff819a3a3 net: cosmetic: Fi... |
138 |
dev->enetaddr); |
7616e7850 Add Ethernet hard... |
139 140 |
printf("Address in environment is %pM ", |
ff819a3a3 net: cosmetic: Fi... |
141 |
env_enetaddr); |
7616e7850 Add Ethernet hard... |
142 |
} |
a40db6d51 net: cosmetic: Do... |
143 |
memcpy(dev->enetaddr, env_enetaddr, ARP_HLEN); |
0adb5b761 net: cosmetic: Na... |
144 |
} else if (is_valid_ethaddr(dev->enetaddr)) { |
fd1e959e9 env: Rename eth_s... |
145 146 |
eth_env_set_enetaddr_by_index(base_name, eth_number, dev->enetaddr); |
0adb5b761 net: cosmetic: Na... |
147 |
} else if (is_zero_ethaddr(dev->enetaddr)) { |
bef1014b3 net: Implement ra... |
148 149 150 151 152 153 154 |
#ifdef CONFIG_NET_RANDOM_ETHADDR net_random_ethaddr(dev->enetaddr); printf(" Warning: %s (eth%d) using random MAC address - %pM ", dev->name, eth_number, dev->enetaddr); #else |
75d9a45cb Ethernet: let use... |
155 156 157 158 159 |
printf(" Error: %s address not set. ", dev->name); return -EINVAL; |
bef1014b3 net: Implement ra... |
160 |
#endif |
7616e7850 Add Ethernet hard... |
161 |
} |
75d9a45cb Ethernet: let use... |
162 |
if (dev->write_hwaddr && !eth_mac_skip(eth_number)) { |
0adb5b761 net: cosmetic: Na... |
163 |
if (!is_valid_ethaddr(dev->enetaddr)) { |
75d9a45cb Ethernet: let use... |
164 165 166 |
printf(" Error: %s address %pM illegal value ", |
ff819a3a3 net: cosmetic: Fi... |
167 |
dev->name, dev->enetaddr); |
75d9a45cb Ethernet: let use... |
168 169 |
return -EINVAL; } |
460f949f8 net: eth_write_hw... |
170 |
|
7616e7850 Add Ethernet hard... |
171 |
ret = dev->write_hwaddr(dev); |
75d9a45cb Ethernet: let use... |
172 |
if (ret) |
ff819a3a3 net: cosmetic: Fi... |
173 174 175 176 |
printf(" Warning: %s failed to set MAC address ", dev->name); |
460f949f8 net: eth_write_hw... |
177 |
} |
7616e7850 Add Ethernet hard... |
178 179 180 |
return ret; } |
89d48367e Add USB host ethe... |
181 182 183 |
int eth_register(struct eth_device *dev) { struct eth_device *d; |
66c7385a5 net: cosmetic: et... |
184 |
static int index; |
58c583b6c net: Check networ... |
185 |
|
f6add132f net/miiphy/serial... |
186 |
assert(strlen(dev->name) < sizeof(dev->name)); |
58c583b6c net: Check networ... |
187 |
|
89d48367e Add USB host ethe... |
188 |
if (!eth_devices) { |
ff819a3a3 net: cosmetic: Fi... |
189 190 |
eth_devices = dev; eth_current = dev; |
89d48367e Add USB host ethe... |
191 |
eth_current_changed(); |
c609719b8 Initial revision |
192 |
} else { |
66c7385a5 net: cosmetic: et... |
193 |
for (d = eth_devices; d->next != eth_devices; d = d->next) |
aba4b69d0 net: Trivial codi... |
194 |
; |
c609719b8 Initial revision |
195 196 197 198 199 |
d->next = dev; } dev->state = ETH_STATE_INIT; dev->next = eth_devices; |
fea7dcae5 net: introduce pe... |
200 |
dev->index = index++; |
c609719b8 Initial revision |
201 202 203 |
return 0; } |
e7e982d69 eth: remove usb-e... |
204 205 206 207 208 209 |
int eth_unregister(struct eth_device *dev) { struct eth_device *cur; /* No device */ if (!eth_devices) |
05324a488 net: Change retur... |
210 |
return -ENODEV; |
e7e982d69 eth: remove usb-e... |
211 212 213 214 215 216 217 |
for (cur = eth_devices; cur->next != eth_devices && cur->next != dev; cur = cur->next) ; /* Device not found */ if (cur->next != dev) |
05324a488 net: Change retur... |
218 |
return -ENODEV; |
e7e982d69 eth: remove usb-e... |
219 220 221 222 223 224 225 226 227 228 229 230 231 |
cur->next = dev->next; if (eth_devices == dev) eth_devices = dev->next == eth_devices ? NULL : dev->next; if (eth_current == dev) { eth_current = eth_devices; eth_current_changed(); } return 0; } |
d2eaec600 net: Remove the b... |
232 |
int eth_initialize(void) |
c609719b8 Initial revision |
233 |
{ |
fea7dcae5 net: introduce pe... |
234 |
int num_devices = 0; |
3bc427006 dm: net: Use exis... |
235 |
|
c609719b8 Initial revision |
236 237 |
eth_devices = NULL; eth_current = NULL; |
3bc427006 dm: net: Use exis... |
238 |
eth_common_init(); |
818f91eb5 net: Move common ... |
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
/* * If board-specific initialization exists, call it. * If not, call a CPU-specific one */ if (board_eth_init != __def_eth_init) { if (board_eth_init(gd->bd) < 0) printf("Board Net Initialization Failed "); } else if (cpu_eth_init != __def_eth_init) { if (cpu_eth_init(gd->bd) < 0) printf("CPU Net Initialization Failed "); } else { printf("Net Initialization Skipped "); } |
d9785c14b Fix miiphy global... |
255 |
|
c609719b8 Initial revision |
256 |
if (!eth_devices) { |
66c7385a5 net: cosmetic: et... |
257 258 |
puts("No ethernet found. "); |
770605e4f bootstage: Replac... |
259 |
bootstage_error(BOOTSTAGE_ID_NET_ETH_START); |
c609719b8 Initial revision |
260 261 |
} else { struct eth_device *dev = eth_devices; |
00caae6d4 env: Rename geten... |
262 |
char *ethprime = env_get("ethprime"); |
c609719b8 Initial revision |
263 |
|
770605e4f bootstage: Replac... |
264 |
bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT); |
c609719b8 Initial revision |
265 |
do { |
fea7dcae5 net: introduce pe... |
266 |
if (dev->index) |
66c7385a5 net: cosmetic: et... |
267 |
puts(", "); |
c609719b8 Initial revision |
268 269 |
printf("%s", dev->name); |
66c7385a5 net: cosmetic: et... |
270 |
if (ethprime && strcmp(dev->name, ethprime) == 0) { |
c609719b8 Initial revision |
271 |
eth_current = dev; |
66c7385a5 net: cosmetic: et... |
272 |
puts(" [PRIME]"); |
c609719b8 Initial revision |
273 |
} |
1384f3bb8 net: warn about s... |
274 |
if (strchr(dev->name, ' ')) |
66c7385a5 net: cosmetic: et... |
275 276 277 278 |
puts(" Warning: eth device name has a space!" " "); |
1384f3bb8 net: warn about s... |
279 |
|
75d9a45cb Ethernet: let use... |
280 |
eth_write_hwaddr(dev, "eth", dev->index); |
c609719b8 Initial revision |
281 |
|
c609719b8 Initial revision |
282 |
dev = dev->next; |
fea7dcae5 net: introduce pe... |
283 |
num_devices++; |
66c7385a5 net: cosmetic: et... |
284 |
} while (dev != eth_devices); |
c609719b8 Initial revision |
285 |
|
89d48367e Add USB host ethe... |
286 |
eth_current_changed(); |
66c7385a5 net: cosmetic: et... |
287 288 |
putc(' '); |
c609719b8 Initial revision |
289 |
} |
fea7dcae5 net: introduce pe... |
290 |
return num_devices; |
c609719b8 Initial revision |
291 |
} |
53a5c424b multicast tftp: R... |
292 293 |
/* Multicast. * mcast_addr: multicast ipaddr from which multicast Mac is made |
85eb5caf6 Coding style clea... |
294 |
* join: 1=join, 0=leave. |
53a5c424b multicast tftp: R... |
295 |
*/ |
049a95a77 net: cosmetic: Ch... |
296 |
int eth_mcast_join(struct in_addr mcast_ip, int join) |
53a5c424b multicast tftp: R... |
297 |
{ |
a40db6d51 net: cosmetic: Do... |
298 |
u8 mcast_mac[ARP_HLEN]; |
85eb5caf6 Coding style clea... |
299 |
if (!eth_current || !eth_current->mcast) |
53a5c424b multicast tftp: R... |
300 |
return -1; |
049a95a77 net: cosmetic: Ch... |
301 302 303 |
mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff; mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff; mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f; |
53a5c424b multicast tftp: R... |
304 305 306 307 308 |
mcast_mac[2] = 0x5e; mcast_mac[1] = 0x0; mcast_mac[0] = 0x1; return eth_current->mcast(eth_current, mcast_mac, join); } |
d2eaec600 net: Remove the b... |
309 |
int eth_init(void) |
c609719b8 Initial revision |
310 |
{ |
6e0d26c05 net: Handle ethad... |
311 |
struct eth_device *old_current; |
c609719b8 Initial revision |
312 |
|
6bc113886 net: Print error ... |
313 |
if (!eth_current) { |
66c7385a5 net: cosmetic: et... |
314 315 |
puts("No ethernet found. "); |
05324a488 net: Change retur... |
316 |
return -ENODEV; |
6bc113886 net: Print error ... |
317 |
} |
c609719b8 Initial revision |
318 319 320 |
old_current = eth_current; do { |
0ebf04c60 minor debug clean... |
321 322 |
debug("Trying %s ", eth_current->name); |
c609719b8 Initial revision |
323 |
|
d2eaec600 net: Remove the b... |
324 |
if (eth_current->init(eth_current, gd->bd) >= 0) { |
c609719b8 Initial revision |
325 |
eth_current->state = ETH_STATE_ACTIVE; |
505be87a6 NET: Proper retur... |
326 |
return 0; |
c609719b8 Initial revision |
327 |
} |
0ebf04c60 minor debug clean... |
328 329 |
debug("FAIL "); |
c609719b8 Initial revision |
330 331 332 |
eth_try_another(0); } while (old_current != eth_current); |
05324a488 net: Change retur... |
333 |
return -ETIMEDOUT; |
c609719b8 Initial revision |
334 335 336 337 338 339 340 341 342 343 344 |
} void eth_halt(void) { if (!eth_current) return; eth_current->halt(eth_current); eth_current->state = ETH_STATE_PASSIVE; } |
eaa8a195c net: expose eth_i... |
345 346 347 348 |
int eth_is_active(struct eth_device *dev) { return dev && dev->state == ETH_STATE_ACTIVE; } |
db288a960 net: Remove volat... |
349 |
int eth_send(void *packet, int length) |
c609719b8 Initial revision |
350 |
{ |
3eaac6307 net: introduce pa... |
351 |
int ret; |
c609719b8 Initial revision |
352 |
if (!eth_current) |
05324a488 net: Change retur... |
353 |
return -ENODEV; |
c609719b8 Initial revision |
354 |
|
3eaac6307 net: introduce pa... |
355 356 357 358 359 360 |
ret = eth_current->send(eth_current, packet, length); #if defined(CONFIG_CMD_PCAP) if (ret >= 0) pcap_post(packet, lengeth, true); #endif return ret; |
c609719b8 Initial revision |
361 362 363 364 365 |
} int eth_rx(void) { if (!eth_current) |
05324a488 net: Change retur... |
366 |
return -ENODEV; |
c609719b8 Initial revision |
367 368 369 |
return eth_current->recv(eth_current); } |
f85b60710 Introduce new eth... |
370 |
#ifdef CONFIG_API |
db288a960 net: Remove volat... |
371 |
static void eth_save_packet(void *packet, int length) |
f85b60710 Introduce new eth... |
372 |
{ |
db288a960 net: Remove volat... |
373 |
char *p = packet; |
f85b60710 Introduce new eth... |
374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
int i; if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current) return; if (PKTSIZE < length) return; for (i = 0; i < length; i++) eth_rcv_bufs[eth_rcv_last].data[i] = p[i]; eth_rcv_bufs[eth_rcv_last].length = length; eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX; } |
db288a960 net: Remove volat... |
388 |
int eth_receive(void *packet, int length) |
f85b60710 Introduce new eth... |
389 |
{ |
db288a960 net: Remove volat... |
390 |
char *p = packet; |
f85b60710 Introduce new eth... |
391 392 393 394 395 396 397 398 399 400 401 |
void *pp = push_packet; int i; if (eth_rcv_current == eth_rcv_last) { push_packet = eth_save_packet; eth_rx(); push_packet = pp; if (eth_rcv_current == eth_rcv_last) return -1; } |
46c07bcf1 api: net: fix len... |
402 |
length = min(eth_rcv_bufs[eth_rcv_current].length, length); |
f85b60710 Introduce new eth... |
403 404 405 406 407 408 409 410 |
for (i = 0; i < length; i++) p[i] = eth_rcv_bufs[eth_rcv_current].data[i]; eth_rcv_current = (eth_rcv_current + 1) % PKTBUFSRX; return length; } #endif /* CONFIG_API */ |