sys_eeprom.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Based on board/freescale/common/sys_eeprom.c
  4. * Copyright 2006, 2008-2009, 2011 Freescale Semiconductor
  5. *
  6. * This defines the API for storing board information in the
  7. * eeprom. It has been adapted from an earlier version of the
  8. * Freescale API, but has a number of key differences. Because
  9. * the two APIs are independent and may diverge further, the
  10. * Varisys version of the API is implemented separately here.
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. #include <env.h>
  15. #include <i2c.h>
  16. #include <linux/ctype.h>
  17. #include <u-boot/crc.h>
  18. #include "eeprom.h"
  19. #ifdef CONFIG_SYS_I2C_EEPROM_NXID_MAC
  20. #define MAX_NUM_PORTS CONFIG_SYS_I2C_EEPROM_NXID_MAC
  21. #else
  22. #define MAX_NUM_PORTS 8
  23. #endif
  24. #define NXID_VERSION 0
  25. /**
  26. * static eeprom: EEPROM layout for NXID formats
  27. *
  28. * See Freescale application note AN3638 for details.
  29. */
  30. static struct __attribute__ ((__packed__)) eeprom {
  31. u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */
  32. u8 sn[12]; /* 0x04 - 0x0F Serial Number */
  33. u8 errata[5]; /* 0x10 - 0x14 Errata Level */
  34. u8 date[6]; /* 0x15 - 0x1a Build Date */
  35. u8 res_0; /* 0x1b Reserved */
  36. u32 version; /* 0x1c - 0x1f NXID Version */
  37. u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */
  38. u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
  39. u8 tempcalflags; /* 0x2a Temperature Calibration Flags */
  40. u8 res_1[21]; /* 0x2b - 0x3f Reserved */
  41. u8 mac_count; /* 0x40 Number of MAC addresses */
  42. u8 mac_flag; /* 0x41 MAC table flags */
  43. u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - x MAC addresses */
  44. u32 crc; /* x+1 CRC32 checksum */
  45. } e;
  46. /* Set to 1 if we've read EEPROM into memory */
  47. static int has_been_read;
  48. /* Is this a valid NXID EEPROM? */
  49. #define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \
  50. (e.id[2] == 'I') || (e.id[3] == 'D'))
  51. /** Fixed ID field in EEPROM */
  52. static unsigned char uid[16];
  53. static int eeprom_bus_num = -1;
  54. static int eeprom_addr;
  55. static int eeprom_addr_len;
  56. /**
  57. * This must be called before any eeprom access.
  58. */
  59. void init_eeprom(int bus_num, int addr, int addr_len)
  60. {
  61. eeprom_bus_num = bus_num;
  62. eeprom_addr = addr;
  63. eeprom_addr_len = addr_len;
  64. }
  65. /**
  66. * show_eeprom - display the contents of the EEPROM
  67. */
  68. void show_eeprom(void)
  69. {
  70. int i;
  71. unsigned int crc;
  72. /* EEPROM tag ID, either CCID or NXID */
  73. printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
  74. be32_to_cpu(e.version));
  75. /* Serial number */
  76. printf("SN: %s\n", e.sn);
  77. printf("UID: ");
  78. for (i = 0; i < 16; i++)
  79. printf("%02x", uid[i]);
  80. printf("\n");
  81. /* Errata level. */
  82. printf("Errata: %s\n", e.errata);
  83. /* Build date, BCD date values, as YYMMDDhhmmss */
  84. printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n",
  85. e.date[0], e.date[1], e.date[2],
  86. e.date[3] & 0x7F, e.date[4], e.date[5],
  87. e.date[3] & 0x80 ? "PM" : "");
  88. /* Show MAC addresses */
  89. for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
  90. u8 *p = e.mac[i];
  91. printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i,
  92. p[0], p[1], p[2], p[3], p[4], p[5]);
  93. }
  94. crc = crc32(0, (void *)&e, sizeof(e) - 4);
  95. if (crc == be32_to_cpu(e.crc))
  96. printf("CRC: %08x\n", be32_to_cpu(e.crc));
  97. else
  98. printf("CRC: %08x (should be %08x)\n",
  99. be32_to_cpu(e.crc), crc);
  100. #ifdef DEBUG
  101. printf("EEPROM dump: (0x%x bytes)\n", sizeof(e));
  102. for (i = 0; i < sizeof(e); i++) {
  103. if ((i % 16) == 0)
  104. printf("%02X: ", i);
  105. printf("%02X ", ((u8 *)&e)[i]);
  106. if (((i % 16) == 15) || (i == sizeof(e) - 1))
  107. printf("\n");
  108. }
  109. #endif
  110. }
  111. /**
  112. * read_eeprom - read the EEPROM into memory
  113. */
  114. int read_eeprom(void)
  115. {
  116. int ret;
  117. unsigned int bus;
  118. if (eeprom_bus_num < 0) {
  119. printf("EEPROM not configured\n");
  120. return -1;
  121. }
  122. if (has_been_read)
  123. return 0;
  124. bus = i2c_get_bus_num();
  125. i2c_set_bus_num(eeprom_bus_num);
  126. ret = i2c_read(eeprom_addr, 0, eeprom_addr_len,
  127. (void *)&e, sizeof(e));
  128. /* Fixed address of ID field */
  129. i2c_read(0x5f, 0x80, 1, uid, 16);
  130. i2c_set_bus_num(bus);
  131. #ifdef DEBUG
  132. show_eeprom();
  133. #endif
  134. has_been_read = (ret == 0) ? 1 : 0;
  135. return ret;
  136. }
  137. /**
  138. * update_crc - update the CRC
  139. *
  140. * This function should be called after each update to the EEPROM structure,
  141. * to make sure the CRC is always correct.
  142. */
  143. static void update_crc(void)
  144. {
  145. u32 crc, crc_offset = offsetof(struct eeprom, crc);
  146. crc = crc32(0, (void *)&e, crc_offset);
  147. e.crc = cpu_to_be32(crc);
  148. }
  149. /**
  150. * prog_eeprom - write the EEPROM from memory
  151. */
  152. static int prog_eeprom(void)
  153. {
  154. int ret = 0;
  155. int i;
  156. void *p;
  157. unsigned int bus;
  158. if (eeprom_bus_num < 0) {
  159. printf("EEPROM not configured\n");
  160. return -1;
  161. }
  162. /* Set the reserved values to 0xFF */
  163. e.res_0 = 0xFF;
  164. memset(e.res_1, 0xFF, sizeof(e.res_1));
  165. update_crc();
  166. bus = i2c_get_bus_num();
  167. i2c_set_bus_num(eeprom_bus_num);
  168. /*
  169. * The AT24C02 datasheet says that data can only be written in page
  170. * mode, which means 8 bytes at a time, and it takes up to 5ms to
  171. * complete a given write.
  172. */
  173. for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
  174. ret = i2c_write(eeprom_addr, i, eeprom_addr_len,
  175. p, min((int)(sizeof(e) - i), 8));
  176. if (ret)
  177. break;
  178. udelay(5000); /* 5ms write cycle timing */
  179. }
  180. if (!ret) {
  181. /* Verify the write by reading back the EEPROM and comparing */
  182. struct eeprom e2;
  183. ret = i2c_read(eeprom_addr, 0,
  184. eeprom_addr_len, (void *)&e2, sizeof(e2));
  185. if (!ret && memcmp(&e, &e2, sizeof(e)))
  186. ret = -1;
  187. }
  188. i2c_set_bus_num(bus);
  189. if (ret) {
  190. printf("Programming failed.\n");
  191. has_been_read = 0;
  192. return -1;
  193. }
  194. printf("Programming passed.\n");
  195. return 0;
  196. }
  197. /**
  198. * h2i - converts hex character into a number
  199. *
  200. * This function takes a hexadecimal character (e.g. '7' or 'C') and returns
  201. * the integer equivalent.
  202. */
  203. static inline u8 h2i(char p)
  204. {
  205. if ((p >= '0') && (p <= '9'))
  206. return p - '0';
  207. if ((p >= 'A') && (p <= 'F'))
  208. return (p - 'A') + 10;
  209. if ((p >= 'a') && (p <= 'f'))
  210. return (p - 'a') + 10;
  211. return 0;
  212. }
  213. /**
  214. * set_date - stores the build date into the EEPROM
  215. *
  216. * This function takes a pointer to a string in the format "YYMMDDhhmmss"
  217. * (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string,
  218. * and stores it in the build date field of the EEPROM local copy.
  219. */
  220. static void set_date(const char *string)
  221. {
  222. unsigned int i;
  223. if (strlen(string) != 12) {
  224. printf("Usage: mac date YYMMDDhhmmss\n");
  225. return;
  226. }
  227. for (i = 0; i < 6; i++)
  228. e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
  229. update_crc();
  230. }
  231. /**
  232. * set_mac_address - stores a MAC address into the EEPROM
  233. *
  234. * This function takes a pointer to MAC address string
  235. * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and
  236. * stores it in one of the MAC address fields of the EEPROM local copy.
  237. */
  238. static void set_mac_address(unsigned int index, const char *string)
  239. {
  240. char *p = (char *)string;
  241. unsigned int i;
  242. if ((index >= MAX_NUM_PORTS) || !string) {
  243. printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n");
  244. return;
  245. }
  246. for (i = 0; *p && (i < 6); i++) {
  247. e.mac[index][i] = simple_strtoul(p, &p, 16);
  248. if (*p == ':')
  249. p++;
  250. }
  251. update_crc();
  252. }
  253. int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  254. {
  255. char cmd;
  256. if (argc == 1) {
  257. show_eeprom();
  258. return 0;
  259. }
  260. cmd = argv[1][0];
  261. if (cmd == 'r') {
  262. read_eeprom();
  263. return 0;
  264. }
  265. if (cmd == 'i') {
  266. memcpy(e.id, "NXID", sizeof(e.id));
  267. e.version = NXID_VERSION;
  268. update_crc();
  269. return 0;
  270. }
  271. if (!is_valid) {
  272. printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n");
  273. return 0;
  274. }
  275. if (argc == 2) {
  276. switch (cmd) {
  277. case 's': /* save */
  278. prog_eeprom();
  279. break;
  280. default:
  281. return cmd_usage(cmdtp);
  282. }
  283. return 0;
  284. }
  285. /* We know we have at least one parameter */
  286. switch (cmd) {
  287. case 'n': /* serial number */
  288. memset(e.sn, 0, sizeof(e.sn));
  289. strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
  290. update_crc();
  291. break;
  292. case 'e': /* errata */
  293. memset(e.errata, 0, 5);
  294. strncpy((char *)e.errata, argv[2], 4);
  295. update_crc();
  296. break;
  297. case 'd': /* date BCD format YYMMDDhhmmss */
  298. set_date(argv[2]);
  299. break;
  300. case 'p': /* MAC table size */
  301. e.mac_count = simple_strtoul(argv[2], NULL, 16);
  302. update_crc();
  303. break;
  304. case '0' ... '9': /* "mac 0" through "mac 22" */
  305. set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]);
  306. break;
  307. case 'h': /* help */
  308. default:
  309. return cmd_usage(cmdtp);
  310. }
  311. return 0;
  312. }
  313. int mac_read_from_generic_eeprom(const char *envvar, int chip,
  314. int address, int mac_bus)
  315. {
  316. int ret;
  317. unsigned int bus;
  318. unsigned char mac[6];
  319. char ethaddr[18];
  320. bus = i2c_get_bus_num();
  321. i2c_set_bus_num(mac_bus);
  322. ret = i2c_read(chip, address, 1, mac, 6);
  323. i2c_set_bus_num(bus);
  324. if (!ret) {
  325. sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
  326. mac[0],
  327. mac[1],
  328. mac[2],
  329. mac[3],
  330. mac[4],
  331. mac[5]);
  332. printf("MAC: %s\n", ethaddr);
  333. env_set(envvar, ethaddr);
  334. }
  335. return ret;
  336. }
  337. void mac_read_from_fixed_id(void)
  338. {
  339. #ifdef CONFIG_SYS_I2C_MAC1_CHIP_ADDR
  340. mac_read_from_generic_eeprom("ethaddr", CONFIG_SYS_I2C_MAC1_CHIP_ADDR,
  341. CONFIG_SYS_I2C_MAC1_DATA_ADDR, CONFIG_SYS_I2C_MAC1_BUS);
  342. #endif
  343. #ifdef CONFIG_SYS_I2C_MAC2_CHIP_ADDR
  344. mac_read_from_generic_eeprom("eth1addr", CONFIG_SYS_I2C_MAC2_CHIP_ADDR,
  345. CONFIG_SYS_I2C_MAC2_DATA_ADDR, CONFIG_SYS_I2C_MAC2_BUS);
  346. #endif
  347. }
  348. /**
  349. * mac_read_from_eeprom - read the MAC addresses from EEPROM
  350. *
  351. * This function reads the MAC addresses from EEPROM and sets the
  352. * appropriate environment variables for each one read.
  353. *
  354. * The environment variables are only set if they haven't been set already.
  355. * This ensures that any user-saved variables are never overwritten.
  356. *
  357. * This function must be called after relocation.
  358. *
  359. * For NXID v1 EEPROMs, we support loading and up-converting the older NXID v0
  360. * format. In a v0 EEPROM, there are only eight MAC addresses and the CRC is
  361. * located at a different offset.
  362. */
  363. int mac_read_from_eeprom_common(void)
  364. {
  365. unsigned int i;
  366. u32 crc, crc_offset = offsetof(struct eeprom, crc);
  367. u32 *crcp; /* Pointer to the CRC in the data read from the EEPROM */
  368. puts("EEPROM: ");
  369. if (read_eeprom()) {
  370. printf("Read failed.\n");
  371. return 0;
  372. }
  373. if (!is_valid) {
  374. printf("Invalid ID (%02x %02x %02x %02x)\n",
  375. e.id[0], e.id[1], e.id[2], e.id[3]);
  376. return 0;
  377. }
  378. crc = crc32(0, (void *)&e, crc_offset);
  379. crcp = (void *)&e + crc_offset;
  380. if (crc != be32_to_cpu(*crcp)) {
  381. printf("CRC mismatch (%08x != %08x)\n", crc,
  382. be32_to_cpu(e.crc));
  383. return 0;
  384. }
  385. /*
  386. * MAC address #9 in v1 occupies the same position as the CRC in v0.
  387. * Erase it so that it's not mistaken for a MAC address. We'll
  388. * update the CRC later.
  389. */
  390. if (e.version == 0)
  391. memset(e.mac[8], 0xff, 6);
  392. for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
  393. if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
  394. memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
  395. char ethaddr[18];
  396. char enetvar[9];
  397. sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
  398. e.mac[i][0],
  399. e.mac[i][1],
  400. e.mac[i][2],
  401. e.mac[i][3],
  402. e.mac[i][4],
  403. e.mac[i][5]);
  404. sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
  405. /* Only initialize environment variables that are blank
  406. * (i.e. have not yet been set)
  407. */
  408. if (!env_get(enetvar))
  409. env_set(enetvar, ethaddr);
  410. }
  411. }
  412. printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
  413. be32_to_cpu(e.version));
  414. return 0;
  415. }