fec.c 18 KB

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