bfin_mac.c 13 KB

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