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. static int SetupSystemRegs(int *opmode)
  277. {
  278. u16 sysctl, phydat;
  279. int count = 0;
  280. /* Enable PHY output */
  281. *pVR_CTL |= CLKBUFOE;
  282. /* Set all the pins to peripheral mode */
  283. #ifdef CONFIG_BFIN_MAC_RMII
  284. /* grab RMII pins */
  285. # if defined(__ADSPBF51x__)
  286. *pPORTF_MUX = (*pPORTF_MUX & \
  287. ~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
  288. PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
  289. *pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
  290. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
  291. *pPORTG_FER |= PG0 | PG1 | PG2;
  292. # elif defined(__ADSPBF52x__)
  293. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
  294. *pPORTG_FER |= PG14 | PG15;
  295. *pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \
  296. PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
  297. *pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8;
  298. # else
  299. *pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15;
  300. # endif
  301. #else
  302. /* grab MII & RMII pins */
  303. # if defined(__ADSPBF51x__)
  304. *pPORTF_MUX = (*pPORTF_MUX & \
  305. ~(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)) | \
  306. 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;
  307. *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
  308. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
  309. *pPORTG_FER |= PG0 | PG1 | PG2;
  310. # elif defined(__ADSPBF52x__)
  311. *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
  312. *pPORTG_FER |= PG14 | PG15;
  313. *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
  314. *pPORTH_FER = -1; /* all pins */
  315. # else
  316. *pPORTH_FER = -1; /* all pins */
  317. # endif
  318. #endif
  319. /* MDC = 2.5 MHz */
  320. sysctl = SET_MDCDIV(24);
  321. /* Odd word alignment for Receive Frame DMA word */
  322. /* Configure checksum support and rcve frame word alignment */
  323. sysctl |= RXDWA | RXCKS;
  324. *pEMAC_SYSCTL = sysctl;
  325. /* auto negotiation on */
  326. /* full duplex */
  327. /* 100 Mbps */
  328. phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
  329. WrPHYReg(PHYADDR, PHY_MODECTL, phydat);
  330. do {
  331. udelay(1000);
  332. phydat = RdPHYReg(PHYADDR, PHY_MODESTAT);
  333. if (count > 3000) {
  334. printf
  335. ("Link is down, please check your network connection\n");
  336. return -1;
  337. }
  338. count++;
  339. } while (!(phydat & 0x0004));
  340. phydat = RdPHYReg(PHYADDR, PHY_ANLPAR);
  341. if ((phydat & 0x0100) || (phydat & 0x0040))
  342. *opmode = FDMODE;
  343. else
  344. *opmode = 0;
  345. *pEMAC_MMC_CTL = RSTC | CROLL;
  346. /* Initialize the TX DMA channel registers */
  347. *pDMA2_X_COUNT = 0;
  348. *pDMA2_X_MODIFY = 4;
  349. *pDMA2_Y_COUNT = 0;
  350. *pDMA2_Y_MODIFY = 0;
  351. /* Initialize the RX DMA channel registers */
  352. *pDMA1_X_COUNT = 0;
  353. *pDMA1_X_MODIFY = 4;
  354. *pDMA1_Y_COUNT = 0;
  355. *pDMA1_Y_MODIFY = 0;
  356. return 0;
  357. }
  358. ADI_ETHER_BUFFER *SetupRxBuffer(int no)
  359. {
  360. ADI_ETHER_FRAME_BUFFER *frmbuf;
  361. ADI_ETHER_BUFFER *buf;
  362. int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
  363. int total_size = nobytes_buffer + RECV_BUFSIZE;
  364. buf = (ADI_ETHER_BUFFER *) (RXBUF_BASE_ADDR + no * total_size);
  365. frmbuf =
  366. (ADI_ETHER_FRAME_BUFFER *) (RXBUF_BASE_ADDR + no * total_size +
  367. nobytes_buffer);
  368. memset(buf, 0x00, nobytes_buffer);
  369. buf->FrmData = frmbuf;
  370. memset(frmbuf, 0xfe, RECV_BUFSIZE);
  371. /* set up first desc to point to receive frame buffer */
  372. buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
  373. buf->Dma[0].START_ADDR = (u32) buf->FrmData;
  374. buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
  375. buf->Dma[0].CONFIG.b_WNR = 1; /* Write to memory */
  376. buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  377. buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
  378. buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
  379. /* set up second desc to point to status word */
  380. buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
  381. buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
  382. buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
  383. buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
  384. buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  385. buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
  386. buf->Dma[1].CONFIG.b_NDSIZE = 5; /* must be 0 when FLOW is 0 */
  387. buf->Dma[1].CONFIG.b_FLOW = 7; /* stop */
  388. return buf;
  389. }
  390. ADI_ETHER_BUFFER *SetupTxBuffer(int no)
  391. {
  392. ADI_ETHER_FRAME_BUFFER *frmbuf;
  393. ADI_ETHER_BUFFER *buf;
  394. int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
  395. int total_size = nobytes_buffer + RECV_BUFSIZE;
  396. buf = (ADI_ETHER_BUFFER *) (TXBUF_BASE_ADDR + no * total_size);
  397. frmbuf =
  398. (ADI_ETHER_FRAME_BUFFER *) (TXBUF_BASE_ADDR + no * total_size +
  399. nobytes_buffer);
  400. memset(buf, 0x00, nobytes_buffer);
  401. buf->FrmData = frmbuf;
  402. memset(frmbuf, 0x00, RECV_BUFSIZE);
  403. /* set up first desc to point to receive frame buffer */
  404. buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
  405. buf->Dma[0].START_ADDR = (u32) buf->FrmData;
  406. buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
  407. buf->Dma[0].CONFIG.b_WNR = 0; /* Read to memory */
  408. buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  409. buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
  410. buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
  411. /* set up second desc to point to status word */
  412. buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
  413. buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
  414. buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
  415. buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
  416. buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
  417. buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
  418. buf->Dma[1].CONFIG.b_NDSIZE = 0; /* must be 0 when FLOW is 0 */
  419. buf->Dma[1].CONFIG.b_FLOW = 0; /* stop */
  420. return buf;
  421. }
  422. #if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER)
  423. int ether_post_test(int flags)
  424. {
  425. uchar buf[64];
  426. int i, value = 0;
  427. int length;
  428. printf("\n--------");
  429. bfin_EMAC_init(NULL, NULL);
  430. /* construct the package */
  431. buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
  432. buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
  433. buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
  434. buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
  435. buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
  436. buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
  437. buf[12] = 0x08; /* Type: ARP */
  438. buf[13] = 0x06;
  439. buf[14] = 0x00; /* Hardware type: Ethernet */
  440. buf[15] = 0x01;
  441. buf[16] = 0x08; /* Protocal type: IP */
  442. buf[17] = 0x00;
  443. buf[18] = 0x06; /* Hardware size */
  444. buf[19] = 0x04; /* Protocol size */
  445. buf[20] = 0x00; /* Opcode: request */
  446. buf[21] = 0x01;
  447. for (i = 0; i < 42; i++)
  448. buf[i + 22] = i;
  449. printf("--------Send 64 bytes......\n");
  450. bfin_EMAC_send(NULL, (volatile void *)buf, 64);
  451. for (i = 0; i < 100; i++) {
  452. udelay(10000);
  453. if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
  454. value = 1;
  455. break;
  456. }
  457. }
  458. if (value == 0) {
  459. printf("--------EMAC can't receive any data\n");
  460. eth_halt();
  461. return -1;
  462. }
  463. length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
  464. for (i = 0; i < length; i++) {
  465. if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
  466. printf("--------EMAC receive error data!\n");
  467. eth_halt();
  468. return -1;
  469. }
  470. }
  471. printf("--------receive %d bytes, matched\n", length);
  472. bfin_EMAC_halt(NULL);
  473. return 0;
  474. }
  475. #endif