mpc512x_fec.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. * (C) Copyright 2003-2010
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * Derived from the MPC8xx FEC driver.
  6. * Adapted for MPC512x by Grzegorz Bernacki <gjb@semihalf.com>
  7. */
  8. #include <common.h>
  9. #include <malloc.h>
  10. #include <net.h>
  11. #include <netdev.h>
  12. #include <miiphy.h>
  13. #include <asm/io.h>
  14. #include "mpc512x_fec.h"
  15. DECLARE_GLOBAL_DATA_PTR;
  16. #define DEBUG 0
  17. #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
  18. defined(CONFIG_MPC512x_FEC)
  19. #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
  20. #error "CONFIG_MII has to be defined!"
  21. #endif
  22. int fec512x_miiphy_read(char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
  23. int fec512x_miiphy_write(char *devname, u8 phyAddr, u8 regAddr, u16 data);
  24. int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
  25. static uchar rx_buff[FEC_BUFFER_SIZE];
  26. static int rx_buff_idx = 0;
  27. /********************************************************************/
  28. #if (DEBUG & 0x2)
  29. static void mpc512x_fec_phydump (char *devname)
  30. {
  31. u16 phyStatus, i;
  32. u8 phyAddr = CONFIG_PHY_ADDR;
  33. u8 reg_mask[] = {
  34. /* regs to print: 0...8, 21,27,31 */
  35. 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
  36. 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
  37. };
  38. for (i = 0; i < 32; i++) {
  39. if (reg_mask[i]) {
  40. miiphy_read (devname, phyAddr, i, &phyStatus);
  41. printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
  42. }
  43. }
  44. }
  45. #endif
  46. /********************************************************************/
  47. static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec)
  48. {
  49. int ix;
  50. /*
  51. * Receive BDs init
  52. */
  53. for (ix = 0; ix < FEC_RBD_NUM; ix++) {
  54. fec->bdBase->rbd[ix].dataPointer =
  55. (u32)&fec->bdBase->recv_frames[ix];
  56. fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY;
  57. fec->bdBase->rbd[ix].dataLength = 0;
  58. }
  59. /*
  60. * have the last RBD to close the ring
  61. */
  62. fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP;
  63. fec->rbdIndex = 0;
  64. /*
  65. * Trasmit BDs init
  66. */
  67. for (ix = 0; ix < FEC_TBD_NUM; ix++) {
  68. fec->bdBase->tbd[ix].status = 0;
  69. }
  70. /*
  71. * Have the last TBD to close the ring
  72. */
  73. fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP;
  74. /*
  75. * Initialize some indices
  76. */
  77. fec->tbdIndex = 0;
  78. fec->usedTbdIndex = 0;
  79. fec->cleanTbdNum = FEC_TBD_NUM;
  80. return 0;
  81. }
  82. /********************************************************************/
  83. static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd)
  84. {
  85. /*
  86. * Reset buffer descriptor as empty
  87. */
  88. if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
  89. pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
  90. else
  91. pRbd->status = FEC_RBD_EMPTY;
  92. pRbd->dataLength = 0;
  93. /*
  94. * Increment BD count
  95. */
  96. fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
  97. /*
  98. * Now, we have an empty RxBD, notify FEC
  99. * Set Descriptor polling active
  100. */
  101. out_be32(&fec->eth->r_des_active, 0x01000000);
  102. }
  103. /********************************************************************/
  104. static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec)
  105. {
  106. volatile FEC_TBD *pUsedTbd;
  107. #if (DEBUG & 0x1)
  108. printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
  109. fec->cleanTbdNum, fec->usedTbdIndex);
  110. #endif
  111. /*
  112. * process all the consumed TBDs
  113. */
  114. while (fec->cleanTbdNum < FEC_TBD_NUM) {
  115. pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex];
  116. if (pUsedTbd->status & FEC_TBD_READY) {
  117. #if (DEBUG & 0x20)
  118. printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex);
  119. #endif
  120. return;
  121. }
  122. /*
  123. * clean this buffer descriptor
  124. */
  125. if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
  126. pUsedTbd->status = FEC_TBD_WRAP;
  127. else
  128. pUsedTbd->status = 0;
  129. /*
  130. * update some indeces for a correct handling of the TBD ring
  131. */
  132. fec->cleanTbdNum++;
  133. fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
  134. }
  135. }
  136. /********************************************************************/
  137. static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, char *mac)
  138. {
  139. u8 currByte; /* byte for which to compute the CRC */
  140. int byte; /* loop - counter */
  141. int bit; /* loop - counter */
  142. u32 crc = 0xffffffff; /* initial value */
  143. /*
  144. * The algorithm used is the following:
  145. * we loop on each of the six bytes of the provided address,
  146. * and we compute the CRC by left-shifting the previous
  147. * value by one position, so that each bit in the current
  148. * byte of the address may contribute the calculation. If
  149. * the latter and the MSB in the CRC are different, then
  150. * the CRC value so computed is also ex-ored with the
  151. * "polynomium generator". The current byte of the address
  152. * is also shifted right by one bit at each iteration.
  153. * This is because the CRC generatore in hardware is implemented
  154. * as a shift-register with as many ex-ores as the radixes
  155. * in the polynomium. This suggests that we represent the
  156. * polynomiumm itself as a 32-bit constant.
  157. */
  158. for (byte = 0; byte < 6; byte++) {
  159. currByte = mac[byte];
  160. for (bit = 0; bit < 8; bit++) {
  161. if ((currByte & 0x01) ^ (crc & 0x01)) {
  162. crc >>= 1;
  163. crc = crc ^ 0xedb88320;
  164. } else {
  165. crc >>= 1;
  166. }
  167. currByte >>= 1;
  168. }
  169. }
  170. crc = crc >> 26;
  171. /*
  172. * Set individual hash table register
  173. */
  174. if (crc >= 32) {
  175. out_be32(&fec->eth->iaddr1, (1 << (crc - 32)));
  176. out_be32(&fec->eth->iaddr2, 0);
  177. } else {
  178. out_be32(&fec->eth->iaddr1, 0);
  179. out_be32(&fec->eth->iaddr2, (1 << crc));
  180. }
  181. /*
  182. * Set physical address
  183. */
  184. out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) +
  185. (mac[2] << 8) + mac[3]);
  186. out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) +
  187. 0x8808);
  188. }
  189. /********************************************************************/
  190. static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
  191. {
  192. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  193. #if (DEBUG & 0x1)
  194. printf ("mpc512x_fec_init... Begin\n");
  195. #endif
  196. /* Set interrupt mask register */
  197. out_be32(&fec->eth->imask, 0x00000000);
  198. /* Clear FEC-Lite interrupt event register(IEVENT) */
  199. out_be32(&fec->eth->ievent, 0xffffffff);
  200. /* Set transmit fifo watermark register(X_WMRK), default = 64 */
  201. out_be32(&fec->eth->x_wmrk, 0x0);
  202. /* Set Opcode/Pause Duration Register */
  203. out_be32(&fec->eth->op_pause, 0x00010020);
  204. /* Frame length=1522; MII mode */
  205. out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x24);
  206. /* Half-duplex, heartbeat disabled */
  207. out_be32(&fec->eth->x_cntrl, 0x00000000);
  208. /* Enable MIB counters */
  209. out_be32(&fec->eth->mib_control, 0x0);
  210. /* Setup recv fifo start and buff size */
  211. out_be32(&fec->eth->r_fstart, 0x500);
  212. out_be32(&fec->eth->r_buff_size, FEC_BUFFER_SIZE);
  213. /* Setup BD base addresses */
  214. out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd);
  215. out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd);
  216. /* DMA Control */
  217. out_be32(&fec->eth->dma_control, 0xc0000000);
  218. /* Enable FEC */
  219. setbits_be32(&fec->eth->ecntrl, 0x00000006);
  220. /* Initilize addresses and status words of BDs */
  221. mpc512x_fec_bd_init (fec);
  222. /* Descriptor polling active */
  223. out_be32(&fec->eth->r_des_active, 0x01000000);
  224. #if (DEBUG & 0x1)
  225. printf("mpc512x_fec_init... Done \n");
  226. #endif
  227. return 1;
  228. }
  229. /********************************************************************/
  230. int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
  231. {
  232. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  233. const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
  234. int timeout = 1;
  235. u16 phyStatus;
  236. #if (DEBUG & 0x1)
  237. printf ("mpc512x_fec_init_phy... Begin\n");
  238. #endif
  239. /*
  240. * Clear FEC-Lite interrupt event register(IEVENT)
  241. */
  242. out_be32(&fec->eth->ievent, 0xffffffff);
  243. /*
  244. * Set interrupt mask register
  245. */
  246. out_be32(&fec->eth->imask, 0x00000000);
  247. if (fec->xcv_type != SEVENWIRE) {
  248. /*
  249. * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
  250. * and do not drop the Preamble.
  251. */
  252. out_be32(&fec->eth->mii_speed,
  253. (((gd->ips_clk / 1000000) / 5) + 1) << 1);
  254. /*
  255. * Reset PHY, then delay 300ns
  256. */
  257. miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
  258. udelay (1000);
  259. if (fec->xcv_type == MII10) {
  260. /*
  261. * Force 10Base-T, FDX operation
  262. */
  263. #if (DEBUG & 0x2)
  264. printf ("Forcing 10 Mbps ethernet link... ");
  265. #endif
  266. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  267. miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
  268. timeout = 20;
  269. do { /* wait for link status to go down */
  270. udelay (10000);
  271. if ((timeout--) == 0) {
  272. #if (DEBUG & 0x2)
  273. printf ("hmmm, should not have waited...");
  274. #endif
  275. break;
  276. }
  277. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  278. #if (DEBUG & 0x2)
  279. printf ("=");
  280. #endif
  281. } while ((phyStatus & 0x0004)); /* !link up */
  282. timeout = 1000;
  283. do { /* wait for link status to come back up */
  284. udelay (10000);
  285. if ((timeout--) == 0) {
  286. printf ("failed. Link is down.\n");
  287. break;
  288. }
  289. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  290. #if (DEBUG & 0x2)
  291. printf ("+");
  292. #endif
  293. } while (!(phyStatus & 0x0004)); /* !link up */
  294. #if (DEBUG & 0x2)
  295. printf ("done.\n");
  296. #endif
  297. } else { /* MII100 */
  298. /*
  299. * Set the auto-negotiation advertisement register bits
  300. */
  301. miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
  302. /*
  303. * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
  304. */
  305. miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
  306. /*
  307. * Wait for AN completion
  308. */
  309. timeout = 2500;
  310. do {
  311. udelay (1000);
  312. if ((timeout--) == 0) {
  313. #if (DEBUG & 0x2)
  314. printf ("PHY auto neg 0 failed...\n");
  315. #endif
  316. return -1;
  317. }
  318. if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) {
  319. #if (DEBUG & 0x2)
  320. printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
  321. #endif
  322. return -1;
  323. }
  324. } while (!(phyStatus & 0x0004));
  325. #if (DEBUG & 0x2)
  326. printf ("PHY auto neg complete! \n");
  327. #endif
  328. }
  329. }
  330. #if (DEBUG & 0x2)
  331. if (fec->xcv_type != SEVENWIRE)
  332. mpc512x_fec_phydump (dev->name);
  333. #endif
  334. #if (DEBUG & 0x1)
  335. printf ("mpc512x_fec_init_phy... Done \n");
  336. #endif
  337. return 1;
  338. }
  339. /********************************************************************/
  340. static void mpc512x_fec_halt (struct eth_device *dev)
  341. {
  342. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  343. int counter = 0xffff;
  344. #if (DEBUG & 0x2)
  345. if (fec->xcv_type != SEVENWIRE)
  346. mpc512x_fec_phydump (dev->name);
  347. #endif
  348. /*
  349. * mask FEC chip interrupts
  350. */
  351. out_be32(&fec->eth->imask, 0);
  352. /*
  353. * issue graceful stop command to the FEC transmitter if necessary
  354. */
  355. setbits_be32(&fec->eth->x_cntrl, 0x00000001);
  356. /*
  357. * wait for graceful stop to register
  358. */
  359. while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000)))
  360. ;
  361. /*
  362. * Disable the Ethernet Controller
  363. */
  364. clrbits_be32(&fec->eth->ecntrl, 0x00000002);
  365. /*
  366. * Issue a reset command to the FEC chip
  367. */
  368. setbits_be32(&fec->eth->ecntrl, 0x1);
  369. /*
  370. * wait at least 16 clock cycles
  371. */
  372. udelay (10);
  373. #if (DEBUG & 0x3)
  374. printf ("Ethernet task stopped\n");
  375. #endif
  376. }
  377. /********************************************************************/
  378. static int mpc512x_fec_send (struct eth_device *dev, volatile void *eth_data,
  379. int data_length)
  380. {
  381. /*
  382. * This routine transmits one frame. This routine only accepts
  383. * 6-byte Ethernet addresses.
  384. */
  385. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  386. volatile FEC_TBD *pTbd;
  387. #if (DEBUG & 0x20)
  388. printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status);
  389. #endif
  390. /*
  391. * Clear Tx BD ring at first
  392. */
  393. mpc512x_fec_tbd_scrub (fec);
  394. /*
  395. * Check for valid length of data.
  396. */
  397. if ((data_length > 1500) || (data_length <= 0)) {
  398. return -1;
  399. }
  400. /*
  401. * Check the number of vacant TxBDs.
  402. */
  403. if (fec->cleanTbdNum < 1) {
  404. #if (DEBUG & 0x20)
  405. printf ("No available TxBDs ...\n");
  406. #endif
  407. return -1;
  408. }
  409. /*
  410. * Get the first TxBD to send the mac header
  411. */
  412. pTbd = &fec->bdBase->tbd[fec->tbdIndex];
  413. pTbd->dataLength = data_length;
  414. pTbd->dataPointer = (u32)eth_data;
  415. pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
  416. fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
  417. /* Activate transmit Buffer Descriptor polling */
  418. out_be32(&fec->eth->x_des_active, 0x01000000);
  419. #if (DEBUG & 0x8)
  420. printf ( "+" );
  421. #endif
  422. fec->cleanTbdNum -= 1;
  423. /*
  424. * wait until frame is sent .
  425. */
  426. while (pTbd->status & FEC_TBD_READY) {
  427. udelay (10);
  428. #if (DEBUG & 0x8)
  429. printf ("TDB status = %04x\n", pTbd->status);
  430. #endif
  431. }
  432. return 0;
  433. }
  434. /********************************************************************/
  435. static int mpc512x_fec_recv (struct eth_device *dev)
  436. {
  437. /*
  438. * This command pulls one frame from the card
  439. */
  440. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  441. volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
  442. unsigned long ievent;
  443. int frame_length = 0;
  444. #if (DEBUG & 0x1)
  445. printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
  446. #endif
  447. #if (DEBUG & 0x8)
  448. printf( "-" );
  449. #endif
  450. /*
  451. * Check if any critical events have happened
  452. */
  453. ievent = in_be32(&fec->eth->ievent);
  454. out_be32(&fec->eth->ievent, ievent);
  455. if (ievent & 0x20060000) {
  456. /* BABT, Rx/Tx FIFO errors */
  457. mpc512x_fec_halt (dev);
  458. mpc512x_fec_init (dev, NULL);
  459. return 0;
  460. }
  461. if (ievent & 0x80000000) {
  462. /* Heartbeat error */
  463. setbits_be32(&fec->eth->x_cntrl, 0x00000001);
  464. }
  465. if (ievent & 0x10000000) {
  466. /* Graceful stop complete */
  467. if (in_be32(&fec->eth->x_cntrl) & 0x00000001) {
  468. mpc512x_fec_halt (dev);
  469. clrbits_be32(&fec->eth->x_cntrl, 0x00000001);;
  470. mpc512x_fec_init (dev, NULL);
  471. }
  472. }
  473. if (!(pRbd->status & FEC_RBD_EMPTY)) {
  474. if (!(pRbd->status & FEC_RBD_ERR) &&
  475. ((pRbd->dataLength - 4) > 14)) {
  476. /*
  477. * Get buffer size
  478. */
  479. if (pRbd->status & FEC_RBD_LAST)
  480. frame_length = pRbd->dataLength - 4;
  481. else
  482. frame_length = pRbd->dataLength;
  483. #if (DEBUG & 0x20)
  484. {
  485. int i;
  486. printf ("recv data length 0x%08x data hdr: ",
  487. pRbd->dataLength);
  488. for (i = 0; i < 14; i++)
  489. printf ("%x ", *((u8*)pRbd->dataPointer + i));
  490. printf("\n");
  491. }
  492. #endif
  493. /*
  494. * Fill the buffer and pass it to upper layers
  495. */
  496. memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
  497. frame_length - rx_buff_idx);
  498. rx_buff_idx = frame_length;
  499. if (pRbd->status & FEC_RBD_LAST) {
  500. NetReceive ((uchar*)rx_buff, frame_length);
  501. rx_buff_idx = 0;
  502. }
  503. }
  504. /*
  505. * Reset buffer descriptor as empty
  506. */
  507. mpc512x_fec_rbd_clean (fec, pRbd);
  508. }
  509. /* Try to fill Buffer Descriptors */
  510. out_be32(&fec->eth->r_des_active, 0x01000000);
  511. return frame_length;
  512. }
  513. /********************************************************************/
  514. int mpc512x_fec_initialize (bd_t * bis)
  515. {
  516. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  517. mpc512x_fec_priv *fec;
  518. struct eth_device *dev;
  519. int i;
  520. char *tmp, *end, env_enetaddr[6];
  521. void * bd;
  522. fec = (mpc512x_fec_priv *) malloc (sizeof(*fec));
  523. dev = (struct eth_device *) malloc (sizeof(*dev));
  524. memset (dev, 0, sizeof *dev);
  525. fec->eth = &im->fec;
  526. # ifndef CONFIG_FEC_10MBIT
  527. fec->xcv_type = MII100;
  528. # else
  529. fec->xcv_type = MII10;
  530. # endif
  531. dev->priv = (void *)fec;
  532. dev->iobase = (int)&im->fec;
  533. dev->init = mpc512x_fec_init;
  534. dev->halt = mpc512x_fec_halt;
  535. dev->send = mpc512x_fec_send;
  536. dev->recv = mpc512x_fec_recv;
  537. sprintf (dev->name, "FEC ETHERNET");
  538. eth_register (dev);
  539. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
  540. miiphy_register (dev->name,
  541. fec512x_miiphy_read, fec512x_miiphy_write);
  542. #endif
  543. /* Clean up space FEC's MIB and FIFO RAM ...*/
  544. memset ((void *)&im->fec.mib, 0x00, sizeof(im->fec.mib));
  545. memset ((void *)&im->fec.fifo, 0x00, sizeof(im->fec.fifo));
  546. /*
  547. * Malloc space for BDs (must be quad word-aligned)
  548. * this pointer is lost, so cannot be freed
  549. */
  550. bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f);
  551. fec->bdBase = (mpc512x_buff_descs*)((u32)bd & 0xfffffff0);
  552. memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f);
  553. /*
  554. * Set interrupt mask register
  555. */
  556. out_be32(&fec->eth->imask, 0x00000000);
  557. /*
  558. * Clear FEC-Lite interrupt event register(IEVENT)
  559. */
  560. out_be32(&fec->eth->ievent, 0xffffffff);
  561. /*
  562. * Try to set the mac address now. The fec mac address is
  563. * a garbage after reset. When not using fec for booting
  564. * the Linux fec driver will try to work with this garbage.
  565. */
  566. tmp = getenv ("ethaddr");
  567. if (tmp) {
  568. for (i=0; i<6; i++) {
  569. env_enetaddr[i] = tmp ? simple_strtoul (tmp, &end, 16) : 0;
  570. if (tmp)
  571. tmp = (*end) ? end+1 : end;
  572. }
  573. mpc512x_fec_set_hwaddr (fec, env_enetaddr);
  574. out_be32(&fec->eth->gaddr1, 0x00000000);
  575. out_be32(&fec->eth->gaddr2, 0x00000000);
  576. }
  577. mpc512x_fec_init_phy (dev, bis);
  578. return 1;
  579. }
  580. /* MII-interface related functions */
  581. /********************************************************************/
  582. int fec512x_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
  583. {
  584. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  585. volatile fec512x_t *eth = &im->fec;
  586. u32 reg; /* convenient holder for the PHY register */
  587. u32 phy; /* convenient holder for the PHY */
  588. int timeout = 0xffff;
  589. /*
  590. * reading from any PHY's register is done by properly
  591. * programming the FEC's MII data register.
  592. */
  593. reg = regAddr << FEC_MII_DATA_RA_SHIFT;
  594. phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
  595. out_be32(&eth->mii_data, FEC_MII_DATA_ST |
  596. FEC_MII_DATA_OP_RD |
  597. FEC_MII_DATA_TA |
  598. phy | reg);
  599. /*
  600. * wait for the related interrupt
  601. */
  602. while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
  603. ;
  604. if (timeout == 0) {
  605. #if (DEBUG & 0x2)
  606. printf ("Read MDIO failed...\n");
  607. #endif
  608. return -1;
  609. }
  610. /*
  611. * clear mii interrupt bit
  612. */
  613. out_be32(&eth->ievent, 0x00800000);
  614. /*
  615. * it's now safe to read the PHY's register
  616. */
  617. *retVal = (u16) in_be32(&eth->mii_data);
  618. return 0;
  619. }
  620. /********************************************************************/
  621. int fec512x_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16 data)
  622. {
  623. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  624. volatile fec512x_t *eth = &im->fec;
  625. u32 reg; /* convenient holder for the PHY register */
  626. u32 phy; /* convenient holder for the PHY */
  627. int timeout = 0xffff;
  628. reg = regAddr << FEC_MII_DATA_RA_SHIFT;
  629. phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
  630. out_be32(&eth->mii_data, FEC_MII_DATA_ST |
  631. FEC_MII_DATA_OP_WR |
  632. FEC_MII_DATA_TA |
  633. phy | reg | data);
  634. /*
  635. * wait for the MII interrupt
  636. */
  637. while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
  638. ;
  639. if (timeout == 0) {
  640. #if (DEBUG & 0x2)
  641. printf ("Write MDIO failed...\n");
  642. #endif
  643. return -1;
  644. }
  645. /*
  646. * clear MII interrupt bit
  647. */
  648. out_be32(&eth->ievent, 0x00800000);
  649. return 0;
  650. }
  651. #endif /* CONFIG_MPC512x_FEC */