ethaddr.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. *
  3. * (C) Copyright 2006
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  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. #include <common.h>
  25. #include <mpc5xxx.h>
  26. #define GPIO_ENABLE (MPC5XXX_WU_GPIO)
  27. /* Open Drain Emulation Register */
  28. #define GPIO_ODR (MPC5XXX_WU_GPIO + 0x04)
  29. /* Data Direction Register */
  30. #define GPIO_DDR (MPC5XXX_WU_GPIO + 0x08)
  31. /* Data Value Out Register */
  32. #define GPIO_DVOR (MPC5XXX_WU_GPIO + 0x0C)
  33. /* Interrupt Enable Register */
  34. #define GPIO_IER (MPC5XXX_WU_GPIO + 0x10)
  35. /* Individual Interrupt Enable Register */
  36. #define GPIO_IIER (MPC5XXX_WU_GPIO + 0x14)
  37. /* Interrupt Type Register */
  38. #define GPIO_ITR (MPC5XXX_WU_GPIO + 0x18)
  39. /* Master Enable Register */
  40. #define GPIO_MER (MPC5XXX_WU_GPIO + 0x1C)
  41. /* Data Input Value Register */
  42. #define GPIO_DIVR (MPC5XXX_WU_GPIO + 0x20)
  43. /* Status Register */
  44. #define GPIO_SR (MPC5XXX_WU_GPIO + 0x24)
  45. #define PSC6_0 0x10000000
  46. #define WKUP_7 0x80000000
  47. /* For NS4 A/B board define WKUP_7, for V38B board PSC_6 */
  48. #define GPIO_PIN PSC6_0
  49. #define NO_ERROR 0
  50. #define ERR_NO_NUMBER 1
  51. #define ERR_BAD_NUMBER 2
  52. typedef volatile unsigned long GPIO_REG;
  53. typedef GPIO_REG *GPIO_REG_PTR;
  54. static int is_high(void);
  55. static int check_device(void);
  56. static void io_out(int value);
  57. static void io_input(void);
  58. static void io_output(void);
  59. static void init_gpio(void);
  60. static void read_byte(unsigned char *data);
  61. static void write_byte(unsigned char command);
  62. void read_2501_memory(unsigned char *psernum, unsigned char *perr);
  63. void board_get_enetaddr(uchar *enetaddr);
  64. static int is_high()
  65. {
  66. return (* ((vu_long *) GPIO_DIVR) & GPIO_PIN);
  67. }
  68. static void io_out(int value)
  69. {
  70. if (value)
  71. *((vu_long *) GPIO_DVOR) |= GPIO_PIN;
  72. else
  73. *((vu_long *) GPIO_DVOR) &= ~GPIO_PIN;
  74. }
  75. static void io_input()
  76. {
  77. *((vu_long *) GPIO_DDR) &= ~GPIO_PIN;
  78. udelay(3); /* allow input to settle */
  79. }
  80. static void io_output()
  81. {
  82. *((vu_long *) GPIO_DDR) |= GPIO_PIN;
  83. }
  84. static void init_gpio()
  85. {
  86. *((vu_long *) GPIO_ENABLE) |= GPIO_PIN; /* Enable appropriate pin */
  87. }
  88. void read_2501_memory(unsigned char *psernum, unsigned char *perr)
  89. {
  90. #define NBYTES 28
  91. unsigned char crcval, i;
  92. unsigned char buf[NBYTES];
  93. *perr = 0;
  94. crcval = 0;
  95. for (i=0; i<NBYTES; i++)
  96. if (!check_device())
  97. *perr = ERR_NO_NUMBER;
  98. else {
  99. *perr = NO_ERROR;
  100. write_byte(0xCC); /* skip ROM (0xCC) */
  101. write_byte(0xF0); /* Read memory command 0xF0 */
  102. write_byte(0x00); /* Address TA1=0, TA2=0 */
  103. write_byte(0x00);
  104. read_byte(&crcval); /* Read CRC of address and command */
  105. for (i=0; i<NBYTES; i++)
  106. read_byte( &buf[i] );
  107. }
  108. if (strncmp((const char*) &buf[11], "MAREL IEEE 802.3", 16)) {
  109. *perr = ERR_BAD_NUMBER;
  110. psernum[0] = 0x00;
  111. psernum[1] = 0xE0;
  112. psernum[2] = 0xEE;
  113. psernum[3] = 0xFF;
  114. psernum[4] = 0xFF;
  115. psernum[5] = 0xFF;
  116. }
  117. else {
  118. psernum[0] = 0x00;
  119. psernum[1] = 0xE0;
  120. psernum[2] = 0xEE;
  121. psernum[3] = buf[7];
  122. psernum[4] = buf[6];
  123. psernum[5] = buf[5];
  124. }
  125. }
  126. static int check_device()
  127. {
  128. int found;
  129. io_output();
  130. io_out(0);
  131. udelay(500); /* must be at least 480 us low pulse */
  132. io_input();
  133. udelay(60);
  134. found = (is_high() == 0) ? 1 : 0;
  135. udelay(500); /* must be at least 480 us low pulse */
  136. return found;
  137. }
  138. static void write_byte(unsigned char command)
  139. {
  140. char i;
  141. for (i=0; i<8; i++) {
  142. /* 1 us to 15 us low pulse starts bit slot */
  143. /* Start with high pulse for 3 us */
  144. io_input();
  145. udelay(3);
  146. io_out(0);
  147. io_output();
  148. udelay(3);
  149. if (command & 0x01) {
  150. /* 60 us high for 1-bit */
  151. io_input();
  152. udelay(60);
  153. }
  154. else {
  155. /* 60 us low for 0-bit */
  156. udelay(60);
  157. }
  158. /* Leave pin as input */
  159. io_input();
  160. command = command >> 1;
  161. }
  162. }
  163. static void read_byte(unsigned char *data)
  164. {
  165. unsigned char i, rdat = 0;
  166. for (i=0; i<8; i++) {
  167. /* read one bit from one-wire device */
  168. /* 1 - 15 us low starts bit slot */
  169. io_out(0);
  170. io_output();
  171. udelay(0);
  172. /* allow line to be pulled high */
  173. io_input();
  174. /* delay 10 us */
  175. udelay(10);
  176. /* now sample input status */
  177. if (is_high())
  178. rdat = (rdat >> 1) | 0x80;
  179. else
  180. rdat = rdat >> 1;
  181. udelay(60); /* at least 60 us */
  182. }
  183. /* copy the return value */
  184. *data = rdat;
  185. }
  186. void board_get_enetaddr(uchar *enetaddr)
  187. {
  188. unsigned char sn[6], err=NO_ERROR;
  189. init_gpio();
  190. read_2501_memory(sn, &err);
  191. if (err == NO_ERROR) {
  192. sprintf(enetaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
  193. sn[0], sn[1], sn[2], sn[3], sn[4], sn[5]);
  194. printf("MAC address: %s\n", enetaddr);
  195. setenv("ethaddr", enetaddr);
  196. }
  197. else {
  198. sprintf(enetaddr, "00:01:02:03:04:05");
  199. printf("Error reading MAC address.\n");
  200. printf("Setting default to %s\n", enetaddr);
  201. setenv("ethaddr", enetaddr);
  202. }
  203. }