mcffec.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2004
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (C) Copyright 2007 Freescale Semiconductor, Inc.
  7. * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
  8. *
  9. * Conversion to DM
  10. * (C) 2019 Angelo Dureghello <angelo.dureghello@timesys.com>
  11. */
  12. #include <common.h>
  13. #include <env.h>
  14. #include <hang.h>
  15. #include <malloc.h>
  16. #include <command.h>
  17. #include <net.h>
  18. #include <miiphy.h>
  19. #include <asm/fec.h>
  20. #include <asm/immap.h>
  21. #include <linux/delay.h>
  22. #include <linux/mii.h>
  23. #undef ET_DEBUG
  24. #undef MII_DEBUG
  25. /* Ethernet Transmit and Receive Buffers */
  26. #define DBUF_LENGTH 1520
  27. #define TX_BUF_CNT 2
  28. #define PKT_MAXBUF_SIZE 1518
  29. #define PKT_MAXBLR_SIZE 1520
  30. #define LAST_PKTBUFSRX PKTBUFSRX - 1
  31. #define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
  32. #define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST)
  33. DECLARE_GLOBAL_DATA_PTR;
  34. static void init_eth_info(struct fec_info_s *info)
  35. {
  36. #ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
  37. static u32 tmp;
  38. if (info->index == 0)
  39. tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000;
  40. else
  41. info->rxbd = (cbd_t *)DBUF_LENGTH;
  42. /* setup Receive and Transmit buffer descriptor */
  43. info->rxbd = (cbd_t *)((u32)info->rxbd + tmp);
  44. tmp = (u32)info->rxbd;
  45. info->txbd =
  46. (cbd_t *)((u32)info->txbd + tmp +
  47. (PKTBUFSRX * sizeof(cbd_t)));
  48. tmp = (u32)info->txbd;
  49. info->txbuf =
  50. (char *)((u32)info->txbuf + tmp +
  51. (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
  52. tmp = (u32)info->txbuf;
  53. #else
  54. info->rxbd =
  55. (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
  56. (PKTBUFSRX * sizeof(cbd_t)));
  57. info->txbd =
  58. (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
  59. (TX_BUF_CNT * sizeof(cbd_t)));
  60. info->txbuf =
  61. (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
  62. #endif
  63. #ifdef ET_DEBUG
  64. printf("rxbd %x txbd %x\n", (int)info->rxbd, (int)info->txbd);
  65. #endif
  66. info->phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
  67. }
  68. static void fec_reset(struct fec_info_s *info)
  69. {
  70. volatile fec_t *fecp = (fec_t *)(info->iobase);
  71. int i;
  72. fecp->ecr = FEC_ECR_RESET;
  73. for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i)
  74. udelay(1);
  75. if (i == FEC_RESET_DELAY)
  76. printf("FEC_RESET_DELAY timeout\n");
  77. }
  78. static void set_fec_duplex_speed(volatile fec_t *fecp, int dup_spd)
  79. {
  80. struct bd_info *bd = gd->bd;
  81. if ((dup_spd >> 16) == FULL) {
  82. /* Set maximum frame length */
  83. fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
  84. FEC_RCR_PROM | 0x100;
  85. fecp->tcr = FEC_TCR_FDEN;
  86. } else {
  87. /* Half duplex mode */
  88. fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
  89. FEC_RCR_MII_MODE | FEC_RCR_DRT;
  90. fecp->tcr &= ~FEC_TCR_FDEN;
  91. }
  92. if ((dup_spd & 0xFFFF) == _100BASET) {
  93. #ifdef CONFIG_MCF5445x
  94. fecp->rcr &= ~0x200; /* disabled 10T base */
  95. #endif
  96. #ifdef MII_DEBUG
  97. printf("100Mbps\n");
  98. #endif
  99. bd->bi_ethspeed = 100;
  100. } else {
  101. #ifdef CONFIG_MCF5445x
  102. fecp->rcr |= 0x200; /* enabled 10T base */
  103. #endif
  104. #ifdef MII_DEBUG
  105. printf("10Mbps\n");
  106. #endif
  107. bd->bi_ethspeed = 10;
  108. }
  109. }
  110. #ifdef ET_DEBUG
  111. static void dbg_fec_regs(struct udevice *dev)
  112. {
  113. struct fec_info_s *info = dev->priv;
  114. volatile fec_t *fecp = (fec_t *)(info->iobase);
  115. printf("=====\n");
  116. printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir);
  117. printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr);
  118. printf("r_des_active %x - %x\n", (int)&fecp->rdar, fecp->rdar);
  119. printf("x_des_active %x - %x\n", (int)&fecp->tdar, fecp->tdar);
  120. printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr);
  121. printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
  122. printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr);
  123. printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
  124. printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr);
  125. printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr);
  126. printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr);
  127. printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur);
  128. printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd);
  129. printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur);
  130. printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr);
  131. printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur);
  132. printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr);
  133. printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
  134. printf("r_bound %x - %x\n", (int)&fecp->frbr, fecp->frbr);
  135. printf("r_fstart %x - %x\n", (int)&fecp->frsr, fecp->frsr);
  136. printf("r_drng %x - %x\n", (int)&fecp->erdsr, fecp->erdsr);
  137. printf("x_drng %x - %x\n", (int)&fecp->etdsr, fecp->etdsr);
  138. printf("r_bufsz %x - %x\n", (int)&fecp->emrbr, fecp->emrbr);
  139. printf("\n");
  140. printf("rmon_t_drop %x - %x\n", (int)&fecp->rmon_t_drop,
  141. fecp->rmon_t_drop);
  142. printf("rmon_t_packets %x - %x\n", (int)&fecp->rmon_t_packets,
  143. fecp->rmon_t_packets);
  144. printf("rmon_t_bc_pkt %x - %x\n", (int)&fecp->rmon_t_bc_pkt,
  145. fecp->rmon_t_bc_pkt);
  146. printf("rmon_t_mc_pkt %x - %x\n", (int)&fecp->rmon_t_mc_pkt,
  147. fecp->rmon_t_mc_pkt);
  148. printf("rmon_t_crc_align %x - %x\n", (int)&fecp->rmon_t_crc_align,
  149. fecp->rmon_t_crc_align);
  150. printf("rmon_t_undersize %x - %x\n", (int)&fecp->rmon_t_undersize,
  151. fecp->rmon_t_undersize);
  152. printf("rmon_t_oversize %x - %x\n", (int)&fecp->rmon_t_oversize,
  153. fecp->rmon_t_oversize);
  154. printf("rmon_t_frag %x - %x\n", (int)&fecp->rmon_t_frag,
  155. fecp->rmon_t_frag);
  156. printf("rmon_t_jab %x - %x\n", (int)&fecp->rmon_t_jab,
  157. fecp->rmon_t_jab);
  158. printf("rmon_t_col %x - %x\n", (int)&fecp->rmon_t_col,
  159. fecp->rmon_t_col);
  160. printf("rmon_t_p64 %x - %x\n", (int)&fecp->rmon_t_p64,
  161. fecp->rmon_t_p64);
  162. printf("rmon_t_p65to127 %x - %x\n", (int)&fecp->rmon_t_p65to127,
  163. fecp->rmon_t_p65to127);
  164. printf("rmon_t_p128to255 %x - %x\n", (int)&fecp->rmon_t_p128to255,
  165. fecp->rmon_t_p128to255);
  166. printf("rmon_t_p256to511 %x - %x\n", (int)&fecp->rmon_t_p256to511,
  167. fecp->rmon_t_p256to511);
  168. printf("rmon_t_p512to1023 %x - %x\n", (int)&fecp->rmon_t_p512to1023,
  169. fecp->rmon_t_p512to1023);
  170. printf("rmon_t_p1024to2047 %x - %x\n", (int)&fecp->rmon_t_p1024to2047,
  171. fecp->rmon_t_p1024to2047);
  172. printf("rmon_t_p_gte2048 %x - %x\n", (int)&fecp->rmon_t_p_gte2048,
  173. fecp->rmon_t_p_gte2048);
  174. printf("rmon_t_octets %x - %x\n", (int)&fecp->rmon_t_octets,
  175. fecp->rmon_t_octets);
  176. printf("\n");
  177. printf("ieee_t_drop %x - %x\n", (int)&fecp->ieee_t_drop,
  178. fecp->ieee_t_drop);
  179. printf("ieee_t_frame_ok %x - %x\n", (int)&fecp->ieee_t_frame_ok,
  180. fecp->ieee_t_frame_ok);
  181. printf("ieee_t_1col %x - %x\n", (int)&fecp->ieee_t_1col,
  182. fecp->ieee_t_1col);
  183. printf("ieee_t_mcol %x - %x\n", (int)&fecp->ieee_t_mcol,
  184. fecp->ieee_t_mcol);
  185. printf("ieee_t_def %x - %x\n", (int)&fecp->ieee_t_def,
  186. fecp->ieee_t_def);
  187. printf("ieee_t_lcol %x - %x\n", (int)&fecp->ieee_t_lcol,
  188. fecp->ieee_t_lcol);
  189. printf("ieee_t_excol %x - %x\n", (int)&fecp->ieee_t_excol,
  190. fecp->ieee_t_excol);
  191. printf("ieee_t_macerr %x - %x\n", (int)&fecp->ieee_t_macerr,
  192. fecp->ieee_t_macerr);
  193. printf("ieee_t_cserr %x - %x\n", (int)&fecp->ieee_t_cserr,
  194. fecp->ieee_t_cserr);
  195. printf("ieee_t_sqe %x - %x\n", (int)&fecp->ieee_t_sqe,
  196. fecp->ieee_t_sqe);
  197. printf("ieee_t_fdxfc %x - %x\n", (int)&fecp->ieee_t_fdxfc,
  198. fecp->ieee_t_fdxfc);
  199. printf("ieee_t_octets_ok %x - %x\n", (int)&fecp->ieee_t_octets_ok,
  200. fecp->ieee_t_octets_ok);
  201. printf("\n");
  202. printf("rmon_r_drop %x - %x\n", (int)&fecp->rmon_r_drop,
  203. fecp->rmon_r_drop);
  204. printf("rmon_r_packets %x - %x\n", (int)&fecp->rmon_r_packets,
  205. fecp->rmon_r_packets);
  206. printf("rmon_r_bc_pkt %x - %x\n", (int)&fecp->rmon_r_bc_pkt,
  207. fecp->rmon_r_bc_pkt);
  208. printf("rmon_r_mc_pkt %x - %x\n", (int)&fecp->rmon_r_mc_pkt,
  209. fecp->rmon_r_mc_pkt);
  210. printf("rmon_r_crc_align %x - %x\n", (int)&fecp->rmon_r_crc_align,
  211. fecp->rmon_r_crc_align);
  212. printf("rmon_r_undersize %x - %x\n", (int)&fecp->rmon_r_undersize,
  213. fecp->rmon_r_undersize);
  214. printf("rmon_r_oversize %x - %x\n", (int)&fecp->rmon_r_oversize,
  215. fecp->rmon_r_oversize);
  216. printf("rmon_r_frag %x - %x\n", (int)&fecp->rmon_r_frag,
  217. fecp->rmon_r_frag);
  218. printf("rmon_r_jab %x - %x\n", (int)&fecp->rmon_r_jab,
  219. fecp->rmon_r_jab);
  220. printf("rmon_r_p64 %x - %x\n", (int)&fecp->rmon_r_p64,
  221. fecp->rmon_r_p64);
  222. printf("rmon_r_p65to127 %x - %x\n", (int)&fecp->rmon_r_p65to127,
  223. fecp->rmon_r_p65to127);
  224. printf("rmon_r_p128to255 %x - %x\n", (int)&fecp->rmon_r_p128to255,
  225. fecp->rmon_r_p128to255);
  226. printf("rmon_r_p256to511 %x - %x\n", (int)&fecp->rmon_r_p256to511,
  227. fecp->rmon_r_p256to511);
  228. printf("rmon_r_p512to1023 %x - %x\n", (int)&fecp->rmon_r_p512to1023,
  229. fecp->rmon_r_p512to1023);
  230. printf("rmon_r_p1024to2047 %x - %x\n", (int)&fecp->rmon_r_p1024to2047,
  231. fecp->rmon_r_p1024to2047);
  232. printf("rmon_r_p_gte2048 %x - %x\n", (int)&fecp->rmon_r_p_gte2048,
  233. fecp->rmon_r_p_gte2048);
  234. printf("rmon_r_octets %x - %x\n", (int)&fecp->rmon_r_octets,
  235. fecp->rmon_r_octets);
  236. printf("\n");
  237. printf("ieee_r_drop %x - %x\n", (int)&fecp->ieee_r_drop,
  238. fecp->ieee_r_drop);
  239. printf("ieee_r_frame_ok %x - %x\n", (int)&fecp->ieee_r_frame_ok,
  240. fecp->ieee_r_frame_ok);
  241. printf("ieee_r_crc %x - %x\n", (int)&fecp->ieee_r_crc,
  242. fecp->ieee_r_crc);
  243. printf("ieee_r_align %x - %x\n", (int)&fecp->ieee_r_align,
  244. fecp->ieee_r_align);
  245. printf("ieee_r_macerr %x - %x\n", (int)&fecp->ieee_r_macerr,
  246. fecp->ieee_r_macerr);
  247. printf("ieee_r_fdxfc %x - %x\n", (int)&fecp->ieee_r_fdxfc,
  248. fecp->ieee_r_fdxfc);
  249. printf("ieee_r_octets_ok %x - %x\n", (int)&fecp->ieee_r_octets_ok,
  250. fecp->ieee_r_octets_ok);
  251. printf("\n\n\n");
  252. }
  253. #endif
  254. int mcffec_init(struct udevice *dev)
  255. {
  256. struct fec_info_s *info = dev->priv;
  257. volatile fec_t *fecp = (fec_t *) (info->iobase);
  258. int rval, i;
  259. uchar ea[6];
  260. fecpin_setclear(info, 1);
  261. fec_reset(info);
  262. #if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
  263. defined (CONFIG_SYS_DISCOVER_PHY)
  264. mii_init();
  265. set_fec_duplex_speed(fecp, info->dup_spd);
  266. #else
  267. #ifndef CONFIG_SYS_DISCOVER_PHY
  268. set_fec_duplex_speed(fecp, (FECDUPLEX << 16) | FECSPEED);
  269. #endif /* ifndef CONFIG_SYS_DISCOVER_PHY */
  270. #endif /* CONFIG_CMD_MII || CONFIG_MII */
  271. /* We use strictly polling mode only */
  272. fecp->eimr = 0;
  273. /* Clear any pending interrupt */
  274. fecp->eir = 0xffffffff;
  275. /* Set station address */
  276. if (info->index == 0)
  277. rval = eth_env_get_enetaddr("ethaddr", ea);
  278. else
  279. rval = eth_env_get_enetaddr("eth1addr", ea);
  280. if (!rval) {
  281. puts("Please set a valid MAC address\n");
  282. return -EINVAL;
  283. }
  284. fecp->palr =
  285. (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
  286. fecp->paur = (ea[4] << 24) | (ea[5] << 16);
  287. /* Clear unicast address hash table */
  288. fecp->iaur = 0;
  289. fecp->ialr = 0;
  290. /* Clear multicast address hash table */
  291. fecp->gaur = 0;
  292. fecp->galr = 0;
  293. /* Set maximum receive buffer size. */
  294. fecp->emrbr = PKT_MAXBLR_SIZE;
  295. /*
  296. * Setup Buffers and Buffer Descriptors
  297. */
  298. info->rx_idx = 0;
  299. info->tx_idx = 0;
  300. /*
  301. * Setup Receiver Buffer Descriptors (13.14.24.18)
  302. * Settings:
  303. * Empty, Wrap
  304. */
  305. for (i = 0; i < PKTBUFSRX; i++) {
  306. info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
  307. info->rxbd[i].cbd_datlen = 0; /* Reset */
  308. info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
  309. }
  310. info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
  311. /*
  312. * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
  313. * Settings:
  314. * Last, Tx CRC
  315. */
  316. for (i = 0; i < TX_BUF_CNT; i++) {
  317. info->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
  318. info->txbd[i].cbd_datlen = 0; /* Reset */
  319. info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
  320. }
  321. info->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
  322. /* Set receive and transmit descriptor base */
  323. fecp->erdsr = (unsigned int)(&info->rxbd[0]);
  324. fecp->etdsr = (unsigned int)(&info->txbd[0]);
  325. /* Now enable the transmit and receive processing */
  326. fecp->ecr |= FEC_ECR_ETHER_EN;
  327. /* And last, try to fill Rx Buffer Descriptors
  328. * Descriptor polling active
  329. */
  330. fecp->rdar = 0x01000000;
  331. return 0;
  332. }
  333. static int mcffec_send(struct udevice *dev, void *packet, int length)
  334. {
  335. struct fec_info_s *info = dev->priv;
  336. volatile fec_t *fecp = (fec_t *)info->iobase;
  337. int j, rc;
  338. u16 phy_status;
  339. miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phy_status);
  340. /* section 16.9.23.3
  341. * Wait for ready
  342. */
  343. j = 0;
  344. while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
  345. (j < info->to_loop)) {
  346. udelay(1);
  347. j++;
  348. }
  349. if (j >= info->to_loop)
  350. printf("TX not ready\n");
  351. info->txbd[info->tx_idx].cbd_bufaddr = (uint)packet;
  352. info->txbd[info->tx_idx].cbd_datlen = length;
  353. info->txbd[info->tx_idx].cbd_sc |= BD_ENET_TX_RDY_LST;
  354. /* Activate transmit Buffer Descriptor polling */
  355. fecp->tdar = 0x01000000; /* Descriptor polling active */
  356. #ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
  357. /*
  358. * FEC unable to initial transmit data packet.
  359. * A nop will ensure the descriptor polling active completed.
  360. * CF Internal RAM has shorter cycle access than DRAM. If use
  361. * DRAM as Buffer descriptor and data, a nop is a must.
  362. * Affect only V2 and V3.
  363. */
  364. __asm__ ("nop");
  365. #endif
  366. #ifdef CONFIG_SYS_UNIFY_CACHE
  367. icache_invalid();
  368. #endif
  369. j = 0;
  370. while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
  371. (j < info->to_loop)) {
  372. udelay(1);
  373. j++;
  374. }
  375. if (j >= info->to_loop)
  376. printf("TX timeout\n");
  377. #ifdef ET_DEBUG
  378. printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
  379. __FILE__, __LINE__, __func__, j,
  380. info->txbd[info->tx_idx].cbd_sc,
  381. (info->txbd[info->tx_idx].cbd_sc & 0x003C) >> 2);
  382. #endif
  383. /* return only status bits */
  384. rc = (info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_STATS);
  385. info->tx_idx = (info->tx_idx + 1) % TX_BUF_CNT;
  386. return rc;
  387. }
  388. static int mcffec_recv(struct udevice *dev, int flags, uchar **packetp)
  389. {
  390. struct fec_info_s *info = dev->priv;
  391. volatile fec_t *fecp = (fec_t *)info->iobase;
  392. int length = -1;
  393. for (;;) {
  394. #ifdef CONFIG_SYS_UNIFY_CACHE
  395. icache_invalid();
  396. #endif
  397. /* If nothing received - leave for() loop */
  398. if (info->rxbd[info->rx_idx].cbd_sc & BD_ENET_RX_EMPTY)
  399. break;
  400. length = info->rxbd[info->rx_idx].cbd_datlen;
  401. if (info->rxbd[info->rx_idx].cbd_sc & 0x003f) {
  402. printf("%s[%d] err: %x\n",
  403. __func__, __LINE__,
  404. info->rxbd[info->rx_idx].cbd_sc);
  405. } else {
  406. length -= 4;
  407. /*
  408. * Pass the buffer ptr up to the protocol layers.
  409. */
  410. *packetp = net_rx_packets[info->rx_idx];
  411. fecp->eir |= FEC_EIR_RXF;
  412. }
  413. /* Give the buffer back to the FEC. */
  414. info->rxbd[info->rx_idx].cbd_datlen = 0;
  415. /* wrap around buffer index when necessary */
  416. if (info->rx_idx == LAST_PKTBUFSRX) {
  417. info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E;
  418. info->rx_idx = 0;
  419. } else {
  420. info->rxbd[info->rx_idx].cbd_sc = BD_ENET_RX_EMPTY;
  421. info->rx_idx++;
  422. }
  423. /* Try to fill Buffer Descriptors
  424. * Descriptor polling active
  425. */
  426. fecp->rdar = 0x01000000;
  427. }
  428. return length;
  429. }
  430. static void mcffec_halt(struct udevice *dev)
  431. {
  432. struct fec_info_s *info = dev->priv;
  433. fec_reset(info);
  434. fecpin_setclear(info, 0);
  435. info->rx_idx = 0;
  436. info->tx_idx = 0;
  437. memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t));
  438. memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t));
  439. memset(info->txbuf, 0, DBUF_LENGTH);
  440. }
  441. static const struct eth_ops mcffec_ops = {
  442. .start = mcffec_init,
  443. .send = mcffec_send,
  444. .recv = mcffec_recv,
  445. .stop = mcffec_halt,
  446. };
  447. /*
  448. * Boot sequence, called just after mcffec_of_to_plat,
  449. * as DM way, it replaces old mcffec_initialize.
  450. */
  451. static int mcffec_probe(struct udevice *dev)
  452. {
  453. struct eth_pdata *pdata = dev_get_plat(dev);
  454. struct fec_info_s *info = dev->priv;
  455. int node = dev_of_offset(dev);
  456. int retval, fec_idx;
  457. const u32 *val;
  458. info->index = dev_seq(dev);
  459. info->iobase = pdata->iobase;
  460. info->phy_addr = -1;
  461. val = fdt_getprop(gd->fdt_blob, node, "mii-base", NULL);
  462. if (val) {
  463. u32 fec_iobase;
  464. fec_idx = fdt32_to_cpu(*val);
  465. if (fec_idx == info->index) {
  466. fec_iobase = info->iobase;
  467. } else {
  468. printf("mii base != base address, fec_idx %d\n",
  469. fec_idx);
  470. retval = fec_get_base_addr(fec_idx, &fec_iobase);
  471. if (retval)
  472. return retval;
  473. }
  474. info->miibase = fec_iobase;
  475. }
  476. val = fdt_getprop(gd->fdt_blob, node, "phy-addr", NULL);
  477. if (val)
  478. info->phy_addr = fdt32_to_cpu(*val);
  479. val = fdt_getprop(gd->fdt_blob, node, "timeout-loop", NULL);
  480. if (val)
  481. info->to_loop = fdt32_to_cpu(*val);
  482. init_eth_info(info);
  483. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
  484. info->bus = mdio_alloc();
  485. if (!info->bus)
  486. return -ENOMEM;
  487. strcpy(info->bus->name, dev->name);
  488. info->bus->read = mcffec_miiphy_read;
  489. info->bus->write = mcffec_miiphy_write;
  490. retval = mdio_register(info->bus);
  491. if (retval < 0)
  492. return retval;
  493. #endif
  494. return 0;
  495. }
  496. static int mcffec_remove(struct udevice *dev)
  497. {
  498. struct fec_info_s *priv = dev_get_priv(dev);
  499. mdio_unregister(priv->bus);
  500. mdio_free(priv->bus);
  501. return 0;
  502. }
  503. /*
  504. * Boot sequence, called 1st
  505. */
  506. static int mcffec_of_to_plat(struct udevice *dev)
  507. {
  508. struct eth_pdata *pdata = dev_get_plat(dev);
  509. const u32 *val;
  510. pdata->iobase = dev_read_addr(dev);
  511. /* Default to 10Mbit/s */
  512. pdata->max_speed = 10;
  513. val = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
  514. "max-speed", NULL);
  515. if (val)
  516. pdata->max_speed = fdt32_to_cpu(*val);
  517. return 0;
  518. }
  519. static const struct udevice_id mcffec_ids[] = {
  520. { .compatible = "fsl,mcf-fec" },
  521. { }
  522. };
  523. U_BOOT_DRIVER(mcffec) = {
  524. .name = "mcffec",
  525. .id = UCLASS_ETH,
  526. .of_match = mcffec_ids,
  527. .of_to_plat = mcffec_of_to_plat,
  528. .probe = mcffec_probe,
  529. .remove = mcffec_remove,
  530. .ops = &mcffec_ops,
  531. .priv_auto = sizeof(struct fec_info_s),
  532. .plat_auto = sizeof(struct eth_pdata),
  533. };