mpc512x_fec.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  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_MII) || defined(CONFIG_CMD_MII))
  18. #error "CONFIG_MII has to be defined!"
  19. #endif
  20. int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
  21. int regAddr);
  22. int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
  23. int 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, unsigned 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. mpc512x_fec_set_hwaddr (fec, dev->enetaddr);
  197. out_be32(&fec->eth->gaddr1, 0x00000000);
  198. out_be32(&fec->eth->gaddr2, 0x00000000);
  199. mpc512x_fec_init_phy (dev, bis);
  200. /* Set interrupt mask register */
  201. out_be32(&fec->eth->imask, 0x00000000);
  202. /* Clear FEC-Lite interrupt event register(IEVENT) */
  203. out_be32(&fec->eth->ievent, 0xffffffff);
  204. /* Set transmit fifo watermark register(X_WMRK), default = 64 */
  205. out_be32(&fec->eth->x_wmrk, 0x0);
  206. /* Set Opcode/Pause Duration Register */
  207. out_be32(&fec->eth->op_pause, 0x00010020);
  208. /* Frame length=1522; MII mode */
  209. out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x24);
  210. /* Half-duplex, heartbeat disabled */
  211. out_be32(&fec->eth->x_cntrl, 0x00000000);
  212. /* Enable MIB counters */
  213. out_be32(&fec->eth->mib_control, 0x0);
  214. /* Setup recv fifo start and buff size */
  215. out_be32(&fec->eth->r_fstart, 0x500);
  216. out_be32(&fec->eth->r_buff_size, FEC_BUFFER_SIZE);
  217. /* Setup BD base addresses */
  218. out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd);
  219. out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd);
  220. /* DMA Control */
  221. out_be32(&fec->eth->dma_control, 0xc0000000);
  222. /* Enable FEC */
  223. setbits_be32(&fec->eth->ecntrl, 0x00000006);
  224. /* Initilize addresses and status words of BDs */
  225. mpc512x_fec_bd_init (fec);
  226. /* Descriptor polling active */
  227. out_be32(&fec->eth->r_des_active, 0x01000000);
  228. #if (DEBUG & 0x1)
  229. printf("mpc512x_fec_init... Done \n");
  230. #endif
  231. return 1;
  232. }
  233. /********************************************************************/
  234. int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
  235. {
  236. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  237. const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
  238. int timeout = 1;
  239. u16 phyStatus;
  240. #if (DEBUG & 0x1)
  241. printf ("mpc512x_fec_init_phy... Begin\n");
  242. #endif
  243. /*
  244. * Clear FEC-Lite interrupt event register(IEVENT)
  245. */
  246. out_be32(&fec->eth->ievent, 0xffffffff);
  247. /*
  248. * Set interrupt mask register
  249. */
  250. out_be32(&fec->eth->imask, 0x00000000);
  251. if (fec->xcv_type != SEVENWIRE) {
  252. /*
  253. * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
  254. * and do not drop the Preamble.
  255. */
  256. out_be32(&fec->eth->mii_speed,
  257. (((gd->arch.ips_clk / 1000000) / 5) + 1) << 1);
  258. /*
  259. * Reset PHY, then delay 300ns
  260. */
  261. miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
  262. udelay (1000);
  263. if (fec->xcv_type == MII10) {
  264. /*
  265. * Force 10Base-T, FDX operation
  266. */
  267. #if (DEBUG & 0x2)
  268. printf ("Forcing 10 Mbps ethernet link... ");
  269. #endif
  270. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  271. miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
  272. timeout = 20;
  273. do { /* wait for link status to go down */
  274. udelay (10000);
  275. if ((timeout--) == 0) {
  276. #if (DEBUG & 0x2)
  277. printf ("hmmm, should not have waited...");
  278. #endif
  279. break;
  280. }
  281. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  282. #if (DEBUG & 0x2)
  283. printf ("=");
  284. #endif
  285. } while ((phyStatus & 0x0004)); /* !link up */
  286. timeout = 1000;
  287. do { /* wait for link status to come back up */
  288. udelay (10000);
  289. if ((timeout--) == 0) {
  290. printf ("failed. Link is down.\n");
  291. break;
  292. }
  293. miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
  294. #if (DEBUG & 0x2)
  295. printf ("+");
  296. #endif
  297. } while (!(phyStatus & 0x0004)); /* !link up */
  298. #if (DEBUG & 0x2)
  299. printf ("done.\n");
  300. #endif
  301. } else { /* MII100 */
  302. /*
  303. * Set the auto-negotiation advertisement register bits
  304. */
  305. miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
  306. /*
  307. * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
  308. */
  309. miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
  310. /*
  311. * Wait for AN completion
  312. */
  313. timeout = 2500;
  314. do {
  315. udelay (1000);
  316. if ((timeout--) == 0) {
  317. #if (DEBUG & 0x2)
  318. printf ("PHY auto neg 0 failed...\n");
  319. #endif
  320. return -1;
  321. }
  322. if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) {
  323. #if (DEBUG & 0x2)
  324. printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
  325. #endif
  326. return -1;
  327. }
  328. } while (!(phyStatus & 0x0004));
  329. #if (DEBUG & 0x2)
  330. printf ("PHY auto neg complete! \n");
  331. #endif
  332. }
  333. }
  334. #if (DEBUG & 0x2)
  335. if (fec->xcv_type != SEVENWIRE)
  336. mpc512x_fec_phydump (dev->name);
  337. #endif
  338. #if (DEBUG & 0x1)
  339. printf ("mpc512x_fec_init_phy... Done \n");
  340. #endif
  341. return 1;
  342. }
  343. /********************************************************************/
  344. static void mpc512x_fec_halt (struct eth_device *dev)
  345. {
  346. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  347. int counter = 0xffff;
  348. #if (DEBUG & 0x2)
  349. if (fec->xcv_type != SEVENWIRE)
  350. mpc512x_fec_phydump (dev->name);
  351. #endif
  352. /*
  353. * mask FEC chip interrupts
  354. */
  355. out_be32(&fec->eth->imask, 0);
  356. /*
  357. * issue graceful stop command to the FEC transmitter if necessary
  358. */
  359. setbits_be32(&fec->eth->x_cntrl, 0x00000001);
  360. /*
  361. * wait for graceful stop to register
  362. */
  363. while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000)))
  364. ;
  365. /*
  366. * Disable the Ethernet Controller
  367. */
  368. clrbits_be32(&fec->eth->ecntrl, 0x00000002);
  369. /*
  370. * Issue a reset command to the FEC chip
  371. */
  372. setbits_be32(&fec->eth->ecntrl, 0x1);
  373. /*
  374. * wait at least 16 clock cycles
  375. */
  376. udelay (10);
  377. #if (DEBUG & 0x3)
  378. printf ("Ethernet task stopped\n");
  379. #endif
  380. }
  381. /********************************************************************/
  382. static int mpc512x_fec_send(struct eth_device *dev, void *eth_data,
  383. int data_length)
  384. {
  385. /*
  386. * This routine transmits one frame. This routine only accepts
  387. * 6-byte Ethernet addresses.
  388. */
  389. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  390. volatile FEC_TBD *pTbd;
  391. #if (DEBUG & 0x20)
  392. printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status);
  393. #endif
  394. /*
  395. * Clear Tx BD ring at first
  396. */
  397. mpc512x_fec_tbd_scrub (fec);
  398. /*
  399. * Check for valid length of data.
  400. */
  401. if ((data_length > 1500) || (data_length <= 0)) {
  402. return -1;
  403. }
  404. /*
  405. * Check the number of vacant TxBDs.
  406. */
  407. if (fec->cleanTbdNum < 1) {
  408. #if (DEBUG & 0x20)
  409. printf ("No available TxBDs ...\n");
  410. #endif
  411. return -1;
  412. }
  413. /*
  414. * Get the first TxBD to send the mac header
  415. */
  416. pTbd = &fec->bdBase->tbd[fec->tbdIndex];
  417. pTbd->dataLength = data_length;
  418. pTbd->dataPointer = (u32)eth_data;
  419. pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
  420. fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
  421. /* Activate transmit Buffer Descriptor polling */
  422. out_be32(&fec->eth->x_des_active, 0x01000000);
  423. #if (DEBUG & 0x8)
  424. printf ( "+" );
  425. #endif
  426. fec->cleanTbdNum -= 1;
  427. /*
  428. * wait until frame is sent .
  429. */
  430. while (pTbd->status & FEC_TBD_READY) {
  431. udelay (10);
  432. #if (DEBUG & 0x8)
  433. printf ("TDB status = %04x\n", pTbd->status);
  434. #endif
  435. }
  436. return 0;
  437. }
  438. /********************************************************************/
  439. static int mpc512x_fec_recv (struct eth_device *dev)
  440. {
  441. /*
  442. * This command pulls one frame from the card
  443. */
  444. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  445. volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
  446. unsigned long ievent;
  447. int frame_length = 0;
  448. #if (DEBUG & 0x1)
  449. printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
  450. #endif
  451. #if (DEBUG & 0x8)
  452. printf( "-" );
  453. #endif
  454. /*
  455. * Check if any critical events have happened
  456. */
  457. ievent = in_be32(&fec->eth->ievent);
  458. out_be32(&fec->eth->ievent, ievent);
  459. if (ievent & 0x20060000) {
  460. /* BABT, Rx/Tx FIFO errors */
  461. mpc512x_fec_halt (dev);
  462. mpc512x_fec_init (dev, NULL);
  463. return 0;
  464. }
  465. if (ievent & 0x80000000) {
  466. /* Heartbeat error */
  467. setbits_be32(&fec->eth->x_cntrl, 0x00000001);
  468. }
  469. if (ievent & 0x10000000) {
  470. /* Graceful stop complete */
  471. if (in_be32(&fec->eth->x_cntrl) & 0x00000001) {
  472. mpc512x_fec_halt (dev);
  473. clrbits_be32(&fec->eth->x_cntrl, 0x00000001);
  474. mpc512x_fec_init (dev, NULL);
  475. }
  476. }
  477. if (!(pRbd->status & FEC_RBD_EMPTY)) {
  478. if (!(pRbd->status & FEC_RBD_ERR) &&
  479. ((pRbd->dataLength - 4) > 14)) {
  480. /*
  481. * Get buffer size
  482. */
  483. if (pRbd->status & FEC_RBD_LAST)
  484. frame_length = pRbd->dataLength - 4;
  485. else
  486. frame_length = pRbd->dataLength;
  487. #if (DEBUG & 0x20)
  488. {
  489. int i;
  490. printf ("recv data length 0x%08x data hdr: ",
  491. pRbd->dataLength);
  492. for (i = 0; i < 14; i++)
  493. printf ("%x ", *((u8*)pRbd->dataPointer + i));
  494. printf("\n");
  495. }
  496. #endif
  497. /*
  498. * Fill the buffer and pass it to upper layers
  499. */
  500. memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
  501. frame_length - rx_buff_idx);
  502. rx_buff_idx = frame_length;
  503. if (pRbd->status & FEC_RBD_LAST) {
  504. net_process_received_packet((uchar *)rx_buff,
  505. frame_length);
  506. rx_buff_idx = 0;
  507. }
  508. }
  509. /*
  510. * Reset buffer descriptor as empty
  511. */
  512. mpc512x_fec_rbd_clean (fec, pRbd);
  513. }
  514. /* Try to fill Buffer Descriptors */
  515. out_be32(&fec->eth->r_des_active, 0x01000000);
  516. return frame_length;
  517. }
  518. /********************************************************************/
  519. int mpc512x_fec_initialize (bd_t * bis)
  520. {
  521. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  522. mpc512x_fec_priv *fec;
  523. struct eth_device *dev;
  524. void * bd;
  525. fec = (mpc512x_fec_priv *) malloc (sizeof(*fec));
  526. dev = (struct eth_device *) malloc (sizeof(*dev));
  527. memset (dev, 0, sizeof *dev);
  528. fec->eth = &im->fec;
  529. # ifndef CONFIG_FEC_10MBIT
  530. fec->xcv_type = MII100;
  531. # else
  532. fec->xcv_type = MII10;
  533. # endif
  534. dev->priv = (void *)fec;
  535. dev->iobase = (int)&im->fec;
  536. dev->init = mpc512x_fec_init;
  537. dev->halt = mpc512x_fec_halt;
  538. dev->send = mpc512x_fec_send;
  539. dev->recv = mpc512x_fec_recv;
  540. strcpy(dev->name, "FEC");
  541. eth_register (dev);
  542. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
  543. int retval;
  544. struct mii_dev *mdiodev = mdio_alloc();
  545. if (!mdiodev)
  546. return -ENOMEM;
  547. strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
  548. mdiodev->read = fec512x_miiphy_read;
  549. mdiodev->write = fec512x_miiphy_write;
  550. retval = mdio_register(mdiodev);
  551. if (retval < 0)
  552. return retval;
  553. #endif
  554. /* Clean up space FEC's MIB and FIFO RAM ...*/
  555. memset ((void *)&im->fec.mib, 0x00, sizeof(im->fec.mib));
  556. memset ((void *)&im->fec.fifo, 0x00, sizeof(im->fec.fifo));
  557. /*
  558. * Malloc space for BDs (must be quad word-aligned)
  559. * this pointer is lost, so cannot be freed
  560. */
  561. bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f);
  562. fec->bdBase = (mpc512x_buff_descs*)((u32)bd & 0xfffffff0);
  563. memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f);
  564. /*
  565. * Set interrupt mask register
  566. */
  567. out_be32(&fec->eth->imask, 0x00000000);
  568. /*
  569. * Clear FEC-Lite interrupt event register(IEVENT)
  570. */
  571. out_be32(&fec->eth->ievent, 0xffffffff);
  572. return 1;
  573. }
  574. /* MII-interface related functions */
  575. /********************************************************************/
  576. int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
  577. int regAddr)
  578. {
  579. u16 retVal = 0;
  580. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  581. volatile fec512x_t *eth = &im->fec;
  582. u32 reg; /* convenient holder for the PHY register */
  583. u32 phy; /* convenient holder for the PHY */
  584. int timeout = 0xffff;
  585. /*
  586. * reading from any PHY's register is done by properly
  587. * programming the FEC's MII data register.
  588. */
  589. reg = regAddr << FEC_MII_DATA_RA_SHIFT;
  590. phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
  591. out_be32(&eth->mii_data, FEC_MII_DATA_ST |
  592. FEC_MII_DATA_OP_RD |
  593. FEC_MII_DATA_TA |
  594. phy | reg);
  595. /*
  596. * wait for the related interrupt
  597. */
  598. while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
  599. ;
  600. if (timeout == 0) {
  601. #if (DEBUG & 0x2)
  602. printf ("Read MDIO failed...\n");
  603. #endif
  604. return -1;
  605. }
  606. /*
  607. * clear mii interrupt bit
  608. */
  609. out_be32(&eth->ievent, 0x00800000);
  610. /*
  611. * it's now safe to read the PHY's register
  612. */
  613. retVal = (u16) in_be32(&eth->mii_data);
  614. return retVal;
  615. }
  616. /********************************************************************/
  617. int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
  618. int regAddr, u16 data)
  619. {
  620. volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  621. volatile fec512x_t *eth = &im->fec;
  622. u32 reg; /* convenient holder for the PHY register */
  623. u32 phy; /* convenient holder for the PHY */
  624. int timeout = 0xffff;
  625. reg = regAddr << FEC_MII_DATA_RA_SHIFT;
  626. phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
  627. out_be32(&eth->mii_data, FEC_MII_DATA_ST |
  628. FEC_MII_DATA_OP_WR |
  629. FEC_MII_DATA_TA |
  630. phy | reg | data);
  631. /*
  632. * wait for the MII interrupt
  633. */
  634. while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
  635. ;
  636. if (timeout == 0) {
  637. #if (DEBUG & 0x2)
  638. printf ("Write MDIO failed...\n");
  639. #endif
  640. return -1;
  641. }
  642. /*
  643. * clear MII interrupt bit
  644. */
  645. out_be32(&eth->ievent, 0x00800000);
  646. return 0;
  647. }