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