bfin_mac.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /*
  2. * Driver for Blackfin On-Chip MAC device
  3. *
  4. * Copyright (c) 2005-2008 Analog Device, Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <config.h>
  10. #include <net.h>
  11. #include <netdev.h>
  12. #include <command.h>
  13. #include <malloc.h>
  14. #include <asm/blackfin.h>
  15. #include <asm/mach-common/bits/dma.h>
  16. #include <asm/mach-common/bits/emac.h>
  17. #include <asm/mach-common/bits/pll.h>
  18. #include "bfin_mac.h"
  19. #ifdef CONFIG_POST
  20. #include <post.h>
  21. #endif
  22. #undef DEBUG_ETHERNET
  23. #ifdef DEBUG_ETHERNET
  24. #define DEBUGF(fmt, args...) printf(fmt, ##args)
  25. #else
  26. #define DEBUGF(fmt, args...)
  27. #endif
  28. #define RXBUF_BASE_ADDR 0xFF900000
  29. #define TXBUF_BASE_ADDR 0xFF800000
  30. #define TX_BUF_CNT 1
  31. #define TOUT_LOOP 1000000
  32. ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
  33. ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
  34. static u16 txIdx; /* index of the current RX buffer */
  35. static u16 rxIdx; /* index of the current TX buffer */
  36. u16 PHYregs[NO_PHY_REGS]; /* u16 PHYADDR; */
  37. /* DMAx_CONFIG values at DMA Restart */
  38. const ADI_DMA_CONFIG_REG rxdmacfg = {
  39. .b_DMA_EN = 1, /* enabled */
  40. .b_WNR = 1, /* write to memory */
  41. .b_WDSIZE = 2, /* wordsize is 32 bits */
  42. .b_DMA2D = 0,
  43. .b_RESTART = 0,
  44. .b_DI_SEL = 0,
  45. .b_DI_EN = 0, /* no interrupt */
  46. .b_NDSIZE = 5, /* 5 half words is desc size */
  47. .b_FLOW = 7 /* large desc flow */
  48. };
  49. const ADI_DMA_CONFIG_REG txdmacfg = {
  50. .b_DMA_EN = 1, /* enabled */
  51. .b_WNR = 0, /* read from memory */
  52. .b_WDSIZE = 2, /* wordsize is 32 bits */
  53. .b_DMA2D = 0,
  54. .b_RESTART = 0,
  55. .b_DI_SEL = 0,
  56. .b_DI_EN = 0, /* no interrupt */
  57. .b_NDSIZE = 5, /* 5 half words is desc size */
  58. .b_FLOW = 7 /* large desc flow */
  59. };
  60. int bfin_EMAC_initialize(bd_t *bis)
  61. {
  62. struct eth_device *dev;
  63. dev = (struct eth_device *)malloc(sizeof(*dev));
  64. if (dev == NULL)
  65. hang();
  66. memset(dev, 0, sizeof(*dev));
  67. sprintf(dev->name, "Blackfin EMAC");
  68. dev->iobase = 0;
  69. dev->priv = 0;
  70. dev->init = bfin_EMAC_init;
  71. dev->halt = bfin_EMAC_halt;
  72. dev->send = bfin_EMAC_send;
  73. dev->recv = bfin_EMAC_recv;
  74. eth_register(dev);
  75. return 0;
  76. }
  77. static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
  78. int length)
  79. {
  80. int i;
  81. int result = 0;
  82. unsigned int *buf;
  83. buf = (unsigned int *)packet;
  84. if (length <= 0) {
  85. printf("Ethernet: bad packet size: %d\n", length);
  86. goto out;
  87. }
  88. if ((*pDMA2_IRQ_STATUS & DMA_ERR) != 0) {
  89. printf("Ethernet: tx DMA error\n");
  90. goto out;
  91. }
  92. for (i = 0; (*pDMA2_IRQ_STATUS & DMA_RUN) != 0; i++) {
  93. if (i > TOUT_LOOP) {
  94. puts("Ethernet: tx time out\n");
  95. goto out;
  96. }
  97. }
  98. txbuf[txIdx]->FrmData->NoBytes = length;
  99. memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
  100. txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
  101. *pDMA2_NEXT_DESC_PTR = &txbuf[txIdx]->Dma[0];
  102. *pDMA2_CONFIG = *(u16 *) (void *)(&txdmacfg);
  103. *pEMAC_OPMODE |= TE;
  104. for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
  105. if (i > TOUT_LOOP) {
  106. puts("Ethernet: tx error\n");
  107. goto out;
  108. }
  109. }
  110. result = txbuf[txIdx]->StatusWord;
  111. txbuf[txIdx]->StatusWord = 0;
  112. if ((txIdx + 1) >= TX_BUF_CNT)
  113. txIdx = 0;
  114. else
  115. txIdx++;
  116. out:
  117. DEBUGF("BFIN EMAC send: length = %d\n", length);
  118. return result;
  119. }
  120. static int bfin_EMAC_recv(struct eth_device *dev)
  121. {
  122. int length = 0;
  123. for (;;) {
  124. if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
  125. length = -1;
  126. break;
  127. }
  128. if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
  129. printf("Ethernet: rx dma overrun\n");
  130. break;
  131. }
  132. if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
  133. printf("Ethernet: rx error\n");
  134. break;
  135. }
  136. length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
  137. if (length <= 4) {
  138. printf("Ethernet: bad frame\n");
  139. break;
  140. }
  141. NetRxPackets[rxIdx] =
  142. (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest);
  143. NetReceive(NetRxPackets[rxIdx], length - 4);
  144. *pDMA1_IRQ_STATUS |= DMA_DONE | DMA_ERR;
  145. rxbuf[rxIdx]->StatusWord = 0x00000000;
  146. if ((rxIdx + 1) >= PKTBUFSRX)
  147. rxIdx = 0;
  148. else
  149. rxIdx++;
  150. }
  151. return length;
  152. }
  153. /**************************************************************
  154. *
  155. * Ethernet Initialization Routine
  156. *
  157. *************************************************************/
  158. static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
  159. {
  160. u32 opmode;
  161. int dat;
  162. int i;
  163. DEBUGF("Eth_init: ......\n");
  164. txIdx = 0;
  165. rxIdx = 0;
  166. /* Initialize System Register */
  167. if (SetupSystemRegs(&dat) < 0)
  168. return -1;
  169. /* Initialize EMAC address */
  170. bfin_EMAC_setup_addr(bd);
  171. /* Initialize TX and RX buffer */
  172. for (i = 0; i < PKTBUFSRX; i++) {
  173. rxbuf[i] = SetupRxBuffer(i);
  174. if (i > 0) {
  175. rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
  176. &(rxbuf[i]->Dma[0]);
  177. if (i == (PKTBUFSRX - 1))
  178. rxbuf[i]->Dma[1].NEXT_DESC_PTR =
  179. &(rxbuf[0]->Dma[0]);
  180. }
  181. }
  182. for (i = 0; i < TX_BUF_CNT; i++) {
  183. txbuf[i] = SetupTxBuffer(i);
  184. if (i > 0) {
  185. txbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
  186. &(txbuf[i]->Dma[0]);
  187. if (i == (TX_BUF_CNT - 1))
  188. txbuf[i]->Dma[1].NEXT_DESC_PTR =
  189. &(txbuf[0]->Dma[0]);
  190. }
  191. }
  192. /* Set RX DMA */
  193. *pDMA1_NEXT_DESC_PTR = &rxbuf[0]->Dma[0];
  194. *pDMA1_CONFIG = *((u16 *) (void *)&rxbuf[0]->Dma[0].CONFIG);
  195. /* Wait MII done */
  196. PollMdcDone();
  197. /* We enable only RX here */
  198. /* ASTP : Enable Automatic Pad Stripping
  199. PR : Promiscuous Mode for test
  200. PSF : Receive frames with total length less than 64 bytes.
  201. FDMODE : Full Duplex Mode
  202. LB : Internal Loopback for test
  203. RE : Receiver Enable */
  204. if (dat == FDMODE)
  205. opmode = ASTP | FDMODE | PSF;
  206. else
  207. opmode = ASTP | PSF;
  208. opmode |= RE;
  209. #ifdef CONFIG_BFIN_MAC_RMII
  210. opmode |= TE | RMII;
  211. #endif
  212. /* Turn on the EMAC */
  213. *pEMAC_OPMODE = opmode;
  214. return 0;
  215. }
  216. static void bfin_EMAC_halt(struct eth_device *dev)
  217. {
  218. DEBUGF("Eth_halt: ......\n");
  219. /* Turn off the EMAC */
  220. *pEMAC_OPMODE = 0x00000000;
  221. /* Turn off the EMAC RX DMA */
  222. *pDMA1_CONFIG = 0x0000;
  223. *pDMA2_CONFIG = 0x0000;
  224. }
  225. void bfin_EMAC_setup_addr(bd_t *bd)
  226. {
  227. *pEMAC_ADDRLO =
  228. bd->bi_enetaddr[0] |
  229. bd->bi_enetaddr[1] << 8 |
  230. bd->bi_enetaddr[2] << 16 |
  231. bd->bi_enetaddr[3] << 24;
  232. *pEMAC_ADDRHI =
  233. bd->bi_enetaddr[4] |
  234. bd->bi_enetaddr[5] << 8;
  235. }
  236. static void PollMdcDone(void)
  237. {
  238. /* poll the STABUSY bit */
  239. while (*pEMAC_STAADD & STABUSY) ;
  240. }
  241. static void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data)
  242. {
  243. PollMdcDone();
  244. *pEMAC_STADAT = Data;
  245. *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
  246. STAOP | STAIE | STABUSY;
  247. }
  248. /*********************************************************************************
  249. * Read an off-chip register in a PHY through the MDC/MDIO port *
  250. *********************************************************************************/
  251. static u16 RdPHYReg(u16 PHYAddr, u16 RegAddr)
  252. {
  253. u16 Data;
  254. PollMdcDone();
  255. *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
  256. STAIE | STABUSY;
  257. PollMdcDone();
  258. Data = (u16) * pEMAC_STADAT;
  259. PHYregs[RegAddr] = Data; /* save shadow copy */
  260. return Data;
  261. }
  262. #if 0 /* dead code ? */
  263. static void SoftResetPHY(void)
  264. {
  265. u16 phydat;
  266. /* set the reset bit */
  267. WrPHYReg(PHYADDR, PHY_MODECTL, PHY_RESET);
  268. /* and clear it again */
  269. WrPHYReg(PHYADDR, PHY_MODECTL, 0x0000);
  270. do {
  271. /* poll until reset is complete */
  272. phydat = RdPHYReg(PHYADDR, PHY_MODECTL);
  273. } while ((phydat & PHY_RESET) != 0);
  274. }
  275. #endif
  276. /* MDC = SCLK / MDC_freq / 2 - 1 */
  277. #define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1)
  278. static int SetupSystemRegs(int *opmode)
  279. {
  280. u16 phydat;
  281. int count = 0;
  282. /* Enable PHY output */
  283. *pVR_CTL |= CLKBUFOE;
  284. /* Set all the pins to peripheral mode */
  285. #ifdef CONFIG_BFIN_MAC_RMII
  286. /* grab RMII pins */
  287. # if defined(__ADSPBF51x__)
  288. *pPORTF_MUX = (*pPORTF_MUX & \
  289. ~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
  290. PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
  291. *pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
  292. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
  293. *pPORTG_FER |= PG0 | PG1 | PG2;
  294. # elif defined(__ADSPBF52x__)
  295. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
  296. *pPORTG_FER |= PG14 | PG15;
  297. *pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \
  298. PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
  299. *pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8;
  300. # else
  301. *pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15;
  302. # endif
  303. #else
  304. /* grab MII & RMII pins */
  305. # if defined(__ADSPBF51x__)
  306. *pPORTF_MUX = (*pPORTF_MUX & \
  307. ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK | PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
  308. PORT_x_MUX_0_FUNC_1 | PORT_x_MUX_1_FUNC_1 | PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
  309. *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
  310. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
  311. *pPORTG_FER |= PG0 | PG1 | PG2;
  312. # elif defined(__ADSPBF52x__)
  313. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
  314. *pPORTG_FER |= PG14 | PG15;
  315. *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
  316. *pPORTH_FER = -1; /* all pins */
  317. # else
  318. *pPORTH_FER = -1; /* all pins */
  319. # endif
  320. #endif
  321. /* Odd word alignment for Receive Frame DMA word */
  322. /* Configure checksum support and rcve frame word alignment */
  323. *pEMAC_SYSCTL = RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(2500000));
  324. /* auto negotiation on */
  325. /* full duplex */
  326. /* 100 Mbps */
  327. phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
  328. WrPHYReg(PHYADDR, PHY_MODECTL, phydat);
  329. do {
  330. udelay(1000);
  331. phydat = RdPHYReg(PHYADDR, PHY_MODESTAT);
  332. if (count > 3000) {
  333. printf
  334. ("Link is down, please check your network connection\n");
  335. return -1;
  336. }
  337. count++;
  338. } while (!(phydat & 0x0004));
  339. phydat = RdPHYReg(PHYADDR, PHY_ANLPAR);
  340. if ((phydat & 0x0100) || (phydat & 0x0040))
  341. *opmode = FDMODE;
  342. else
  343. *opmode = 0;
  344. *pEMAC_MMC_CTL = RSTC | CROLL;
  345. /* Initialize the TX DMA channel registers */
  346. *pDMA2_X_COUNT = 0;
  347. *pDMA2_X_MODIFY = 4;
  348. *pDMA2_Y_COUNT = 0;
  349. *pDMA2_Y_MODIFY = 0;
  350. /* Initialize the RX DMA channel registers */
  351. *pDMA1_X_COUNT = 0;
  352. *pDMA1_X_MODIFY = 4;
  353. *pDMA1_Y_COUNT = 0;
  354. *pDMA1_Y_MODIFY = 0;
  355. return 0;
  356. }
  357. ADI_ETHER_BUFFER *SetupRxBuffer(int no)
  358. {
  359. ADI_ETHER_FRAME_BUFFER *frmbuf;
  360. ADI_ETHER_BUFFER *buf;
  361. int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
  362. int total_size = nobytes_buffer + RECV_BUFSIZE;
  363. buf = (ADI_ETHER_BUFFER *) (RXBUF_BASE_ADDR + no * total_size);
  364. frmbuf =
  365. (ADI_ETHER_FRAME_BUFFER *) (RXBUF_BASE_ADDR + no * total_size +
  366. nobytes_buffer);
  367. memset(buf, 0x00, nobytes_buffer);
  368. buf->FrmData = frmbuf;
  369. memset(frmbuf, 0xfe, RECV_BUFSIZE);
  370. /* set up first desc to point to receive frame buffer */
  371. buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
  372. buf->Dma[0].START_ADDR = (u32) buf->FrmData;
  373. buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
  374. buf->Dma[0].CONFIG.b_WNR = 1; /* Write to memory */
  375. buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  376. buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
  377. buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
  378. /* set up second desc to point to status word */
  379. buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
  380. buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
  381. buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
  382. buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
  383. buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  384. buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
  385. buf->Dma[1].CONFIG.b_NDSIZE = 5; /* must be 0 when FLOW is 0 */
  386. buf->Dma[1].CONFIG.b_FLOW = 7; /* stop */
  387. return buf;
  388. }
  389. ADI_ETHER_BUFFER *SetupTxBuffer(int no)
  390. {
  391. ADI_ETHER_FRAME_BUFFER *frmbuf;
  392. ADI_ETHER_BUFFER *buf;
  393. int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
  394. int total_size = nobytes_buffer + RECV_BUFSIZE;
  395. buf = (ADI_ETHER_BUFFER *) (TXBUF_BASE_ADDR + no * total_size);
  396. frmbuf =
  397. (ADI_ETHER_FRAME_BUFFER *) (TXBUF_BASE_ADDR + no * total_size +
  398. nobytes_buffer);
  399. memset(buf, 0x00, nobytes_buffer);
  400. buf->FrmData = frmbuf;
  401. memset(frmbuf, 0x00, RECV_BUFSIZE);
  402. /* set up first desc to point to receive frame buffer */
  403. buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
  404. buf->Dma[0].START_ADDR = (u32) buf->FrmData;
  405. buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
  406. buf->Dma[0].CONFIG.b_WNR = 0; /* Read to memory */
  407. buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  408. buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
  409. buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
  410. /* set up second desc to point to status word */
  411. buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
  412. buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
  413. buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
  414. buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
  415. buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  416. buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
  417. buf->Dma[1].CONFIG.b_NDSIZE = 0; /* must be 0 when FLOW is 0 */
  418. buf->Dma[1].CONFIG.b_FLOW = 0; /* stop */
  419. return buf;
  420. }
  421. #if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER)
  422. int ether_post_test(int flags)
  423. {
  424. uchar buf[64];
  425. int i, value = 0;
  426. int length;
  427. printf("\n--------");
  428. bfin_EMAC_init(NULL, NULL);
  429. /* construct the package */
  430. buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
  431. buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
  432. buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
  433. buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
  434. buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
  435. buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
  436. buf[12] = 0x08; /* Type: ARP */
  437. buf[13] = 0x06;
  438. buf[14] = 0x00; /* Hardware type: Ethernet */
  439. buf[15] = 0x01;
  440. buf[16] = 0x08; /* Protocal type: IP */
  441. buf[17] = 0x00;
  442. buf[18] = 0x06; /* Hardware size */
  443. buf[19] = 0x04; /* Protocol size */
  444. buf[20] = 0x00; /* Opcode: request */
  445. buf[21] = 0x01;
  446. for (i = 0; i < 42; i++)
  447. buf[i + 22] = i;
  448. printf("--------Send 64 bytes......\n");
  449. bfin_EMAC_send(NULL, (volatile void *)buf, 64);
  450. for (i = 0; i < 100; i++) {
  451. udelay(10000);
  452. if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
  453. value = 1;
  454. break;
  455. }
  456. }
  457. if (value == 0) {
  458. printf("--------EMAC can't receive any data\n");
  459. eth_halt();
  460. return -1;
  461. }
  462. length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
  463. for (i = 0; i < length; i++) {
  464. if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
  465. printf("--------EMAC receive error data!\n");
  466. eth_halt();
  467. return -1;
  468. }
  469. }
  470. printf("--------receive %d bytes, matched\n", length);
  471. bfin_EMAC_halt(NULL);
  472. return 0;
  473. }
  474. #endif