ether.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * (C) Copyright 2007
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * Author: Igor Lisitsin <igor@emcraft.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. /*
  11. * Ethernet test
  12. *
  13. * The Ethernet Media Access Controllers (EMAC) are tested in the
  14. * internal loopback mode.
  15. * The controllers are configured accordingly and several packets
  16. * are transmitted. The configurable test parameters are:
  17. * MIN_PACKET_LENGTH - minimum size of packet to transmit
  18. * MAX_PACKET_LENGTH - maximum size of packet to transmit
  19. * CONFIG_SYS_POST_ETH_LOOPS - Number of test loops. Each loop
  20. * is tested with a different frame length. Starting with
  21. * MAX_PACKET_LENGTH and going down to MIN_PACKET_LENGTH.
  22. * Defaults to 10 and can be overridden in the board config header.
  23. */
  24. #include <post.h>
  25. #if CONFIG_POST & CONFIG_SYS_POST_ETHER
  26. #include <asm/cache.h>
  27. #include <asm/io.h>
  28. #include <asm/processor.h>
  29. #include <asm/ppc4xx-mal.h>
  30. #include <asm/ppc4xx-emac.h>
  31. #include <malloc.h>
  32. DECLARE_GLOBAL_DATA_PTR;
  33. /*
  34. * Get count of EMAC devices (doesn't have to be the max. possible number
  35. * supported by the cpu)
  36. *
  37. * CONFIG_BOARD_EMAC_COUNT added so now a "dynamic" way to configure the
  38. * EMAC count is possible. As it is needed for the Kilauea/Haleakala
  39. * 405EX/405EXr eval board, using the same binary.
  40. */
  41. #if defined(CONFIG_BOARD_EMAC_COUNT)
  42. #define LAST_EMAC_NUM board_emac_count()
  43. #else /* CONFIG_BOARD_EMAC_COUNT */
  44. #if defined(CONFIG_HAS_ETH3)
  45. #define LAST_EMAC_NUM 4
  46. #elif defined(CONFIG_HAS_ETH2)
  47. #define LAST_EMAC_NUM 3
  48. #elif defined(CONFIG_HAS_ETH1)
  49. #define LAST_EMAC_NUM 2
  50. #else
  51. #define LAST_EMAC_NUM 1
  52. #endif
  53. #endif /* CONFIG_BOARD_EMAC_COUNT */
  54. #if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  55. #define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1))
  56. #endif
  57. #define MIN_PACKET_LENGTH 64
  58. #define MAX_PACKET_LENGTH 1514
  59. #ifndef CONFIG_SYS_POST_ETH_LOOPS
  60. #define CONFIG_SYS_POST_ETH_LOOPS 10
  61. #endif
  62. #define PACKET_INCR ((MAX_PACKET_LENGTH - MIN_PACKET_LENGTH) / \
  63. CONFIG_SYS_POST_ETH_LOOPS)
  64. static volatile mal_desc_t tx __cacheline_aligned;
  65. static volatile mal_desc_t rx __cacheline_aligned;
  66. static char *tx_buf;
  67. static char *rx_buf;
  68. int board_emac_count(void);
  69. static void ether_post_init (int devnum, int hw_addr)
  70. {
  71. int i;
  72. #if defined(CONFIG_440GX) || \
  73. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  74. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  75. unsigned mode_reg;
  76. sys_info_t sysinfo;
  77. #endif
  78. #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
  79. unsigned long mfr;
  80. #endif
  81. #if defined(CONFIG_440GX) || \
  82. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  83. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  84. /* Need to get the OPB frequency so we can access the PHY */
  85. get_sys_info (&sysinfo);
  86. #endif
  87. #if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  88. /* provide clocks for EMAC internal loopback */
  89. mfsdr (SDR0_MFR, mfr);
  90. mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
  91. mtsdr (SDR0_MFR, mfr);
  92. sync ();
  93. #endif
  94. /* reset emac */
  95. out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_SRST);
  96. sync ();
  97. for (i = 0;; i++) {
  98. if (!(in_be32 ((void*)(EMAC0_MR0 + hw_addr)) & EMAC_MR0_SRST))
  99. break;
  100. if (i >= 1000) {
  101. printf ("Timeout resetting EMAC\n");
  102. break;
  103. }
  104. udelay (1000);
  105. }
  106. #if defined(CONFIG_440GX) || \
  107. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  108. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  109. /* Whack the M1 register */
  110. mode_reg = 0x0;
  111. if (sysinfo.freqOPB <= 50000000);
  112. else if (sysinfo.freqOPB <= 66666667)
  113. mode_reg |= EMAC_MR1_OBCI_66;
  114. else if (sysinfo.freqOPB <= 83333333)
  115. mode_reg |= EMAC_MR1_OBCI_83;
  116. else if (sysinfo.freqOPB <= 100000000)
  117. mode_reg |= EMAC_MR1_OBCI_100;
  118. else
  119. mode_reg |= EMAC_MR1_OBCI_GT100;
  120. out_be32 ((void*)(EMAC0_MR1 + hw_addr), mode_reg);
  121. #endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
  122. /* set the Mal configuration reg */
  123. #if defined(CONFIG_440GX) || \
  124. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  125. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  126. mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
  127. MAL_CR_PLBLT_DEFAULT | 0x00330000);
  128. #else
  129. mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
  130. /* Errata 1.12: MAL_1 -- Disable MAL bursting */
  131. if (get_pvr() == PVR_440GP_RB) {
  132. mtdcr (MAL0_CFG, mfdcr(MAL0_CFG) & ~MAL_CR_PLBB);
  133. }
  134. #endif
  135. /* setup buffer descriptors */
  136. tx.ctrl = MAL_TX_CTRL_WRAP;
  137. tx.data_len = 0;
  138. tx.data_ptr = (char*)L1_CACHE_ALIGN((u32)tx_buf);
  139. rx.ctrl = MAL_TX_CTRL_WRAP | MAL_RX_CTRL_EMPTY;
  140. rx.data_len = 0;
  141. rx.data_ptr = (char*)L1_CACHE_ALIGN((u32)rx_buf);
  142. flush_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
  143. flush_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
  144. switch (devnum) {
  145. case 1:
  146. /* setup MAL tx & rx channel pointers */
  147. #if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
  148. mtdcr (MAL0_TXCTP2R, &tx);
  149. #else
  150. mtdcr (MAL0_TXCTP1R, &tx);
  151. #endif
  152. #if defined(CONFIG_440)
  153. mtdcr (MAL0_TXBADDR, 0x0);
  154. mtdcr (MAL0_RXBADDR, 0x0);
  155. #endif
  156. mtdcr (MAL0_RXCTP1R, &rx);
  157. /* set RX buffer size */
  158. mtdcr (MAL0_RCBS1, PKTSIZE_ALIGN / 16);
  159. break;
  160. case 0:
  161. default:
  162. /* setup MAL tx & rx channel pointers */
  163. #if defined(CONFIG_440)
  164. mtdcr (MAL0_TXBADDR, 0x0);
  165. mtdcr (MAL0_RXBADDR, 0x0);
  166. #endif
  167. mtdcr (MAL0_TXCTP0R, &tx);
  168. mtdcr (MAL0_RXCTP0R, &rx);
  169. /* set RX buffer size */
  170. mtdcr (MAL0_RCBS0, PKTSIZE_ALIGN / 16);
  171. break;
  172. }
  173. /* Enable MAL transmit and receive channels */
  174. #if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
  175. mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> (devnum*2)));
  176. #else
  177. mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> devnum));
  178. #endif
  179. mtdcr (MAL0_RXCASR, (MAL_TXRX_CASR >> devnum));
  180. /* set internal loopback mode */
  181. #ifdef CONFIG_SYS_POST_ETHER_EXT_LOOPBACK
  182. out_be32 ((void*)(EMAC0_MR1 + hw_addr), EMAC_MR1_FDE | 0 |
  183. EMAC_MR1_RFS_4K | EMAC_MR1_TX_FIFO_2K |
  184. EMAC_MR1_MF_100MBPS | EMAC_MR1_IST |
  185. in_be32 ((void*)(EMAC0_MR1 + hw_addr)));
  186. #else
  187. out_be32 ((void*)(EMAC0_MR1 + hw_addr), EMAC_MR1_FDE | EMAC_MR1_ILE |
  188. EMAC_MR1_RFS_4K | EMAC_MR1_TX_FIFO_2K |
  189. EMAC_MR1_MF_100MBPS | EMAC_MR1_IST |
  190. in_be32 ((void*)(EMAC0_MR1 + hw_addr)));
  191. #endif
  192. /* set transmit enable & receive enable */
  193. out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_TXE | EMAC_MR0_RXE);
  194. /* enable broadcast address */
  195. out_be32 ((void*)(EMAC0_RXM + hw_addr), EMAC_RMR_BAE);
  196. /* set transmit request threshold register */
  197. out_be32 ((void*)(EMAC0_TRTR + hw_addr), 0x18000000); /* 256 byte threshold */
  198. /* set receive low/high water mark register */
  199. #if defined(CONFIG_440)
  200. /* 440s has a 64 byte burst length */
  201. out_be32 ((void*)(EMAC0_RX_HI_LO_WMARK + hw_addr), 0x80009000);
  202. #else
  203. /* 405s have a 16 byte burst length */
  204. out_be32 ((void*)(EMAC0_RX_HI_LO_WMARK + hw_addr), 0x0f002000);
  205. #endif /* defined(CONFIG_440) */
  206. out_be32 ((void*)(EMAC0_TMR1 + hw_addr), 0xf8640000);
  207. /* Set fifo limit entry in tx mode 0 */
  208. out_be32 ((void*)(EMAC0_TMR0 + hw_addr), 0x00000003);
  209. /* Frame gap set */
  210. out_be32 ((void*)(EMAC0_I_FRAME_GAP_REG + hw_addr), 0x00000008);
  211. sync ();
  212. }
  213. static void ether_post_halt (int devnum, int hw_addr)
  214. {
  215. int i = 0;
  216. #if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  217. unsigned long mfr;
  218. #endif
  219. /* 1st reset MAL channel */
  220. /* Note: writing a 0 to a channel has no effect */
  221. #if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
  222. mtdcr (MAL0_TXCARR, MAL_TXRX_CASR >> (devnum * 2));
  223. #else
  224. mtdcr (MAL0_TXCARR, MAL_TXRX_CASR >> devnum);
  225. #endif
  226. mtdcr (MAL0_RXCARR, MAL_TXRX_CASR >> devnum);
  227. /* wait for reset */
  228. while (mfdcr (MAL0_RXCASR) & (MAL_TXRX_CASR >> devnum)) {
  229. if (i++ >= 1000)
  230. break;
  231. udelay (1000);
  232. }
  233. /* emac reset */
  234. out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_SRST);
  235. #if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  236. /* remove clocks for EMAC internal loopback */
  237. mfsdr (SDR0_MFR, mfr);
  238. mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
  239. mtsdr (SDR0_MFR, mfr);
  240. #endif
  241. }
  242. static void ether_post_send (int devnum, int hw_addr, void *packet, int length)
  243. {
  244. int i = 0;
  245. while (tx.ctrl & MAL_TX_CTRL_READY) {
  246. if (i++ > 100) {
  247. printf ("TX timeout\n");
  248. return;
  249. }
  250. udelay (1000);
  251. invalidate_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
  252. }
  253. tx.ctrl = MAL_TX_CTRL_READY | MAL_TX_CTRL_WRAP | MAL_TX_CTRL_LAST |
  254. EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP;
  255. tx.data_len = length;
  256. memcpy (tx.data_ptr, packet, length);
  257. flush_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
  258. flush_dcache_range((u32)tx.data_ptr, (u32)tx.data_ptr + length);
  259. sync ();
  260. out_be32 ((void*)(EMAC0_TMR0 + hw_addr), in_be32 ((void*)(EMAC0_TMR0 + hw_addr)) | EMAC_TMR0_GNP0);
  261. sync ();
  262. }
  263. static int ether_post_recv (int devnum, int hw_addr, void *packet, int max_length)
  264. {
  265. int length;
  266. int i = 0;
  267. while (rx.ctrl & MAL_RX_CTRL_EMPTY) {
  268. if (i++ > 100) {
  269. printf ("RX timeout\n");
  270. return 0;
  271. }
  272. udelay (1000);
  273. invalidate_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
  274. }
  275. length = rx.data_len - 4;
  276. if (length <= max_length) {
  277. invalidate_dcache_range((u32)rx.data_ptr, (u32)rx.data_ptr + length);
  278. memcpy(packet, rx.data_ptr, length);
  279. }
  280. sync ();
  281. rx.ctrl |= MAL_RX_CTRL_EMPTY;
  282. flush_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
  283. sync ();
  284. return length;
  285. }
  286. /*
  287. * Test routines
  288. */
  289. static void packet_fill (char *packet, int length)
  290. {
  291. char c = (char) length;
  292. int i;
  293. /* set up ethernet header */
  294. memset (packet, 0xff, 14);
  295. for (i = 14; i < length; i++) {
  296. packet[i] = c++;
  297. }
  298. }
  299. static int packet_check (char *packet, int length)
  300. {
  301. char c = (char) length;
  302. int i;
  303. for (i = 14; i < length; i++) {
  304. if (packet[i] != c++)
  305. return -1;
  306. }
  307. return 0;
  308. }
  309. char packet_send[MAX_PACKET_LENGTH];
  310. char packet_recv[MAX_PACKET_LENGTH];
  311. static int test_ctlr (int devnum, int hw_addr)
  312. {
  313. int res = -1;
  314. int length;
  315. int l;
  316. ether_post_init (devnum, hw_addr);
  317. for (l = MAX_PACKET_LENGTH; l >= MIN_PACKET_LENGTH;
  318. l -= PACKET_INCR) {
  319. packet_fill (packet_send, l);
  320. ether_post_send (devnum, hw_addr, packet_send, l);
  321. length = ether_post_recv (devnum, hw_addr, packet_recv,
  322. sizeof (packet_recv));
  323. if (length != l || packet_check (packet_recv, length) < 0) {
  324. goto Done;
  325. }
  326. }
  327. res = 0;
  328. Done:
  329. ether_post_halt (devnum, hw_addr);
  330. if (res != 0) {
  331. post_log ("EMAC%d test failed\n", devnum);
  332. }
  333. return res;
  334. }
  335. int ether_post_test (int flags)
  336. {
  337. int res = 0;
  338. int i;
  339. /* Allocate tx & rx packet buffers */
  340. tx_buf = malloc (PKTSIZE_ALIGN + CONFIG_SYS_CACHELINE_SIZE);
  341. rx_buf = malloc (PKTSIZE_ALIGN + CONFIG_SYS_CACHELINE_SIZE);
  342. if (!tx_buf || !rx_buf) {
  343. printf ("Failed to allocate packet buffers\n");
  344. res = -1;
  345. goto out_free;
  346. }
  347. for (i = 0; i < LAST_EMAC_NUM; i++) {
  348. if (test_ctlr (i, i*0x100))
  349. res = -1;
  350. }
  351. out_free:
  352. free (tx_buf);
  353. free (rx_buf);
  354. return res;
  355. }
  356. #endif /* CONFIG_POST & CONFIG_SYS_POST_ETHER */