xilinx_emac.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /******************************************************************************
  2. *
  3. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
  4. * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
  5. * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
  6. * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
  7. * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
  8. * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
  9. * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
  10. * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
  11. * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
  12. * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
  13. * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
  14. * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15. * FOR A PARTICULAR PURPOSE.
  16. *
  17. * (C) Copyright 2007-2008 Michal Simek
  18. * Michal SIMEK <monstr@monstr.eu>
  19. *
  20. * (c) Copyright 2003 Xilinx Inc.
  21. * All rights reserved.
  22. *
  23. ******************************************************************************/
  24. #include <config.h>
  25. #include <common.h>
  26. #include <net.h>
  27. #include <asm/io.h>
  28. #include <asm/asm.h>
  29. #undef DEBUG
  30. typedef struct {
  31. u32 regbaseaddress; /* Base address of registers */
  32. u32 databaseaddress; /* Base address of data for FIFOs */
  33. } xpacketfifov100b;
  34. typedef struct {
  35. u32 baseaddress; /* Base address (of IPIF) */
  36. u32 isstarted; /* Device is currently started 0-no, 1-yes */
  37. xpacketfifov100b recvfifo; /* FIFO used to receive frames */
  38. xpacketfifov100b sendfifo; /* FIFO used to send frames */
  39. } xemac;
  40. #define XIIF_V123B_IISR_OFFSET 32UL /* IP interrupt status register */
  41. #define XIIF_V123B_RESET_MASK 0xAUL
  42. #define XIIF_V123B_RESETR_OFFSET 64UL /* reset register */
  43. /* This constant is used with the Reset Register */
  44. #define XPF_RESET_FIFO_MASK 0x0000000A
  45. #define XPF_COUNT_STATUS_REG_OFFSET 4UL
  46. /* These constants are used with the Occupancy/Vacancy Count Register. This
  47. * register also contains FIFO status */
  48. #define XPF_COUNT_MASK 0x0000FFFF
  49. #define XPF_DEADLOCK_MASK 0x20000000
  50. /* Offset of the MAC registers from the IPIF base address */
  51. #define XEM_REG_OFFSET 0x1100UL
  52. /*
  53. * Register offsets for the Ethernet MAC. Each register is 32 bits.
  54. */
  55. #define XEM_ECR_OFFSET (XEM_REG_OFFSET + 0x4) /* MAC Control */
  56. #define XEM_SAH_OFFSET (XEM_REG_OFFSET + 0xC) /* Station addr, high */
  57. #define XEM_SAL_OFFSET (XEM_REG_OFFSET + 0x10) /* Station addr, low */
  58. #define XEM_RPLR_OFFSET (XEM_REG_OFFSET + 0x1C) /* Rx packet length */
  59. #define XEM_TPLR_OFFSET (XEM_REG_OFFSET + 0x20) /* Tx packet length */
  60. #define XEM_TSR_OFFSET (XEM_REG_OFFSET + 0x24) /* Tx status */
  61. #define XEM_PFIFO_OFFSET 0x2000UL
  62. /* Tx registers */
  63. #define XEM_PFIFO_TXREG_OFFSET (XEM_PFIFO_OFFSET + 0x0)
  64. /* Rx registers */
  65. #define XEM_PFIFO_RXREG_OFFSET (XEM_PFIFO_OFFSET + 0x10)
  66. /* Tx keyhole */
  67. #define XEM_PFIFO_TXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x100)
  68. /* Rx keyhole */
  69. #define XEM_PFIFO_RXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x200)
  70. /*
  71. * EMAC Interrupt Registers (Status and Enable) masks. These registers are
  72. * part of the IPIF IP Interrupt registers
  73. */
  74. /* A mask for all transmit interrupts, used in polled mode */
  75. #define XEM_EIR_XMIT_ALL_MASK (XEM_EIR_XMIT_DONE_MASK |\
  76. XEM_EIR_XMIT_ERROR_MASK | \
  77. XEM_EIR_XMIT_SFIFO_EMPTY_MASK |\
  78. XEM_EIR_XMIT_LFIFO_FULL_MASK)
  79. /* Xmit complete */
  80. #define XEM_EIR_XMIT_DONE_MASK 0x00000001UL
  81. /* Recv complete */
  82. #define XEM_EIR_RECV_DONE_MASK 0x00000002UL
  83. /* Xmit error */
  84. #define XEM_EIR_XMIT_ERROR_MASK 0x00000004UL
  85. /* Recv error */
  86. #define XEM_EIR_RECV_ERROR_MASK 0x00000008UL
  87. /* Xmit status fifo empty */
  88. #define XEM_EIR_XMIT_SFIFO_EMPTY_MASK 0x00000010UL
  89. /* Recv length fifo empty */
  90. #define XEM_EIR_RECV_LFIFO_EMPTY_MASK 0x00000020UL
  91. /* Xmit length fifo full */
  92. #define XEM_EIR_XMIT_LFIFO_FULL_MASK 0x00000040UL
  93. /* Recv length fifo overrun */
  94. #define XEM_EIR_RECV_LFIFO_OVER_MASK 0x00000080UL
  95. /* Recv length fifo underrun */
  96. #define XEM_EIR_RECV_LFIFO_UNDER_MASK 0x00000100UL
  97. /* Xmit status fifo overrun */
  98. #define XEM_EIR_XMIT_SFIFO_OVER_MASK 0x00000200UL
  99. /* Transmit status fifo underrun */
  100. #define XEM_EIR_XMIT_SFIFO_UNDER_MASK 0x00000400UL
  101. /* Transmit length fifo overrun */
  102. #define XEM_EIR_XMIT_LFIFO_OVER_MASK 0x00000800UL
  103. /* Transmit length fifo underrun */
  104. #define XEM_EIR_XMIT_LFIFO_UNDER_MASK 0x00001000UL
  105. /* Transmit pause pkt received */
  106. #define XEM_EIR_XMIT_PAUSE_MASK 0x00002000UL
  107. /*
  108. * EMAC Control Register (ECR)
  109. */
  110. /* Full duplex mode */
  111. #define XEM_ECR_FULL_DUPLEX_MASK 0x80000000UL
  112. /* Reset transmitter */
  113. #define XEM_ECR_XMIT_RESET_MASK 0x40000000UL
  114. /* Enable transmitter */
  115. #define XEM_ECR_XMIT_ENABLE_MASK 0x20000000UL
  116. /* Reset receiver */
  117. #define XEM_ECR_RECV_RESET_MASK 0x10000000UL
  118. /* Enable receiver */
  119. #define XEM_ECR_RECV_ENABLE_MASK 0x08000000UL
  120. /* Enable PHY */
  121. #define XEM_ECR_PHY_ENABLE_MASK 0x04000000UL
  122. /* Enable xmit pad insert */
  123. #define XEM_ECR_XMIT_PAD_ENABLE_MASK 0x02000000UL
  124. /* Enable xmit FCS insert */
  125. #define XEM_ECR_XMIT_FCS_ENABLE_MASK 0x01000000UL
  126. /* Enable unicast addr */
  127. #define XEM_ECR_UNICAST_ENABLE_MASK 0x00020000UL
  128. /* Enable broadcast addr */
  129. #define XEM_ECR_BROAD_ENABLE_MASK 0x00008000UL
  130. /*
  131. * Transmit Status Register (TSR)
  132. */
  133. /* Transmit excess deferral */
  134. #define XEM_TSR_EXCESS_DEFERRAL_MASK 0x80000000UL
  135. /* Transmit late collision */
  136. #define XEM_TSR_LATE_COLLISION_MASK 0x01000000UL
  137. #define ENET_MAX_MTU PKTSIZE
  138. #define ENET_ADDR_LENGTH 6
  139. static unsigned int etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
  140. static u8 emacaddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
  141. static xemac emac;
  142. void eth_halt(void)
  143. {
  144. debug ("eth_halt\n");
  145. }
  146. int eth_init(bd_t * bis)
  147. {
  148. u32 helpreg;
  149. debug ("EMAC Initialization Started\n\r");
  150. if (emac.isstarted) {
  151. puts("Emac is started\n");
  152. return 0;
  153. }
  154. memset (&emac, 0, sizeof (xemac));
  155. emac.baseaddress = XILINX_EMAC_BASEADDR;
  156. /* Setting up FIFOs */
  157. emac.recvfifo.regbaseaddress = emac.baseaddress +
  158. XEM_PFIFO_RXREG_OFFSET;
  159. emac.recvfifo.databaseaddress = emac.baseaddress +
  160. XEM_PFIFO_RXDATA_OFFSET;
  161. out_be32 (emac.recvfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
  162. emac.sendfifo.regbaseaddress = emac.baseaddress +
  163. XEM_PFIFO_TXREG_OFFSET;
  164. emac.sendfifo.databaseaddress = emac.baseaddress +
  165. XEM_PFIFO_TXDATA_OFFSET;
  166. out_be32 (emac.sendfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
  167. /* Reset the entire IPIF */
  168. out_be32 (emac.baseaddress + XIIF_V123B_RESETR_OFFSET,
  169. XIIF_V123B_RESET_MASK);
  170. /* Stopping EMAC for setting up MAC */
  171. helpreg = in_be32 (emac.baseaddress + XEM_ECR_OFFSET);
  172. helpreg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
  173. out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
  174. if (!getenv("ethaddr")) {
  175. memcpy(bis->bi_enetaddr, emacaddr, ENET_ADDR_LENGTH);
  176. }
  177. /* Set the device station address high and low registers */
  178. helpreg = (bis->bi_enetaddr[0] << 8) | bis->bi_enetaddr[1];
  179. out_be32 (emac.baseaddress + XEM_SAH_OFFSET, helpreg);
  180. helpreg = (bis->bi_enetaddr[2] << 24) | (bis->bi_enetaddr[3] << 16) |
  181. (bis->bi_enetaddr[4] << 8) | bis->bi_enetaddr[5];
  182. out_be32 (emac.baseaddress + XEM_SAL_OFFSET, helpreg);
  183. helpreg = XEM_ECR_UNICAST_ENABLE_MASK | XEM_ECR_BROAD_ENABLE_MASK |
  184. XEM_ECR_FULL_DUPLEX_MASK | XEM_ECR_XMIT_FCS_ENABLE_MASK |
  185. XEM_ECR_XMIT_PAD_ENABLE_MASK | XEM_ECR_PHY_ENABLE_MASK;
  186. out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
  187. emac.isstarted = 1;
  188. /* Enable the transmitter, and receiver */
  189. helpreg = in_be32 (emac.baseaddress + XEM_ECR_OFFSET);
  190. helpreg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
  191. helpreg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
  192. out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
  193. printf("EMAC Initialization complete\n\r");
  194. return 0;
  195. }
  196. int eth_send(volatile void *ptr, int len)
  197. {
  198. u32 intrstatus;
  199. u32 xmitstatus;
  200. u32 fifocount;
  201. u32 wordcount;
  202. u32 extrabytecount;
  203. u32 *wordbuffer = (u32 *) ptr;
  204. if (len > ENET_MAX_MTU)
  205. len = ENET_MAX_MTU;
  206. /*
  207. * Check for overruns and underruns for the transmit status and length
  208. * FIFOs and make sure the send packet FIFO is not deadlocked.
  209. * Any of these conditions is bad enough that we do not want to
  210. * continue. The upper layer software should reset the device to resolve
  211. * the error.
  212. */
  213. intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
  214. if (intrstatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
  215. XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
  216. debug ("Transmitting overrun error\n");
  217. return 0;
  218. } else if (intrstatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
  219. XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
  220. debug ("Transmitting underrun error\n");
  221. return 0;
  222. } else if (in_be32 (emac.sendfifo.regbaseaddress +
  223. XPF_COUNT_STATUS_REG_OFFSET) & XPF_DEADLOCK_MASK) {
  224. debug ("Transmitting fifo error\n");
  225. return 0;
  226. }
  227. /*
  228. * Before writing to the data FIFO, make sure the length FIFO is not
  229. * full. The data FIFO might not be full yet even though the length FIFO
  230. * is. This avoids an overrun condition on the length FIFO and keeps the
  231. * FIFOs in sync.
  232. *
  233. * Clear the latched LFIFO_FULL bit so next time around the most
  234. * current status is represented
  235. */
  236. if (intrstatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
  237. out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
  238. intrstatus & XEM_EIR_XMIT_LFIFO_FULL_MASK);
  239. debug ("Fifo is full\n");
  240. return 0;
  241. }
  242. /* get the count of how many words may be inserted into the FIFO */
  243. fifocount = in_be32 (emac.sendfifo.regbaseaddress +
  244. XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
  245. wordcount = len >> 2;
  246. extrabytecount = len & 0x3;
  247. if (fifocount < wordcount) {
  248. debug ("Sending packet is larger then size of FIFO\n");
  249. return 0;
  250. }
  251. for (fifocount = 0; fifocount < wordcount; fifocount++) {
  252. out_be32 (emac.sendfifo.databaseaddress, wordbuffer[fifocount]);
  253. }
  254. if (extrabytecount > 0) {
  255. u32 lastword = 0;
  256. u8 *extrabytesbuffer = (u8 *) (wordbuffer + wordcount);
  257. if (extrabytecount == 1) {
  258. lastword = extrabytesbuffer[0] << 24;
  259. } else if (extrabytecount == 2) {
  260. lastword = extrabytesbuffer[0] << 24 |
  261. extrabytesbuffer[1] << 16;
  262. } else if (extrabytecount == 3) {
  263. lastword = extrabytesbuffer[0] << 24 |
  264. extrabytesbuffer[1] << 16 |
  265. extrabytesbuffer[2] << 8;
  266. }
  267. out_be32 (emac.sendfifo.databaseaddress, lastword);
  268. }
  269. /* Loop on the MAC's status to wait for any pause to complete */
  270. intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
  271. while ((intrstatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
  272. intrstatus = in_be32 ((emac.baseaddress) +
  273. XIIF_V123B_IISR_OFFSET);
  274. /* Clear the pause status from the transmit status register */
  275. out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
  276. intrstatus & XEM_EIR_XMIT_PAUSE_MASK);
  277. }
  278. /*
  279. * Set the MAC's transmit packet length register to tell it to transmit
  280. */
  281. out_be32 (emac.baseaddress + XEM_TPLR_OFFSET, len);
  282. /*
  283. * Loop on the MAC's status to wait for the transmit to complete.
  284. * The transmit status is in the FIFO when the XMIT_DONE bit is set.
  285. */
  286. do {
  287. intrstatus = in_be32 ((emac.baseaddress) +
  288. XIIF_V123B_IISR_OFFSET);
  289. }
  290. while ((intrstatus & XEM_EIR_XMIT_DONE_MASK) == 0);
  291. xmitstatus = in_be32 (emac.baseaddress + XEM_TSR_OFFSET);
  292. if (intrstatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
  293. XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
  294. debug ("Transmitting overrun error\n");
  295. return 0;
  296. } else if (intrstatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
  297. XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
  298. debug ("Transmitting underrun error\n");
  299. return 0;
  300. }
  301. /* Clear the interrupt status register of transmit statuses */
  302. out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
  303. intrstatus & XEM_EIR_XMIT_ALL_MASK);
  304. /*
  305. * Collision errors are stored in the transmit status register
  306. * instead of the interrupt status register
  307. */
  308. if ((xmitstatus & XEM_TSR_EXCESS_DEFERRAL_MASK) ||
  309. (xmitstatus & XEM_TSR_LATE_COLLISION_MASK)) {
  310. debug ("Transmitting collision error\n");
  311. return 0;
  312. }
  313. return 1;
  314. }
  315. int eth_rx(void)
  316. {
  317. u32 pktlength;
  318. u32 intrstatus;
  319. u32 fifocount;
  320. u32 wordcount;
  321. u32 extrabytecount;
  322. u32 lastword;
  323. u8 *extrabytesbuffer;
  324. if (in_be32 (emac.recvfifo.regbaseaddress + XPF_COUNT_STATUS_REG_OFFSET)
  325. & XPF_DEADLOCK_MASK) {
  326. out_be32 (emac.recvfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
  327. debug ("Receiving FIFO deadlock\n");
  328. return 0;
  329. }
  330. /*
  331. * Get the interrupt status to know what happened (whether an error
  332. * occurred and/or whether frames have been received successfully).
  333. * When clearing the intr status register, clear only statuses that
  334. * pertain to receive.
  335. */
  336. intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
  337. /*
  338. * Before reading from the length FIFO, make sure the length FIFO is not
  339. * empty. We could cause an underrun error if we try to read from an
  340. * empty FIFO.
  341. */
  342. if (!(intrstatus & XEM_EIR_RECV_DONE_MASK)) {
  343. /* debug ("Receiving FIFO is empty\n"); */
  344. return 0;
  345. }
  346. /*
  347. * Determine, from the MAC, the length of the next packet available
  348. * in the data FIFO (there should be a non-zero length here)
  349. */
  350. pktlength = in_be32 (emac.baseaddress + XEM_RPLR_OFFSET);
  351. if (!pktlength) {
  352. return 0;
  353. }
  354. /*
  355. * Write the RECV_DONE bit in the status register to clear it. This bit
  356. * indicates the RPLR is non-empty, and we know it's set at this point.
  357. * We clear it so that subsequent entry into this routine will reflect
  358. * the current status. This is done because the non-empty bit is latched
  359. * in the IPIF, which means it may indicate a non-empty condition even
  360. * though there is something in the FIFO.
  361. */
  362. out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
  363. XEM_EIR_RECV_DONE_MASK);
  364. fifocount = in_be32 (emac.recvfifo.regbaseaddress +
  365. XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
  366. if ((fifocount * 4) < pktlength) {
  367. debug ("Receiving FIFO is smaller than packet size.\n");
  368. return 0;
  369. }
  370. wordcount = pktlength >> 2;
  371. extrabytecount = pktlength & 0x3;
  372. for (fifocount = 0; fifocount < wordcount; fifocount++) {
  373. etherrxbuff[fifocount] =
  374. in_be32 (emac.recvfifo.databaseaddress);
  375. }
  376. /*
  377. * if there are extra bytes to handle, read the last word from the FIFO
  378. * and insert the extra bytes into the buffer
  379. */
  380. if (extrabytecount > 0) {
  381. extrabytesbuffer = (u8 *) (etherrxbuff + wordcount);
  382. lastword = in_be32 (emac.recvfifo.databaseaddress);
  383. /*
  384. * one extra byte in the last word, put the byte into the next
  385. * location of the buffer, bytes in a word of the FIFO are
  386. * ordered from most significant byte to least
  387. */
  388. if (extrabytecount == 1) {
  389. extrabytesbuffer[0] = (u8) (lastword >> 24);
  390. } else if (extrabytecount == 2) {
  391. extrabytesbuffer[0] = (u8) (lastword >> 24);
  392. extrabytesbuffer[1] = (u8) (lastword >> 16);
  393. } else if (extrabytecount == 3) {
  394. extrabytesbuffer[0] = (u8) (lastword >> 24);
  395. extrabytesbuffer[1] = (u8) (lastword >> 16);
  396. extrabytesbuffer[2] = (u8) (lastword >> 8);
  397. }
  398. }
  399. NetReceive((uchar *)etherrxbuff, pktlength);
  400. return 1;
  401. }