mpc512x_fec.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /*
  2. * (C) Copyright 2003-2007
  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 <mpc512x.h>
  10. #include <malloc.h>
  11. #include <net.h>
  12. #include <netdev.h>
  13. #include <miiphy.h>
  14. #include <asm/io.h>
  15. #include "mpc512x_fec.h"
  16. DECLARE_GLOBAL_DATA_PTR;
  17. #define DEBUG 0
  18. #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
  19. defined(CONFIG_MPC512x_FEC)
  20. #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
  21. #error "CONFIG_MII has to be defined!"
  22. #endif
  23. #if (DEBUG & 0x40)
  24. static uint32 local_crc32(char *string, unsigned int crc_value, int len);
  25. #endif
  26. int fec512x_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal);
  27. int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
  28. int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
  29. static uchar rx_buff[FEC_BUFFER_SIZE];
  30. static int rx_buff_idx = 0;
  31. /********************************************************************/
  32. #if (DEBUG & 0x2)
  33. static void mpc512x_fec_phydump (char *devname)
  34. {
  35. uint16 phyStatus, i;
  36. uint8 phyAddr = CONFIG_PHY_ADDR;
  37. uint8 reg_mask[] = {
  38. /* regs to print: 0...8, 21,27,31 */
  39. 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
  40. 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
  41. };
  42. for (i = 0; i < 32; i++) {
  43. if (reg_mask[i]) {
  44. miiphy_read (devname, phyAddr, i, &phyStatus);
  45. printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
  46. }
  47. }
  48. }
  49. #endif
  50. /********************************************************************/
  51. static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec)
  52. {
  53. int ix;
  54. /*
  55. * Receive BDs init
  56. */
  57. for (ix = 0; ix < FEC_RBD_NUM; ix++) {
  58. fec->bdBase->rbd[ix].dataPointer =
  59. (uint32)&fec->bdBase->recv_frames[ix];
  60. fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY;
  61. fec->bdBase->rbd[ix].dataLength = 0;
  62. }
  63. /*
  64. * have the last RBD to close the ring
  65. */
  66. fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP;
  67. fec->rbdIndex = 0;
  68. /*
  69. * Trasmit BDs init
  70. */
  71. for (ix = 0; ix < FEC_TBD_NUM; ix++) {
  72. fec->bdBase->tbd[ix].status = 0;
  73. }
  74. /*
  75. * Have the last TBD to close the ring
  76. */
  77. fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP;
  78. /*
  79. * Initialize some indices
  80. */
  81. fec->tbdIndex = 0;
  82. fec->usedTbdIndex = 0;
  83. fec->cleanTbdNum = FEC_TBD_NUM;
  84. return 0;
  85. }
  86. /********************************************************************/
  87. static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd)
  88. {
  89. /*
  90. * Reset buffer descriptor as empty
  91. */
  92. if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
  93. pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
  94. else
  95. pRbd->status = FEC_RBD_EMPTY;
  96. pRbd->dataLength = 0;
  97. /*
  98. * Increment BD count
  99. */
  100. fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
  101. /*
  102. * Now, we have an empty RxBD, notify FEC
  103. * Set Descriptor polling active
  104. */
  105. out_be32(&fec->eth->r_des_active, 0x01000000);
  106. }
  107. /********************************************************************/
  108. static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec)
  109. {
  110. volatile FEC_TBD *pUsedTbd;
  111. #if (DEBUG & 0x1)
  112. printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
  113. fec->cleanTbdNum, fec->usedTbdIndex);
  114. #endif
  115. /*
  116. * process all the consumed TBDs
  117. */
  118. while (fec->cleanTbdNum < FEC_TBD_NUM) {
  119. pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex];
  120. if (pUsedTbd->status & FEC_TBD_READY) {
  121. #if (DEBUG & 0x20)
  122. printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex);
  123. #endif
  124. return;
  125. }
  126. /*
  127. * clean this buffer descriptor
  128. */
  129. if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
  130. pUsedTbd->status = FEC_TBD_WRAP;
  131. else
  132. pUsedTbd->status = 0;
  133. /*
  134. * update some indeces for a correct handling of the TBD ring
  135. */
  136. fec->cleanTbdNum++;
  137. fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
  138. }
  139. }
  140. /********************************************************************/
  141. static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, char *mac)
  142. {
  143. uint8 currByte; /* byte for which to compute the CRC */
  144. int byte; /* loop - counter */
  145. int bit; /* loop - counter */
  146. uint32 crc = 0xffffffff; /* initial value */
  147. /*
  148. * The algorithm used is the following:
  149. * we loop on each of the six bytes of the provided address,
  150. * and we compute the CRC by left-shifting the previous
  151. * value by one position, so that each bit in the current
  152. * byte of the address may contribute the calculation. If
  153. * the latter and the MSB in the CRC are different, then
  154. * the CRC value so computed is also ex-ored with the
  155. * "polynomium generator". The current byte of the address
  156. * is also shifted right by one bit at each iteration.
  157. * This is because the CRC generatore in hardware is implemented
  158. * as a shift-register with as many ex-ores as the radixes
  159. * in the polynomium. This suggests that we represent the
  160. * polynomiumm itself as a 32-bit constant.
  161. */
  162. for (byte = 0; byte < 6; byte++) {
  163. currByte = mac[byte];
  164. for (bit = 0; bit < 8; bit++) {
  165. if ((currByte & 0x01) ^ (crc & 0x01)) {
  166. crc >>= 1;
  167. crc = crc ^ 0xedb88320;
  168. } else {
  169. crc >>= 1;
  170. }
  171. currByte >>= 1;
  172. }
  173. }
  174. crc = crc >> 26;
  175. /*
  176. * Set individual hash table register
  177. */
  178. if (crc >= 32) {
  179. out_be32(&fec->eth->iaddr1, (1 << (crc - 32)));
  180. out_be32(&fec->eth->iaddr2, 0);
  181. } else {
  182. out_be32(&fec->eth->iaddr1, 0);
  183. out_be32(&fec->eth->iaddr2, (1 << crc));
  184. }
  185. /*
  186. * Set physical address
  187. */
  188. out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) +
  189. (mac[2] << 8) + mac[3]);
  190. out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) +
  191. 0x8808);
  192. }
  193. /********************************************************************/
  194. static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
  195. {
  196. mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
  197. #if (DEBUG & 0x1)
  198. printf ("mpc512x_fec_init... Begin\n");
  199. #endif
  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, (uint32)fec->bdBase->rbd);
  219. out_be32(&fec->eth->x_des_start, (uint32)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 uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
  238. int timeout = 1;
  239. uint16 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->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, volatile 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 = (uint32)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 ", *((uint8*)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. NetReceive ((uchar*)rx_buff, frame_length);
  505. rx_buff_idx = 0;
  506. }
  507. }
  508. /*
  509. * Reset buffer descriptor as empty
  510. */
  511. mpc512x_fec_rbd_clean (fec, pRbd);
  512. }
  513. /* Try to fill Buffer Descriptors */
  514. out_be32(&fec->eth->r_des_active, 0x01000000);
  515. return frame_length;
  516. }
  517. /********************************************************************/
  518. int mpc512x_fec_initialize (bd_t * bis)
  519. {
  520. mpc512x_fec_priv *fec;
  521. struct eth_device *dev;
  522. int i;
  523. char *tmp, *end, env_enetaddr[6];
  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 = (ethernet_regs *) MPC512X_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 = MPC512X_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. sprintf (dev->name, "FEC ETHERNET");
  541. eth_register (dev);
  542. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
  543. miiphy_register (dev->name,
  544. fec512x_miiphy_read, fec512x_miiphy_write);
  545. #endif
  546. /* Clean up space FEC's MIB and FIFO RAM ...*/
  547. memset ((void *) MPC512X_FEC + 0x200, 0x00, 0x400);
  548. /*
  549. * Malloc space for BDs (must be quad word-aligned)
  550. * this pointer is lost, so cannot be freed
  551. */
  552. bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f);
  553. fec->bdBase = (mpc512x_buff_descs*)((uint32)bd & 0xfffffff0);
  554. memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f);
  555. /*
  556. * Set interrupt mask register
  557. */
  558. out_be32(&fec->eth->imask, 0x00000000);
  559. /*
  560. * Clear FEC-Lite interrupt event register(IEVENT)
  561. */
  562. out_be32(&fec->eth->ievent, 0xffffffff);
  563. /*
  564. * Try to set the mac address now. The fec mac address is
  565. * a garbage after reset. When not using fec for booting
  566. * the Linux fec driver will try to work with this garbage.
  567. */
  568. tmp = getenv ("ethaddr");
  569. if (tmp) {
  570. for (i=0; i<6; i++) {
  571. env_enetaddr[i] = tmp ? simple_strtoul (tmp, &end, 16) : 0;
  572. if (tmp)
  573. tmp = (*end) ? end+1 : end;
  574. }
  575. mpc512x_fec_set_hwaddr (fec, env_enetaddr);
  576. out_be32(&fec->eth->gaddr1, 0x00000000);
  577. out_be32(&fec->eth->gaddr2, 0x00000000);
  578. }
  579. mpc512x_fec_init_phy (dev, bis);
  580. return 1;
  581. }
  582. /* MII-interface related functions */
  583. /********************************************************************/
  584. int fec512x_miiphy_read (char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
  585. {
  586. ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC;
  587. uint32 reg; /* convenient holder for the PHY register */
  588. uint32 phy; /* convenient holder for the PHY */
  589. int timeout = 0xffff;
  590. /*
  591. * reading from any PHY's register is done by properly
  592. * programming the FEC's MII data register.
  593. */
  594. reg = regAddr << FEC_MII_DATA_RA_SHIFT;
  595. phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
  596. out_be32(&eth->mii_data, FEC_MII_DATA_ST |
  597. FEC_MII_DATA_OP_RD |
  598. FEC_MII_DATA_TA |
  599. phy | reg);
  600. /*
  601. * wait for the related interrupt
  602. */
  603. while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
  604. ;
  605. if (timeout == 0) {
  606. #if (DEBUG & 0x2)
  607. printf ("Read MDIO failed...\n");
  608. #endif
  609. return -1;
  610. }
  611. /*
  612. * clear mii interrupt bit
  613. */
  614. out_be32(&eth->ievent, 0x00800000);
  615. /*
  616. * it's now safe to read the PHY's register
  617. */
  618. *retVal = (uint16) in_be32(&eth->mii_data);
  619. return 0;
  620. }
  621. /********************************************************************/
  622. int fec512x_miiphy_write (char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
  623. {
  624. ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC;
  625. uint32 reg; /* convenient holder for the PHY register */
  626. uint32 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. #if (DEBUG & 0x40)
  652. static uint32 local_crc32 (char *string, unsigned int crc_value, int len)
  653. {
  654. int i;
  655. char c;
  656. unsigned int crc, count;
  657. /*
  658. * crc32 algorithm
  659. */
  660. /*
  661. * crc = 0xffffffff; * The initialized value should be 0xffffffff
  662. */
  663. crc = crc_value;
  664. for (i = len; --i >= 0;) {
  665. c = *string++;
  666. for (count = 0; count < 8; count++) {
  667. if ((c & 0x01) ^ (crc & 0x01)) {
  668. crc >>= 1;
  669. crc = crc ^ 0xedb88320;
  670. } else {
  671. crc >>= 1;
  672. }
  673. c >>= 1;
  674. }
  675. }
  676. /*
  677. * In big endian system, do byte swaping for crc value
  678. */
  679. /**/ return crc;
  680. }
  681. #endif /* DEBUG */
  682. #endif /* CONFIG_MPC512x_FEC */