eth.c 24 KB

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