netarm_eth.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright (C) 2004 IMMS gGmbH <www.imms.de>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. *
  19. * author(s): Thomas Elste, <info@elste.org>
  20. * (some parts derived from uCLinux Netarm Ethernet Driver)
  21. */
  22. #include <common.h>
  23. #include <command.h>
  24. #include <net.h>
  25. #include "netarm_eth.h"
  26. #include <asm/arch/netarm_registers.h>
  27. static int na_mii_poll_busy (void);
  28. static void na_get_mac_addr (void)
  29. {
  30. unsigned short p[3];
  31. char *m_addr;
  32. char ethaddr[20];
  33. m_addr = (char *) p;
  34. p[0] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_1);
  35. p[1] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_2);
  36. p[2] = (unsigned short) GET_EADDR (NETARM_ETH_SAL_STATION_ADDR_3);
  37. sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
  38. m_addr[0], m_addr[1],
  39. m_addr[2], m_addr[3], m_addr[4], m_addr[5]);
  40. printf ("HW-MAC Address: %s\n", ethaddr);
  41. /* set env, todo: check if already an adress is set */
  42. setenv ("ethaddr", ethaddr);
  43. }
  44. static void na_mii_write (int reg, int value)
  45. {
  46. int mii_addr;
  47. /* Select register */
  48. mii_addr = CONFIG_SYS_ETH_PHY_ADDR + reg;
  49. SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
  50. /* Write value */
  51. SET_EADDR (NETARM_ETH_MII_WRITE, value);
  52. na_mii_poll_busy ();
  53. }
  54. static unsigned int na_mii_read (int reg)
  55. {
  56. int mii_addr, val;
  57. /* Select register */
  58. mii_addr = CONFIG_SYS_ETH_PHY_ADDR + reg;
  59. SET_EADDR (NETARM_ETH_MII_ADDR, mii_addr);
  60. /* do one management cycle */
  61. SET_EADDR (NETARM_ETH_MII_CMD,
  62. GET_EADDR (NETARM_ETH_MII_CMD) | NETARM_ETH_MIIC_RSTAT);
  63. na_mii_poll_busy ();
  64. /* Return read value */
  65. val = GET_EADDR (NETARM_ETH_MII_READ);
  66. return val;
  67. }
  68. static int na_mii_poll_busy (void)
  69. {
  70. /* arm simple, non interrupt dependent timer */
  71. reset_timer_masked ();
  72. while (get_timer_masked () < NA_MII_POLL_BUSY_DELAY) {
  73. if (!(GET_EADDR (NETARM_ETH_MII_IND) & NETARM_ETH_MIII_BUSY)) {
  74. return 1;
  75. }
  76. }
  77. printf ("na_mii_busy timeout\n");
  78. return (0);
  79. }
  80. static int na_mii_identify_phy (void)
  81. {
  82. int id_reg_a = 0;
  83. /* get phy id register */
  84. id_reg_a = na_mii_read (MII_PHY_ID);
  85. if (id_reg_a == 0x0043) {
  86. /* This must be an Enable or a Lucent LU3X31 PHY chip */
  87. return 1;
  88. } else if (id_reg_a == 0x0013) {
  89. /* it is an Intel LXT971A */
  90. return 1;
  91. }
  92. return (0);
  93. }
  94. static int na_mii_negotiate (void)
  95. {
  96. int i = 0;
  97. /* Enable auto-negotiation */
  98. na_mii_write (MII_PHY_AUTONEGADV, 0x01e1);
  99. /* FIXME: 0x01E1 is 100Mb half and full duplex, 0x0061 is 10Mb only */
  100. /* Restart auto-negotiation */
  101. na_mii_write (MII_PHY_CONTROL, 0x1200);
  102. /* status register is 0xffff after setting the autoneg restart bit */
  103. while (na_mii_read (MII_PHY_STATUS) == 0xffff) {
  104. i++;
  105. }
  106. /* na_mii_read uses the timer already, so we can't use it again for
  107. timeout checking.
  108. Instead we just try some times.
  109. */
  110. for (i = 0; i < 40000; i++) {
  111. if ((na_mii_read (MII_PHY_STATUS) & 0x0024) == 0x0024) {
  112. return 0;
  113. }
  114. }
  115. /*
  116. printf("*Warning* autonegotiation timeout, status: 0x%x\n",na_mii_read(MII_PHY_STATUS));
  117. */
  118. return (1);
  119. }
  120. static unsigned int na_mii_check_speed (void)
  121. {
  122. unsigned int status;
  123. /* Read Status register */
  124. status = na_mii_read (MII_PHY_STATUS);
  125. /* Check link status. If 0, default to 100 Mbps. */
  126. if ((status & 0x0004) == 0) {
  127. printf ("*Warning* no link detected, set default speed to 100Mbs\n");
  128. return 1;
  129. } else {
  130. if ((na_mii_read (17) & 0x4000) != 0) {
  131. printf ("100Mbs link detected\n");
  132. return 1;
  133. } else {
  134. printf ("10Mbs link detected\n");
  135. return 0;
  136. }
  137. }
  138. return 0;
  139. }
  140. static int reset_eth (void)
  141. {
  142. int pt;
  143. na_get_mac_addr ();
  144. pt = na_mii_identify_phy ();
  145. /* reset the phy */
  146. na_mii_write (MII_PHY_CONTROL, 0x8000);
  147. reset_timer_masked ();
  148. while (get_timer_masked () < NA_MII_NEGOTIATE_DELAY) {
  149. if ((na_mii_read (MII_PHY_STATUS) & 0x8000) == 0) {
  150. break;
  151. }
  152. }
  153. if (get_timer_masked () >= NA_MII_NEGOTIATE_DELAY)
  154. printf ("phy reset timeout\n");
  155. /* set the PCS reg */
  156. SET_EADDR (NETARM_ETH_PCS_CFG, NETARM_ETH_PCSC_CLKS_25M |
  157. NETARM_ETH_PCSC_ENJAB | NETARM_ETH_PCSC_NOCFR);
  158. na_mii_negotiate ();
  159. na_mii_check_speed ();
  160. /* Delay 10 millisecond. (Maybe this should be 1 second.) */
  161. udelay (10000);
  162. /* Turn receive on.
  163. Enable statistics register autozero on read.
  164. Do not insert MAC address on transmit.
  165. Do not enable special test modes. */
  166. SET_EADDR (NETARM_ETH_STL_CFG,
  167. (NETARM_ETH_STLC_AUTOZ | NETARM_ETH_STLC_RXEN));
  168. /* Set the inter-packet gap delay to 0.96us for MII.
  169. The NET+ARM H/W Reference Guide indicates that the Back-to-back IPG
  170. Gap Timer Register should be set to 0x15 and the Non Back-to-back IPG
  171. Gap Timer Register should be set to 0x00000C12 for the MII PHY. */
  172. SET_EADDR (NETARM_ETH_B2B_IPG_GAP_TMR, 0x15);
  173. SET_EADDR (NETARM_ETH_NB2B_IPG_GAP_TMR, 0x00000C12);
  174. /* Add CRC to end of packets.
  175. Pad packets to minimum length of 64 bytes.
  176. Allow unlimited length transmit packets.
  177. Receive all broadcast packets.
  178. NOTE: Multicast addressing is NOT enabled here currently. */
  179. SET_EADDR (NETARM_ETH_MAC_CFG,
  180. (NETARM_ETH_MACC_CRCEN |
  181. NETARM_ETH_MACC_PADEN | NETARM_ETH_MACC_HUGEN));
  182. SET_EADDR (NETARM_ETH_SAL_FILTER, NETARM_ETH_SALF_BROAD);
  183. /* enable fifos */
  184. SET_EADDR (NETARM_ETH_GEN_CTRL,
  185. (NETARM_ETH_GCR_ERX | NETARM_ETH_GCR_ETX));
  186. return (0);
  187. }
  188. extern int eth_init (bd_t * bd)
  189. {
  190. reset_eth ();
  191. return 0;
  192. }
  193. extern void eth_halt (void)
  194. {
  195. SET_EADDR (NETARM_ETH_GEN_CTRL, 0);
  196. }
  197. /* Get a data block via Ethernet */
  198. extern int eth_rx (void)
  199. {
  200. int i;
  201. unsigned short rxlen;
  202. unsigned int *addr;
  203. unsigned int rxstatus, lastrxlen;
  204. char *pa;
  205. /* RXBR is 1, data block was received */
  206. if ((GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXBR) == 0)
  207. return 0;
  208. /* get status register and the length of received block */
  209. rxstatus = GET_EADDR (NETARM_ETH_RX_STAT);
  210. rxlen = (rxstatus & NETARM_ETH_RXSTAT_SIZE) >> 16;
  211. if (rxlen == 0)
  212. return 0;
  213. /* clear RXBR to make fifo available */
  214. SET_EADDR (NETARM_ETH_GEN_STAT,
  215. GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_RXBR);
  216. /* clear TXBC to make fifo available */
  217. /* According to NETARM50 data manual you just have to clear
  218. RXBR but that has no effect. Only after clearing TXBC the
  219. Fifo becomes readable. */
  220. SET_EADDR (NETARM_ETH_GEN_STAT,
  221. GET_EADDR (NETARM_ETH_GEN_STAT) & ~NETARM_ETH_GST_TXBC);
  222. addr = (unsigned int *) NetRxPackets[0];
  223. pa = (char *) NetRxPackets[0];
  224. /* read the fifo */
  225. for (i = 0; i < rxlen / 4; i++) {
  226. *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
  227. addr++;
  228. }
  229. if (GET_EADDR (NETARM_ETH_GEN_STAT) & NETARM_ETH_GST_RXREGR) {
  230. /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
  231. lastrxlen =
  232. (GET_EADDR (NETARM_ETH_GEN_STAT) &
  233. NETARM_ETH_GST_RXFDB) >> 28;
  234. *addr = GET_EADDR (NETARM_ETH_FIFO_DAT1);
  235. switch (lastrxlen) {
  236. case 1:
  237. *addr &= 0xff000000;
  238. break;
  239. case 2:
  240. *addr &= 0xffff0000;
  241. break;
  242. case 3:
  243. *addr &= 0xffffff00;
  244. break;
  245. }
  246. }
  247. /* Pass the packet up to the protocol layers. */
  248. NetReceive (NetRxPackets[0], rxlen);
  249. return rxlen;
  250. }
  251. /* Send a data block via Ethernet. */
  252. extern int eth_send (volatile void *packet, int length)
  253. {
  254. int i, length32;
  255. char *pa;
  256. unsigned int *pa32, lastp = 0, rest;
  257. pa = (char *) packet;
  258. pa32 = (unsigned int *) packet;
  259. length32 = length / 4;
  260. rest = length % 4;
  261. /* make sure there's no garbage in the last word */
  262. switch (rest) {
  263. case 0:
  264. lastp = pa32[length32];
  265. length32--;
  266. break;
  267. case 1:
  268. lastp = pa32[length32] & 0x000000ff;
  269. break;
  270. case 2:
  271. lastp = pa32[length32] & 0x0000ffff;
  272. break;
  273. case 3:
  274. lastp = pa32[length32] & 0x00ffffff;
  275. break;
  276. }
  277. /* write to the fifo */
  278. for (i = 0; i < length32; i++)
  279. SET_EADDR (NETARM_ETH_FIFO_DAT1, pa32[i]);
  280. /* the last word is written to an extra register, this
  281. starts the transmission */
  282. SET_EADDR (NETARM_ETH_FIFO_DAT2, lastp);
  283. /* NETARM_ETH_TXSTAT_TXOK should be checked, to know if the transmission
  284. went fine. But we can't use the timer for a timeout loop because
  285. of it is used already in upper layers. So we just try some times. */
  286. i = 0;
  287. while (i < 50000) {
  288. if ((GET_EADDR (NETARM_ETH_TX_STAT) & NETARM_ETH_TXSTAT_TXOK)
  289. == NETARM_ETH_TXSTAT_TXOK)
  290. return 0;
  291. i++;
  292. }
  293. printf ("eth_send timeout\n");
  294. return 1;
  295. }