eth.c 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. /*
  2. * (C) Copyright 2001-2015
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. * Joe Hershberger, National Instruments
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <dm.h>
  11. #include <net.h>
  12. #include <miiphy.h>
  13. #include <phy.h>
  14. #include <asm/errno.h>
  15. #include <dm/device-internal.h>
  16. DECLARE_GLOBAL_DATA_PTR;
  17. void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
  18. {
  19. char *end;
  20. int i;
  21. for (i = 0; i < 6; ++i) {
  22. enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
  23. if (addr)
  24. addr = (*end) ? end + 1 : end;
  25. }
  26. }
  27. int eth_getenv_enetaddr(char *name, uchar *enetaddr)
  28. {
  29. eth_parse_enetaddr(getenv(name), enetaddr);
  30. return is_valid_ethaddr(enetaddr);
  31. }
  32. int eth_setenv_enetaddr(char *name, const uchar *enetaddr)
  33. {
  34. char buf[20];
  35. sprintf(buf, "%pM", enetaddr);
  36. return setenv(name, buf);
  37. }
  38. int eth_getenv_enetaddr_by_index(const char *base_name, int index,
  39. uchar *enetaddr)
  40. {
  41. char enetvar[32];
  42. sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
  43. return eth_getenv_enetaddr(enetvar, enetaddr);
  44. }
  45. static inline int eth_setenv_enetaddr_by_index(const char *base_name, int index,
  46. uchar *enetaddr)
  47. {
  48. char enetvar[32];
  49. sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
  50. return eth_setenv_enetaddr(enetvar, enetaddr);
  51. }
  52. static void eth_env_init(void)
  53. {
  54. const char *s;
  55. s = getenv("bootfile");
  56. if (s != NULL)
  57. copy_filename(net_boot_file_name, s,
  58. sizeof(net_boot_file_name));
  59. }
  60. static int eth_mac_skip(int index)
  61. {
  62. char enetvar[15];
  63. char *skip_state;
  64. sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
  65. skip_state = getenv(enetvar);
  66. return skip_state != NULL;
  67. }
  68. static void eth_current_changed(void);
  69. #ifdef CONFIG_DM_ETH
  70. /**
  71. * struct eth_device_priv - private structure for each Ethernet device
  72. *
  73. * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t)
  74. */
  75. struct eth_device_priv {
  76. enum eth_state_t state;
  77. };
  78. /**
  79. * struct eth_uclass_priv - The structure attached to the uclass itself
  80. *
  81. * @current: The Ethernet device that the network functions are using
  82. */
  83. struct eth_uclass_priv {
  84. struct udevice *current;
  85. };
  86. /* eth_errno - This stores the most recent failure code from DM functions */
  87. static int eth_errno;
  88. static struct eth_uclass_priv *eth_get_uclass_priv(void)
  89. {
  90. struct uclass *uc;
  91. uclass_get(UCLASS_ETH, &uc);
  92. assert(uc);
  93. return uc->priv;
  94. }
  95. static void eth_set_current_to_next(void)
  96. {
  97. struct eth_uclass_priv *uc_priv;
  98. uc_priv = eth_get_uclass_priv();
  99. if (uc_priv->current)
  100. uclass_next_device(&uc_priv->current);
  101. if (!uc_priv->current)
  102. uclass_first_device(UCLASS_ETH, &uc_priv->current);
  103. }
  104. /*
  105. * Typically this will simply return the active device.
  106. * In the case where the most recent active device was unset, this will attempt
  107. * to return the first device. If that device doesn't exist or fails to probe,
  108. * this function will return NULL.
  109. */
  110. struct udevice *eth_get_dev(void)
  111. {
  112. struct eth_uclass_priv *uc_priv;
  113. uc_priv = eth_get_uclass_priv();
  114. if (!uc_priv->current)
  115. eth_errno = uclass_first_device(UCLASS_ETH,
  116. &uc_priv->current);
  117. return uc_priv->current;
  118. }
  119. /*
  120. * Typically this will just store a device pointer.
  121. * In case it was not probed, we will attempt to do so.
  122. * dev may be NULL to unset the active device.
  123. */
  124. static void eth_set_dev(struct udevice *dev)
  125. {
  126. if (dev && !device_active(dev))
  127. eth_errno = device_probe(dev);
  128. eth_get_uclass_priv()->current = dev;
  129. }
  130. /*
  131. * Find the udevice that either has the name passed in as devname or has an
  132. * alias named devname.
  133. */
  134. struct udevice *eth_get_dev_by_name(const char *devname)
  135. {
  136. int seq = -1;
  137. char *endp = NULL;
  138. const char *startp = NULL;
  139. struct udevice *it;
  140. struct uclass *uc;
  141. /* Must be longer than 3 to be an alias */
  142. if (strlen(devname) > strlen("eth")) {
  143. startp = devname + strlen("eth");
  144. seq = simple_strtoul(startp, &endp, 10);
  145. }
  146. uclass_get(UCLASS_ETH, &uc);
  147. uclass_foreach_dev(it, uc) {
  148. /*
  149. * We need the seq to be valid, so try to probe it.
  150. * If the probe fails, the seq will not match since it will be
  151. * -1 instead of what we are looking for.
  152. * We don't care about errors from probe here. Either they won't
  153. * match an alias or it will match a literal name and we'll pick
  154. * up the error when we try to probe again in eth_set_dev().
  155. */
  156. device_probe(it);
  157. /*
  158. * Check for the name or the sequence number to match
  159. */
  160. if (strcmp(it->name, devname) == 0 ||
  161. (endp > startp && it->seq == seq))
  162. return it;
  163. }
  164. return NULL;
  165. }
  166. unsigned char *eth_get_ethaddr(void)
  167. {
  168. struct eth_pdata *pdata;
  169. if (eth_get_dev()) {
  170. pdata = eth_get_dev()->platdata;
  171. return pdata->enetaddr;
  172. }
  173. return NULL;
  174. }
  175. /* Set active state without calling start on the driver */
  176. int eth_init_state_only(void)
  177. {
  178. struct udevice *current;
  179. struct eth_device_priv *priv;
  180. current = eth_get_dev();
  181. if (!current || !device_active(current))
  182. return -EINVAL;
  183. priv = current->uclass_priv;
  184. priv->state = ETH_STATE_ACTIVE;
  185. return 0;
  186. }
  187. /* Set passive state without calling stop on the driver */
  188. void eth_halt_state_only(void)
  189. {
  190. struct udevice *current;
  191. struct eth_device_priv *priv;
  192. current = eth_get_dev();
  193. if (!current || !device_active(current))
  194. return;
  195. priv = current->uclass_priv;
  196. priv->state = ETH_STATE_PASSIVE;
  197. }
  198. int eth_get_dev_index(void)
  199. {
  200. if (eth_get_dev())
  201. return eth_get_dev()->seq;
  202. return -1;
  203. }
  204. int eth_init(void)
  205. {
  206. struct udevice *current;
  207. struct udevice *old_current;
  208. int ret = -ENODEV;
  209. current = eth_get_dev();
  210. if (!current) {
  211. printf("No ethernet found.\n");
  212. return -ENODEV;
  213. }
  214. old_current = current;
  215. do {
  216. debug("Trying %s\n", current->name);
  217. if (device_active(current)) {
  218. uchar env_enetaddr[6];
  219. struct eth_pdata *pdata = current->platdata;
  220. /* Sync environment with network device */
  221. if (eth_getenv_enetaddr_by_index("eth", current->seq,
  222. env_enetaddr))
  223. memcpy(pdata->enetaddr, env_enetaddr, 6);
  224. else
  225. memset(pdata->enetaddr, 0, 6);
  226. ret = eth_get_ops(current)->start(current);
  227. if (ret >= 0) {
  228. struct eth_device_priv *priv =
  229. current->uclass_priv;
  230. priv->state = ETH_STATE_ACTIVE;
  231. return 0;
  232. }
  233. } else {
  234. ret = eth_errno;
  235. }
  236. debug("FAIL\n");
  237. /*
  238. * If ethrotate is enabled, this will change "current",
  239. * otherwise we will drop out of this while loop immediately
  240. */
  241. eth_try_another(0);
  242. /* This will ensure the new "current" attempted to probe */
  243. current = eth_get_dev();
  244. } while (old_current != current);
  245. return ret;
  246. }
  247. void eth_halt(void)
  248. {
  249. struct udevice *current;
  250. struct eth_device_priv *priv;
  251. current = eth_get_dev();
  252. if (!current || !device_active(current))
  253. return;
  254. eth_get_ops(current)->stop(current);
  255. priv = current->uclass_priv;
  256. priv->state = ETH_STATE_PASSIVE;
  257. }
  258. int eth_send(void *packet, int length)
  259. {
  260. struct udevice *current;
  261. int ret;
  262. current = eth_get_dev();
  263. if (!current)
  264. return -ENODEV;
  265. if (!device_active(current))
  266. return -EINVAL;
  267. ret = eth_get_ops(current)->send(current, packet, length);
  268. if (ret < 0) {
  269. /* We cannot completely return the error at present */
  270. debug("%s: send() returned error %d\n", __func__, ret);
  271. }
  272. return ret;
  273. }
  274. int eth_rx(void)
  275. {
  276. struct udevice *current;
  277. uchar *packet;
  278. int ret;
  279. int i;
  280. current = eth_get_dev();
  281. if (!current)
  282. return -ENODEV;
  283. if (!device_active(current))
  284. return -EINVAL;
  285. /* Process up to 32 packets at one time */
  286. for (i = 0; i < 32; i++) {
  287. ret = eth_get_ops(current)->recv(current, &packet);
  288. if (ret > 0)
  289. net_process_received_packet(packet, ret);
  290. if (ret >= 0 && eth_get_ops(current)->free_pkt)
  291. eth_get_ops(current)->free_pkt(current, packet, ret);
  292. if (ret <= 0)
  293. break;
  294. }
  295. if (ret == -EAGAIN)
  296. ret = 0;
  297. if (ret < 0) {
  298. /* We cannot completely return the error at present */
  299. debug("%s: recv() returned error %d\n", __func__, ret);
  300. }
  301. return ret;
  302. }
  303. static int eth_write_hwaddr(struct udevice *dev)
  304. {
  305. struct eth_pdata *pdata = dev->platdata;
  306. int ret = 0;
  307. if (!dev || !device_active(dev))
  308. return -EINVAL;
  309. /* seq is valid since the device is active */
  310. if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
  311. if (!is_valid_ethaddr(pdata->enetaddr)) {
  312. printf("\nError: %s address %pM illegal value\n",
  313. dev->name, pdata->enetaddr);
  314. return -EINVAL;
  315. }
  316. ret = eth_get_ops(dev)->write_hwaddr(dev);
  317. if (ret)
  318. printf("\nWarning: %s failed to set MAC address\n",
  319. dev->name);
  320. }
  321. return ret;
  322. }
  323. int eth_initialize(void)
  324. {
  325. int num_devices = 0;
  326. struct udevice *dev;
  327. bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
  328. eth_env_init();
  329. /*
  330. * Devices need to write the hwaddr even if not started so that Linux
  331. * will have access to the hwaddr that u-boot stored for the device.
  332. * This is accomplished by attempting to probe each device and calling
  333. * their write_hwaddr() operation.
  334. */
  335. uclass_first_device(UCLASS_ETH, &dev);
  336. if (!dev) {
  337. printf("No ethernet found.\n");
  338. bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
  339. } else {
  340. char *ethprime = getenv("ethprime");
  341. struct udevice *prime_dev = NULL;
  342. if (ethprime)
  343. prime_dev = eth_get_dev_by_name(ethprime);
  344. if (prime_dev) {
  345. eth_set_dev(prime_dev);
  346. eth_current_changed();
  347. } else {
  348. eth_set_dev(NULL);
  349. }
  350. bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
  351. do {
  352. if (num_devices)
  353. printf(", ");
  354. printf("eth%d: %s", dev->seq, dev->name);
  355. if (ethprime && dev == prime_dev)
  356. printf(" [PRIME]");
  357. eth_write_hwaddr(dev);
  358. uclass_next_device(&dev);
  359. num_devices++;
  360. } while (dev);
  361. putc('\n');
  362. }
  363. return num_devices;
  364. }
  365. static int eth_post_bind(struct udevice *dev)
  366. {
  367. if (strchr(dev->name, ' ')) {
  368. printf("\nError: eth device name \"%s\" has a space!\n",
  369. dev->name);
  370. return -EINVAL;
  371. }
  372. return 0;
  373. }
  374. static int eth_pre_unbind(struct udevice *dev)
  375. {
  376. /* Don't hang onto a pointer that is going away */
  377. if (dev == eth_get_uclass_priv()->current)
  378. eth_set_dev(NULL);
  379. return 0;
  380. }
  381. static int eth_post_probe(struct udevice *dev)
  382. {
  383. struct eth_device_priv *priv = dev->uclass_priv;
  384. struct eth_pdata *pdata = dev->platdata;
  385. unsigned char env_enetaddr[6];
  386. priv->state = ETH_STATE_INIT;
  387. /* Check if the device has a MAC address in ROM */
  388. if (eth_get_ops(dev)->read_rom_hwaddr)
  389. eth_get_ops(dev)->read_rom_hwaddr(dev);
  390. eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr);
  391. if (!is_zero_ethaddr(env_enetaddr)) {
  392. if (!is_zero_ethaddr(pdata->enetaddr) &&
  393. memcmp(pdata->enetaddr, env_enetaddr, 6)) {
  394. printf("\nWarning: %s MAC addresses don't match:\n",
  395. dev->name);
  396. printf("Address in SROM is %pM\n",
  397. pdata->enetaddr);
  398. printf("Address in environment is %pM\n",
  399. env_enetaddr);
  400. }
  401. /* Override the ROM MAC address */
  402. memcpy(pdata->enetaddr, env_enetaddr, 6);
  403. } else if (is_valid_ethaddr(pdata->enetaddr)) {
  404. eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
  405. printf("\nWarning: %s using MAC address from ROM\n",
  406. dev->name);
  407. } else if (is_zero_ethaddr(pdata->enetaddr)) {
  408. printf("\nError: %s address not set.\n",
  409. dev->name);
  410. return -EINVAL;
  411. }
  412. return 0;
  413. }
  414. static int eth_pre_remove(struct udevice *dev)
  415. {
  416. eth_get_ops(dev)->stop(dev);
  417. return 0;
  418. }
  419. UCLASS_DRIVER(eth) = {
  420. .name = "eth",
  421. .id = UCLASS_ETH,
  422. .post_bind = eth_post_bind,
  423. .pre_unbind = eth_pre_unbind,
  424. .post_probe = eth_post_probe,
  425. .pre_remove = eth_pre_remove,
  426. .priv_auto_alloc_size = sizeof(struct eth_uclass_priv),
  427. .per_device_auto_alloc_size = sizeof(struct eth_device_priv),
  428. .flags = DM_UC_FLAG_SEQ_ALIAS,
  429. };
  430. #endif
  431. #ifndef CONFIG_DM_ETH
  432. /*
  433. * CPU and board-specific Ethernet initializations. Aliased function
  434. * signals caller to move on
  435. */
  436. static int __def_eth_init(bd_t *bis)
  437. {
  438. return -1;
  439. }
  440. int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
  441. int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
  442. #ifdef CONFIG_API
  443. static struct {
  444. uchar data[PKTSIZE];
  445. int length;
  446. } eth_rcv_bufs[PKTBUFSRX];
  447. static unsigned int eth_rcv_current, eth_rcv_last;
  448. #endif
  449. static struct eth_device *eth_devices;
  450. struct eth_device *eth_current;
  451. static void eth_set_current_to_next(void)
  452. {
  453. eth_current = eth_current->next;
  454. }
  455. static void eth_set_dev(struct eth_device *dev)
  456. {
  457. eth_current = dev;
  458. }
  459. struct eth_device *eth_get_dev_by_name(const char *devname)
  460. {
  461. struct eth_device *dev, *target_dev;
  462. BUG_ON(devname == NULL);
  463. if (!eth_devices)
  464. return NULL;
  465. dev = eth_devices;
  466. target_dev = NULL;
  467. do {
  468. if (strcmp(devname, dev->name) == 0) {
  469. target_dev = dev;
  470. break;
  471. }
  472. dev = dev->next;
  473. } while (dev != eth_devices);
  474. return target_dev;
  475. }
  476. struct eth_device *eth_get_dev_by_index(int index)
  477. {
  478. struct eth_device *dev, *target_dev;
  479. if (!eth_devices)
  480. return NULL;
  481. dev = eth_devices;
  482. target_dev = NULL;
  483. do {
  484. if (dev->index == index) {
  485. target_dev = dev;
  486. break;
  487. }
  488. dev = dev->next;
  489. } while (dev != eth_devices);
  490. return target_dev;
  491. }
  492. int eth_get_dev_index(void)
  493. {
  494. if (!eth_current)
  495. return -1;
  496. return eth_current->index;
  497. }
  498. int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
  499. int eth_number)
  500. {
  501. unsigned char env_enetaddr[6];
  502. int ret = 0;
  503. eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
  504. if (!is_zero_ethaddr(env_enetaddr)) {
  505. if (!is_zero_ethaddr(dev->enetaddr) &&
  506. memcmp(dev->enetaddr, env_enetaddr, 6)) {
  507. printf("\nWarning: %s MAC addresses don't match:\n",
  508. dev->name);
  509. printf("Address in SROM is %pM\n",
  510. dev->enetaddr);
  511. printf("Address in environment is %pM\n",
  512. env_enetaddr);
  513. }
  514. memcpy(dev->enetaddr, env_enetaddr, 6);
  515. } else if (is_valid_ethaddr(dev->enetaddr)) {
  516. eth_setenv_enetaddr_by_index(base_name, eth_number,
  517. dev->enetaddr);
  518. printf("\nWarning: %s using MAC address from net device\n",
  519. dev->name);
  520. } else if (is_zero_ethaddr(dev->enetaddr)) {
  521. printf("\nError: %s address not set.\n",
  522. dev->name);
  523. return -EINVAL;
  524. }
  525. if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
  526. if (!is_valid_ethaddr(dev->enetaddr)) {
  527. printf("\nError: %s address %pM illegal value\n",
  528. dev->name, dev->enetaddr);
  529. return -EINVAL;
  530. }
  531. ret = dev->write_hwaddr(dev);
  532. if (ret)
  533. printf("\nWarning: %s failed to set MAC address\n",
  534. dev->name);
  535. }
  536. return ret;
  537. }
  538. int eth_register(struct eth_device *dev)
  539. {
  540. struct eth_device *d;
  541. static int index;
  542. assert(strlen(dev->name) < sizeof(dev->name));
  543. if (!eth_devices) {
  544. eth_devices = dev;
  545. eth_current = dev;
  546. eth_current_changed();
  547. } else {
  548. for (d = eth_devices; d->next != eth_devices; d = d->next)
  549. ;
  550. d->next = dev;
  551. }
  552. dev->state = ETH_STATE_INIT;
  553. dev->next = eth_devices;
  554. dev->index = index++;
  555. return 0;
  556. }
  557. int eth_unregister(struct eth_device *dev)
  558. {
  559. struct eth_device *cur;
  560. /* No device */
  561. if (!eth_devices)
  562. return -ENODEV;
  563. for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
  564. cur = cur->next)
  565. ;
  566. /* Device not found */
  567. if (cur->next != dev)
  568. return -ENODEV;
  569. cur->next = dev->next;
  570. if (eth_devices == dev)
  571. eth_devices = dev->next == eth_devices ? NULL : dev->next;
  572. if (eth_current == dev) {
  573. eth_current = eth_devices;
  574. eth_current_changed();
  575. }
  576. return 0;
  577. }
  578. int eth_initialize(void)
  579. {
  580. int num_devices = 0;
  581. eth_devices = NULL;
  582. eth_current = NULL;
  583. bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
  584. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  585. miiphy_init();
  586. #endif
  587. #ifdef CONFIG_PHYLIB
  588. phy_init();
  589. #endif
  590. eth_env_init();
  591. /*
  592. * If board-specific initialization exists, call it.
  593. * If not, call a CPU-specific one
  594. */
  595. if (board_eth_init != __def_eth_init) {
  596. if (board_eth_init(gd->bd) < 0)
  597. printf("Board Net Initialization Failed\n");
  598. } else if (cpu_eth_init != __def_eth_init) {
  599. if (cpu_eth_init(gd->bd) < 0)
  600. printf("CPU Net Initialization Failed\n");
  601. } else {
  602. printf("Net Initialization Skipped\n");
  603. }
  604. if (!eth_devices) {
  605. puts("No ethernet found.\n");
  606. bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
  607. } else {
  608. struct eth_device *dev = eth_devices;
  609. char *ethprime = getenv("ethprime");
  610. bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
  611. do {
  612. if (dev->index)
  613. puts(", ");
  614. printf("%s", dev->name);
  615. if (ethprime && strcmp(dev->name, ethprime) == 0) {
  616. eth_current = dev;
  617. puts(" [PRIME]");
  618. }
  619. if (strchr(dev->name, ' '))
  620. puts("\nWarning: eth device name has a space!"
  621. "\n");
  622. eth_write_hwaddr(dev, "eth", dev->index);
  623. dev = dev->next;
  624. num_devices++;
  625. } while (dev != eth_devices);
  626. eth_current_changed();
  627. putc('\n');
  628. }
  629. return num_devices;
  630. }
  631. #ifdef CONFIG_MCAST_TFTP
  632. /* Multicast.
  633. * mcast_addr: multicast ipaddr from which multicast Mac is made
  634. * join: 1=join, 0=leave.
  635. */
  636. int eth_mcast_join(struct in_addr mcast_ip, int join)
  637. {
  638. u8 mcast_mac[6];
  639. if (!eth_current || !eth_current->mcast)
  640. return -1;
  641. mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff;
  642. mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff;
  643. mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f;
  644. mcast_mac[2] = 0x5e;
  645. mcast_mac[1] = 0x0;
  646. mcast_mac[0] = 0x1;
  647. return eth_current->mcast(eth_current, mcast_mac, join);
  648. }
  649. /* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
  650. * and this is the ethernet-crc method needed for TSEC -- and perhaps
  651. * some other adapter -- hash tables
  652. */
  653. #define CRCPOLY_LE 0xedb88320
  654. u32 ether_crc(size_t len, unsigned char const *p)
  655. {
  656. int i;
  657. u32 crc;
  658. crc = ~0;
  659. while (len--) {
  660. crc ^= *p++;
  661. for (i = 0; i < 8; i++)
  662. crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
  663. }
  664. /* an reverse the bits, cuz of way they arrive -- last-first */
  665. crc = (crc >> 16) | (crc << 16);
  666. crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
  667. crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
  668. crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
  669. crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
  670. return crc;
  671. }
  672. #endif
  673. int eth_init(void)
  674. {
  675. struct eth_device *old_current, *dev;
  676. if (!eth_current) {
  677. puts("No ethernet found.\n");
  678. return -ENODEV;
  679. }
  680. /* Sync environment with network devices */
  681. dev = eth_devices;
  682. do {
  683. uchar env_enetaddr[6];
  684. if (eth_getenv_enetaddr_by_index("eth", dev->index,
  685. env_enetaddr))
  686. memcpy(dev->enetaddr, env_enetaddr, 6);
  687. dev = dev->next;
  688. } while (dev != eth_devices);
  689. old_current = eth_current;
  690. do {
  691. debug("Trying %s\n", eth_current->name);
  692. if (eth_current->init(eth_current, gd->bd) >= 0) {
  693. eth_current->state = ETH_STATE_ACTIVE;
  694. return 0;
  695. }
  696. debug("FAIL\n");
  697. eth_try_another(0);
  698. } while (old_current != eth_current);
  699. return -ETIMEDOUT;
  700. }
  701. void eth_halt(void)
  702. {
  703. if (!eth_current)
  704. return;
  705. eth_current->halt(eth_current);
  706. eth_current->state = ETH_STATE_PASSIVE;
  707. }
  708. int eth_send(void *packet, int length)
  709. {
  710. if (!eth_current)
  711. return -ENODEV;
  712. return eth_current->send(eth_current, packet, length);
  713. }
  714. int eth_rx(void)
  715. {
  716. if (!eth_current)
  717. return -ENODEV;
  718. return eth_current->recv(eth_current);
  719. }
  720. #endif /* ifndef CONFIG_DM_ETH */
  721. #ifdef CONFIG_API
  722. static void eth_save_packet(void *packet, int length)
  723. {
  724. char *p = packet;
  725. int i;
  726. if ((eth_rcv_last+1) % PKTBUFSRX == eth_rcv_current)
  727. return;
  728. if (PKTSIZE < length)
  729. return;
  730. for (i = 0; i < length; i++)
  731. eth_rcv_bufs[eth_rcv_last].data[i] = p[i];
  732. eth_rcv_bufs[eth_rcv_last].length = length;
  733. eth_rcv_last = (eth_rcv_last + 1) % PKTBUFSRX;
  734. }
  735. int eth_receive(void *packet, int length)
  736. {
  737. char *p = packet;
  738. void *pp = push_packet;
  739. int i;
  740. if (eth_rcv_current == eth_rcv_last) {
  741. push_packet = eth_save_packet;
  742. eth_rx();
  743. push_packet = pp;
  744. if (eth_rcv_current == eth_rcv_last)
  745. return -1;
  746. }
  747. length = min(eth_rcv_bufs[eth_rcv_current].length, length);
  748. for (i = 0; i < length; i++)
  749. p[i] = eth_rcv_bufs[eth_rcv_current].data[i];
  750. eth_rcv_current = (eth_rcv_current + 1) % PKTBUFSRX;
  751. return length;
  752. }
  753. #endif /* CONFIG_API */
  754. static void eth_current_changed(void)
  755. {
  756. char *act = getenv("ethact");
  757. /* update current ethernet name */
  758. if (eth_get_dev()) {
  759. if (act == NULL || strcmp(act, eth_get_name()) != 0)
  760. setenv("ethact", eth_get_name());
  761. }
  762. /*
  763. * remove the variable completely if there is no active
  764. * interface
  765. */
  766. else if (act != NULL)
  767. setenv("ethact", NULL);
  768. }
  769. void eth_try_another(int first_restart)
  770. {
  771. static void *first_failed;
  772. char *ethrotate;
  773. /*
  774. * Do not rotate between network interfaces when
  775. * 'ethrotate' variable is set to 'no'.
  776. */
  777. ethrotate = getenv("ethrotate");
  778. if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0))
  779. return;
  780. if (!eth_get_dev())
  781. return;
  782. if (first_restart)
  783. first_failed = eth_get_dev();
  784. eth_set_current_to_next();
  785. eth_current_changed();
  786. if (first_failed == eth_get_dev())
  787. net_restart_wrap = 1;
  788. }
  789. void eth_set_current(void)
  790. {
  791. static char *act;
  792. static int env_changed_id;
  793. int env_id;
  794. env_id = get_env_id();
  795. if ((act == NULL) || (env_changed_id != env_id)) {
  796. act = getenv("ethact");
  797. env_changed_id = env_id;
  798. }
  799. if (act == NULL) {
  800. char *ethprime = getenv("ethprime");
  801. void *dev = NULL;
  802. if (ethprime)
  803. dev = eth_get_dev_by_name(ethprime);
  804. if (dev)
  805. eth_set_dev(dev);
  806. else
  807. eth_set_dev(NULL);
  808. } else {
  809. eth_set_dev(eth_get_dev_by_name(act));
  810. }
  811. eth_current_changed();
  812. }
  813. const char *eth_get_name(void)
  814. {
  815. return eth_get_dev() ? eth_get_dev()->name : "unknown";
  816. }