s3c4510b_eth.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /***********************************************************************
  2. *
  3. * Copyright (c) 2004 Cucy Systems (http://www.cucy.com)
  4. * Curt Brune <curt@cucy.com>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. *
  24. * Description: Ethernet interface for Samsung S3C4510B SoC
  25. */
  26. #include <common.h>
  27. #ifdef CONFIG_DRIVER_S3C4510_ETH
  28. #include <command.h>
  29. #include <net.h>
  30. #include <asm/hardware.h>
  31. #include "s3c4510b_eth.h"
  32. static TX_FrameDescriptor txFDbase[ETH_MaxTxFrames];
  33. static MACFrame txFrameBase[ETH_MaxTxFrames];
  34. static RX_FrameDescriptor rxFDbase[PKTBUFSRX];
  35. static ETH m_eth;
  36. static s32 TxFDinit( ETH *eth) {
  37. s32 i;
  38. MACFrame *txFrmBase;
  39. /* disable cache for access to the TX buffers */
  40. txFrmBase = (MACFrame *)( (u32)txFrameBase | CACHE_DISABLE_MASK);
  41. /* store start of Tx descriptors and set current */
  42. eth->m_curTX_FD = (TX_FrameDescriptor *) ((u32)txFDbase | CACHE_DISABLE_MASK);
  43. eth->m_baseTX_FD = eth->m_curTX_FD;
  44. for ( i = 0; i < ETH_MaxTxFrames; i++) {
  45. eth->m_baseTX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)&txFrmBase[i];
  46. eth->m_baseTX_FD[i].m_frameDataPtr.bf.owner = 0x0; /* CPU owner */
  47. eth->m_baseTX_FD[i].m_opt.ui = 0x0;
  48. eth->m_baseTX_FD[i].m_status.ui = 0x0;
  49. eth->m_baseTX_FD[i].m_nextFD = &eth->m_baseTX_FD[i+1];
  50. }
  51. /* make the list circular */
  52. eth->m_baseTX_FD[i-1].m_nextFD = &eth->m_baseTX_FD[0];
  53. PUT_REG( REG_BDMATXPTR, (u32)eth->m_curTX_FD);
  54. return 0;
  55. }
  56. static s32 RxFDinit( ETH *eth) {
  57. s32 i;
  58. /* MACFrame *rxFrmBase; */
  59. /* disable cache for access to the RX buffers */
  60. /* rxFrmBase = (MACFrame *)( (u32)rxFrameBase | CACHE_DISABLE_MASK); */
  61. /* store start of Rx descriptors and set current */
  62. eth->m_curRX_FD = (RX_FrameDescriptor *)((u32)rxFDbase | CACHE_DISABLE_MASK);
  63. eth->m_baseRX_FD = eth->m_curRX_FD;
  64. for ( i = 0; i < PKTBUFSRX; i++) {
  65. eth->m_baseRX_FD[i].m_frameDataPtr.bf.dataPtr = (u32)NetRxPackets[i] | CACHE_DISABLE_MASK;
  66. eth->m_baseRX_FD[i].m_frameDataPtr.bf.owner = 0x1; /* BDMA owner */
  67. eth->m_baseRX_FD[i].m_reserved = 0x0;
  68. eth->m_baseRX_FD[i].m_status.ui = 0x0;
  69. eth->m_baseRX_FD[i].m_nextFD = &eth->m_baseRX_FD[i+1];
  70. }
  71. /* make the list circular */
  72. eth->m_baseRX_FD[i-1].m_nextFD = &eth->m_baseRX_FD[0];
  73. PUT_REG( REG_BDMARXPTR, (u32)eth->m_curRX_FD);
  74. return 0;
  75. }
  76. /*
  77. * Public u-boot interface functions below
  78. */
  79. int eth_init(bd_t *bis)
  80. {
  81. ETH *eth = &m_eth;
  82. /* store our MAC address */
  83. eth->m_mac = bis->bi_enetaddr;
  84. /* setup DBMA and MAC */
  85. PUT_REG( REG_BDMARXCON, ETH_BRxRS); /* reset BDMA RX machine */
  86. PUT_REG( REG_BDMATXCON, ETH_BTxRS); /* reset BDMA TX machine */
  87. PUT_REG( REG_MACCON , ETH_SwReset); /* reset MAC machine */
  88. PUT_REG( REG_BDMARXLSZ, sizeof(MACFrame));
  89. PUT_REG( REG_MACCON , 0); /* reset MAC machine */
  90. /* init frame descriptors */
  91. TxFDinit( eth);
  92. RxFDinit( eth);
  93. /* init the CAM with our MAC address */
  94. PUT_REG( REG_CAM_BASE, (eth->m_mac[0] << 24) |
  95. (eth->m_mac[1] << 16) |
  96. (eth->m_mac[2] << 8) |
  97. (eth->m_mac[3]));
  98. PUT_REG( REG_CAM_BASE + 0x4, (eth->m_mac[4] << 24) |
  99. (eth->m_mac[5] << 16));
  100. /* enable CAM address 1 -- the MAC we just loaded */
  101. PUT_REG( REG_CAMEN, 0x1);
  102. PUT_REG( REG_CAMCON,
  103. ETH_BroadAcc | /* accept broadcast packetes */
  104. ETH_CompEn); /* enable compare mode (check against the CAM) */
  105. /* configure the BDMA Transmitter control */
  106. PUT_REG( REG_BDMATXCON,
  107. ETH_BTxBRST | /* BDMA Tx burst size 16 words */
  108. ETH_BTxMSL110 | /* BDMA Tx wait to fill 6/8 of the BDMA */
  109. ETH_BTxSTSKO | /* BDMA Tx interrupt(Stop) on non-owner TX FD */
  110. ETH_BTxEn); /* BDMA Tx Enable */
  111. /* configure the MAC Transmitter control */
  112. PUT_REG( REG_MACTXCON,
  113. ETH_EnComp | /* interrupt when the MAC transmits or discards packet */
  114. ETH_TxEn); /* MAC transmit enable */
  115. /* configure the BDMA Receiver control */
  116. PUT_REG( REG_BDMARXCON,
  117. ETH_BRxBRST | /* BDMA Rx Burst Size 16 words */
  118. ETH_BRxSTSKO | /* BDMA Rx interrupt(Stop) on non-owner RX FD */
  119. ETH_BRxMAINC | /* BDMA Rx Memory Address increment */
  120. ETH_BRxDIE | /* BDMA Rx Every Received Frame Interrupt Enable */
  121. ETH_BRxNLIE | /* BDMA Rx NULL List Interrupt Enable */
  122. ETH_BRxNOIE | /* BDMA Rx Not Owner Interrupt Enable */
  123. ETH_BRxLittle | /* BDMA Rx Little endian */
  124. ETH_BRxEn); /* BDMA Rx Enable */
  125. /* configure the MAC Receiver control */
  126. PUT_REG( REG_MACRXCON,
  127. ETH_RxEn); /* MAC ETH_RxEn */
  128. return 0;
  129. }
  130. /* Send a packet */
  131. s32 eth_send(volatile void *packet, s32 length)
  132. {
  133. u32 i;
  134. ETH *eth = &m_eth;
  135. if ( eth->m_curTX_FD->m_frameDataPtr.bf.owner) {
  136. printf("eth_send(): TX Frame. CPU not owner.\n");
  137. return -1;
  138. }
  139. /* copy user data into frame data pointer */
  140. memcpy((void *)((u32)(eth->m_curTX_FD->m_frameDataPtr.bf.dataPtr)),
  141. (void *)packet,
  142. length);
  143. /* Set TX Frame flags */
  144. eth->m_curTX_FD->m_opt.bf.widgetAlign = 0;
  145. eth->m_curTX_FD->m_opt.bf.frameDataDir = 1;
  146. eth->m_curTX_FD->m_opt.bf.littleEndian = 1;
  147. eth->m_curTX_FD->m_opt.bf.macTxIrqEnbl = 1;
  148. eth->m_curTX_FD->m_opt.bf.no_crc = 0;
  149. eth->m_curTX_FD->m_opt.bf.no_padding = 0;
  150. /* Set TX Frame length */
  151. eth->m_curTX_FD->m_status.bf.len = length;
  152. /* Change ownership to BDMA */
  153. eth->m_curTX_FD->m_frameDataPtr.bf.owner = 1;
  154. /* Enable MAC and BDMA Tx control register */
  155. SET_REG( REG_BDMATXCON, ETH_BTxEn);
  156. SET_REG( REG_MACTXCON, ETH_TxEn);
  157. /* poll on TX completion status */
  158. while ( !eth->m_curTX_FD->m_status.bf.complete) {
  159. /* sleep */
  160. for ( i = 0; i < 0x10000; i ++);
  161. }
  162. /* Change the Tx frame descriptor for next use */
  163. eth->m_curTX_FD = eth->m_curTX_FD->m_nextFD;
  164. return 0;
  165. }
  166. /* Check for received packets */
  167. s32 eth_rx (void)
  168. {
  169. s32 nLen = 0;
  170. ETH *eth = &m_eth;
  171. /* check if packet ready */
  172. if ( (GET_REG( REG_BDMASTAT)) & ETH_S_BRxRDF) {
  173. /* process all waiting packets */
  174. while ( !eth->m_curRX_FD->m_frameDataPtr.bf.owner) {
  175. nLen = eth->m_curRX_FD->m_status.bf.len;
  176. /* call back u-boot -- may call eth_send() */
  177. NetReceive ((u8 *)eth->m_curRX_FD->m_frameDataPtr.ui, nLen);
  178. /* set owner back to CPU */
  179. eth->m_curRX_FD->m_frameDataPtr.bf.owner = 1;
  180. /* clear status */
  181. eth->m_curRX_FD->m_status.ui = 0x0;
  182. /* advance to next descriptor */
  183. eth->m_curRX_FD = eth->m_curRX_FD->m_nextFD;
  184. /* clear received frame bit */
  185. PUT_REG( REG_BDMASTAT, ETH_S_BRxRDF);
  186. }
  187. }
  188. return nLen;
  189. }
  190. /* Halt ethernet engine */
  191. void eth_halt(void)
  192. {
  193. /* disable MAC */
  194. PUT_REG( REG_MACCON, ETH_HaltReg);
  195. }
  196. #endif