sys_eeprom.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * Copyright 2006 Freescale Semiconductor
  3. * York Sun (yorksun@freescale.com)
  4. * Haiying Wang (haiying.wang@freescale.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. #include <common.h>
  25. #include <command.h>
  26. #include <i2c.h>
  27. #include <linux/ctype.h>
  28. typedef struct {
  29. u8 id[4]; /* 0x0000 - 0x0003 EEPROM Tag */
  30. u8 sn[12]; /* 0x0004 - 0x000F Serial Number */
  31. u8 errata[5]; /* 0x0010 - 0x0014 Errata Level */
  32. u8 date[6]; /* 0x0015 - 0x001a Build Date */
  33. u8 res_0; /* 0x001b Reserved */
  34. u8 version[4]; /* 0x001c - 0x001f Version */
  35. u8 tempcal[8]; /* 0x0020 - 0x0027 Temperature Calibration Factors*/
  36. u8 tempcalsys[2]; /* 0x0028 - 0x0029 System Temperature Calibration Factors*/
  37. u8 res_1[22]; /* 0x0020 - 0x003f Reserved */
  38. u8 mac_size; /* 0x0040 Mac table size */
  39. u8 mac_flag; /* 0x0041 Mac table flags */
  40. u8 mac[8][6]; /* 0x0042 - 0x0071 Mac addresses */
  41. u32 crc; /* 0x0072 crc32 checksum */
  42. } EEPROM_data;
  43. static EEPROM_data mac_data;
  44. int mac_show(void)
  45. {
  46. int i;
  47. u8 mac_size;
  48. unsigned char ethaddr[8][18];
  49. unsigned char enetvar[32];
  50. /* Show EEPROM tagID,
  51. * always the four characters 'NXID'.
  52. */
  53. printf("ID ");
  54. for (i = 0; i < 4; i++)
  55. printf("%c", mac_data.id[i]);
  56. printf("\n");
  57. /* Show Serial number,
  58. * 0 to 11 charaters of errata information.
  59. */
  60. printf("SN ");
  61. for (i = 0; i < 12; i++)
  62. printf("%c", mac_data.sn[i]);
  63. printf("\n");
  64. /* Show Errata Level,
  65. * 0 to 4 characters of errata information.
  66. */
  67. printf("Errata ");
  68. for (i = 0; i < 5; i++)
  69. printf("%c", mac_data.errata[i]);
  70. printf("\n");
  71. /* Show Build Date,
  72. * BCD date values, as YYMMDDhhmmss.
  73. */
  74. printf("Date 20%02x/%02x/%02x %02x:%02x:%02x\n",
  75. mac_data.date[0],
  76. mac_data.date[1],
  77. mac_data.date[2],
  78. mac_data.date[3],
  79. mac_data.date[4],
  80. mac_data.date[5]);
  81. /* Show MAC table size,
  82. * Value from 0 to 7 indicating how many MAC
  83. * addresses are stored in the system EEPROM.
  84. */
  85. if((mac_data.mac_size > 0) && (mac_data.mac_size <= 8))
  86. mac_size = mac_data.mac_size;
  87. else
  88. mac_size = 8; /* Set the max size */
  89. printf("MACSIZE %x\n", mac_size);
  90. /* Show Mac addresses */
  91. for (i = 0; i < mac_size; i++) {
  92. sprintf((char *)ethaddr[i],
  93. "%02x:%02x:%02x:%02x:%02x:%02x",
  94. mac_data.mac[i][0],
  95. mac_data.mac[i][1],
  96. mac_data.mac[i][2],
  97. mac_data.mac[i][3],
  98. mac_data.mac[i][4],
  99. mac_data.mac[i][5]);
  100. printf("MAC %d %s\n", i, ethaddr[i]);
  101. sprintf((char *)enetvar,
  102. i ? "eth%daddr" : "ethaddr", i);
  103. setenv((char *)enetvar, (char *)ethaddr[i]);
  104. }
  105. return 0;
  106. }
  107. int mac_read(void)
  108. {
  109. int ret, length;
  110. unsigned int crc = 0;
  111. unsigned char dev = ID_EEPROM_ADDR, *data;
  112. length = sizeof(EEPROM_data);
  113. ret = i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length);
  114. if (ret) {
  115. printf("Read failed.\n");
  116. return -1;
  117. }
  118. data = (unsigned char *)(&mac_data);
  119. printf("Check CRC on reading ...");
  120. crc = crc32(crc, data, length - 4);
  121. if (crc != mac_data.crc) {
  122. printf("CRC checksum is invalid, in EEPROM CRC is %x, calculated CRC is %x\n",
  123. mac_data.crc, crc);
  124. return -1;
  125. } else {
  126. printf("CRC OK\n");
  127. mac_show();
  128. }
  129. return 0;
  130. }
  131. int mac_prog(void)
  132. {
  133. int ret, i, length;
  134. unsigned int crc = 0;
  135. unsigned char dev = ID_EEPROM_ADDR, *ptr;
  136. unsigned char *eeprom_data = (unsigned char *)(&mac_data);
  137. mac_data.res_0 = 0;
  138. memset((void *)mac_data.res_1, 0, sizeof(mac_data.res_1));
  139. length = sizeof(EEPROM_data);
  140. crc = crc32(crc, eeprom_data, length - 4);
  141. mac_data.crc = crc;
  142. for (i = 0, ptr = eeprom_data; i < length; i += 8, ptr += 8) {
  143. ret = i2c_write(dev, i, 1, ptr, min((length - i),8));
  144. udelay(5000); /* 5ms write cycle timing */
  145. if (ret)
  146. break;
  147. }
  148. if (ret) {
  149. printf("Programming failed.\n");
  150. return -1;
  151. } else {
  152. printf("Programming %d bytes. Reading back ...\n", length);
  153. mac_read();
  154. }
  155. return 0;
  156. }
  157. int do_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  158. {
  159. int i;
  160. char cmd = 's';
  161. unsigned long long mac_val;
  162. if (i2c_probe(ID_EEPROM_ADDR) != 0)
  163. return -1;
  164. if (argc > 1) {
  165. cmd = argv[1][0];
  166. switch (cmd) {
  167. case 'r': /* display */
  168. mac_read();
  169. break;
  170. case 's': /* save */
  171. mac_prog();
  172. break;
  173. case 'i': /* id */
  174. for (i = 0; i < 4; i++) {
  175. mac_data.id[i] = argv[2][i];
  176. }
  177. break;
  178. case 'n': /* serial number */
  179. for (i = 0; i < 12; i++) {
  180. mac_data.sn[i] = argv[2][i];
  181. }
  182. break;
  183. case 'e': /* errata */
  184. for (i = 0; i < 5; i++) {
  185. mac_data.errata[i] = argv[2][i];
  186. }
  187. break;
  188. case 'd': /* date */
  189. mac_val = simple_strtoull(argv[2], NULL, 16);
  190. for (i = 0; i < 6; i++) {
  191. mac_data.date[i] = (mac_val >> (40 - 8 * i));
  192. }
  193. break;
  194. case 'p': /* mac table size */
  195. mac_data.mac_size =
  196. (unsigned char)simple_strtoul(argv[2], NULL, 16);
  197. break;
  198. case '0': /* mac 0 */
  199. case '1': /* mac 1 */
  200. case '2': /* mac 2 */
  201. case '3': /* mac 3 */
  202. case '4': /* mac 4 */
  203. case '5': /* mac 5 */
  204. case '6': /* mac 6 */
  205. case '7': /* mac 7 */
  206. mac_val = simple_strtoull(argv[2], NULL, 16);
  207. for (i = 0; i < 6; i++) {
  208. mac_data.mac[cmd - '0'][i] =
  209. *((unsigned char *)
  210. (((unsigned int)(&mac_val)) + i + 2));
  211. }
  212. break;
  213. case 'h': /* help */
  214. default:
  215. printf("Usage:\n%s\n", cmdtp->usage);
  216. break;
  217. }
  218. } else {
  219. mac_show();
  220. }
  221. return 0;
  222. }
  223. int mac_read_from_eeprom(void)
  224. {
  225. int length, i;
  226. unsigned char dev = ID_EEPROM_ADDR;
  227. unsigned char *data;
  228. unsigned char ethaddr[4][18];
  229. unsigned char enetvar[32];
  230. unsigned int crc = 0;
  231. length = sizeof(EEPROM_data);
  232. if (i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length)) {
  233. printf("Read failed.\n");
  234. return -1;
  235. }
  236. data = (unsigned char *)(&mac_data);
  237. crc = crc32(crc, data, length - 4);
  238. if (crc != mac_data.crc) {
  239. return -1;
  240. } else {
  241. for (i = 0; i < 4; i++) {
  242. if (memcmp(&mac_data.mac[i], "\0\0\0\0\0\0", 6)) {
  243. sprintf((char *)ethaddr[i],
  244. "%02x:%02x:%02x:%02x:%02x:%02x",
  245. mac_data.mac[i][0],
  246. mac_data.mac[i][1],
  247. mac_data.mac[i][2],
  248. mac_data.mac[i][3],
  249. mac_data.mac[i][4],
  250. mac_data.mac[i][5]);
  251. sprintf((char *)enetvar,
  252. i ? "eth%daddr" : "ethaddr",
  253. i);
  254. setenv((char *)enetvar, (char *)ethaddr[i]);
  255. }
  256. }
  257. }
  258. return 0;
  259. }