smc91111_eeprom.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2004
  4. * Robin Getz rgetz@blacfin.uclinux.org
  5. *
  6. * Heavily borrowed from the following peoples GPL'ed software:
  7. * - Wolfgang Denk, DENX Software Engineering, wd@denx.de
  8. * Das U-Boot
  9. * - Ladislav Michl ladis@linux-mips.org
  10. * A rejected patch on the U-Boot mailing list
  11. */
  12. #include <common.h>
  13. #include <exports.h>
  14. #include "../drivers/net/smc91111.h"
  15. #ifndef SMC91111_EEPROM_INIT
  16. # define SMC91111_EEPROM_INIT()
  17. #endif
  18. #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
  19. #define EEPROM 0x1
  20. #define MAC 0x2
  21. #define UNKNOWN 0x4
  22. void dump_reg (struct eth_device *dev);
  23. void dump_eeprom (struct eth_device *dev);
  24. int write_eeprom_reg (struct eth_device *dev, int value, int reg);
  25. void copy_from_eeprom (struct eth_device *dev);
  26. void print_MAC (struct eth_device *dev);
  27. int read_eeprom_reg (struct eth_device *dev, int reg);
  28. void print_macaddr (struct eth_device *dev);
  29. int smc91111_eeprom (int argc, char * const argv[])
  30. {
  31. int c, i, j, done, line, reg, value, start, what;
  32. char input[50];
  33. struct eth_device dev;
  34. dev.iobase = CONFIG_SMC91111_BASE;
  35. /* Print the ABI version */
  36. app_startup (argv);
  37. if (XF_VERSION != (int) get_version ()) {
  38. printf ("Expects ABI version %d\n", XF_VERSION);
  39. printf ("Actual U-Boot ABI version %d\n",
  40. (int) get_version ());
  41. printf ("Can't run\n\n");
  42. return (0);
  43. }
  44. SMC91111_EEPROM_INIT();
  45. if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
  46. printf ("Can't find SMSC91111\n");
  47. return (0);
  48. }
  49. done = 0;
  50. what = UNKNOWN;
  51. printf ("\n");
  52. while (!done) {
  53. /* print the prompt */
  54. printf ("SMC91111> ");
  55. line = 0;
  56. i = 0;
  57. start = 1;
  58. while (!line) {
  59. /* Wait for a keystroke */
  60. while (!tstc ());
  61. c = getc ();
  62. /* Make Uppercase */
  63. if (c >= 'Z')
  64. c -= ('a' - 'A');
  65. /* printf(" |%02x| ",c); */
  66. switch (c) {
  67. case '\r': /* Enter */
  68. case '\n':
  69. input[i] = 0;
  70. puts ("\r\n");
  71. line = 1;
  72. break;
  73. case '\0': /* nul */
  74. continue;
  75. case 0x03: /* ^C - break */
  76. input[0] = 0;
  77. i = 0;
  78. line = 1;
  79. done = 1;
  80. break;
  81. case 0x5F:
  82. case 0x08: /* ^H - backspace */
  83. case 0x7F: /* DEL - backspace */
  84. if (i > 0) {
  85. puts ("\b \b");
  86. i--;
  87. }
  88. break;
  89. default:
  90. if (start) {
  91. if ((c == 'W') || (c == 'D')
  92. || (c == 'M') || (c == 'C')
  93. || (c == 'P')) {
  94. putc (c);
  95. input[i] = c;
  96. if (i <= 45)
  97. i++;
  98. start = 0;
  99. }
  100. } else {
  101. if ((c >= '0' && c <= '9')
  102. || (c >= 'A' && c <= 'F')
  103. || (c == 'E') || (c == 'M')
  104. || (c == ' ')) {
  105. putc (c);
  106. input[i] = c;
  107. if (i <= 45)
  108. i++;
  109. break;
  110. }
  111. }
  112. break;
  113. }
  114. }
  115. for (; i < 49; i++)
  116. input[i] = 0;
  117. switch (input[0]) {
  118. case ('W'):
  119. /* Line should be w reg value */
  120. i = 0;
  121. reg = 0;
  122. value = 0;
  123. /* Skip to the next space or end) */
  124. while ((input[i] != ' ') && (input[i] != 0))
  125. i++;
  126. if (input[i] != 0)
  127. i++;
  128. /* Are we writing to EEPROM or MAC */
  129. switch (input[i]) {
  130. case ('E'):
  131. what = EEPROM;
  132. break;
  133. case ('M'):
  134. what = MAC;
  135. break;
  136. default:
  137. what = UNKNOWN;
  138. break;
  139. }
  140. /* skip to the next space or end */
  141. while ((input[i] != ' ') && (input[i] != 0))
  142. i++;
  143. if (input[i] != 0)
  144. i++;
  145. /* Find register to write into */
  146. j = 0;
  147. while ((input[i] != ' ') && (input[i] != 0)) {
  148. j = input[i] - 0x30;
  149. if (j >= 0xA) {
  150. j -= 0x07;
  151. }
  152. reg = (reg * 0x10) + j;
  153. i++;
  154. }
  155. while ((input[i] != ' ') && (input[i] != 0))
  156. i++;
  157. if (input[i] != 0)
  158. i++;
  159. else
  160. what = UNKNOWN;
  161. /* Get the value to write */
  162. j = 0;
  163. while ((input[i] != ' ') && (input[i] != 0)) {
  164. j = input[i] - 0x30;
  165. if (j >= 0xA) {
  166. j -= 0x07;
  167. }
  168. value = (value * 0x10) + j;
  169. i++;
  170. }
  171. switch (what) {
  172. case 1:
  173. printf ("Writing EEPROM register %02x with %04x\n", reg, value);
  174. write_eeprom_reg (&dev, value, reg);
  175. break;
  176. case 2:
  177. printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
  178. SMC_SELECT_BANK (&dev, reg >> 4);
  179. SMC_outw (&dev, value, reg & 0xE);
  180. break;
  181. default:
  182. printf ("Wrong\n");
  183. break;
  184. }
  185. break;
  186. case ('D'):
  187. dump_eeprom (&dev);
  188. break;
  189. case ('M'):
  190. dump_reg (&dev);
  191. break;
  192. case ('C'):
  193. copy_from_eeprom (&dev);
  194. break;
  195. case ('P'):
  196. print_macaddr (&dev);
  197. break;
  198. default:
  199. break;
  200. }
  201. }
  202. return (0);
  203. }
  204. void copy_from_eeprom (struct eth_device *dev)
  205. {
  206. int i;
  207. SMC_SELECT_BANK (dev, 1);
  208. SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
  209. CTL_RELOAD, CTL_REG);
  210. i = 100;
  211. while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
  212. udelay (100);
  213. if (i == 0) {
  214. printf ("Timeout Refreshing EEPROM registers\n");
  215. } else {
  216. printf ("EEPROM contents copied to MAC\n");
  217. }
  218. }
  219. void print_macaddr (struct eth_device *dev)
  220. {
  221. int i, j, k, mac[6];
  222. printf ("Current MAC Address in SMSC91111 ");
  223. SMC_SELECT_BANK (dev, 1);
  224. for (i = 0; i < 5; i++) {
  225. printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
  226. }
  227. printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
  228. i = 0;
  229. for (j = 0x20; j < 0x23; j++) {
  230. k = read_eeprom_reg (dev, j);
  231. mac[i] = k & 0xFF;
  232. i++;
  233. mac[i] = k >> 8;
  234. i++;
  235. }
  236. printf ("Current MAC Address in EEPROM ");
  237. for (i = 0; i < 5; i++)
  238. printf ("%02x:", mac[i]);
  239. printf ("%02x\n", mac[5]);
  240. }
  241. void dump_eeprom (struct eth_device *dev)
  242. {
  243. int j, k;
  244. printf ("IOS2-0 ");
  245. for (j = 0; j < 8; j++) {
  246. printf ("%03x ", j);
  247. }
  248. printf ("\n");
  249. for (k = 0; k < 4; k++) {
  250. if (k == 0)
  251. printf ("CONFIG ");
  252. if (k == 1)
  253. printf ("BASE ");
  254. if ((k == 2) || (k == 3))
  255. printf (" ");
  256. for (j = 0; j < 0x20; j += 4) {
  257. printf ("%02x:%04x ", j + k,
  258. read_eeprom_reg (dev, j + k));
  259. }
  260. printf ("\n");
  261. }
  262. for (j = 0x20; j < 0x40; j++) {
  263. if ((j & 0x07) == 0)
  264. printf ("\n");
  265. printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
  266. }
  267. printf ("\n");
  268. }
  269. int read_eeprom_reg (struct eth_device *dev, int reg)
  270. {
  271. int timeout;
  272. SMC_SELECT_BANK (dev, 2);
  273. SMC_outw (dev, reg, PTR_REG);
  274. SMC_SELECT_BANK (dev, 1);
  275. SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
  276. CTL_RELOAD, CTL_REG);
  277. timeout = 100;
  278. while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
  279. udelay (100);
  280. if (timeout == 0) {
  281. printf ("Timeout Reading EEPROM register %02x\n", reg);
  282. return 0;
  283. }
  284. return SMC_inw (dev, GP_REG);
  285. }
  286. int write_eeprom_reg (struct eth_device *dev, int value, int reg)
  287. {
  288. int timeout;
  289. SMC_SELECT_BANK (dev, 2);
  290. SMC_outw (dev, reg, PTR_REG);
  291. SMC_SELECT_BANK (dev, 1);
  292. SMC_outw (dev, value, GP_REG);
  293. SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
  294. CTL_STORE, CTL_REG);
  295. timeout = 100;
  296. while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
  297. udelay (100);
  298. if (timeout == 0) {
  299. printf ("Timeout Writing EEPROM register %02x\n", reg);
  300. return 0;
  301. }
  302. return 1;
  303. }
  304. void dump_reg (struct eth_device *dev)
  305. {
  306. int i, j;
  307. printf (" ");
  308. for (j = 0; j < 4; j++) {
  309. printf ("Bank%i ", j);
  310. }
  311. printf ("\n");
  312. for (i = 0; i < 0xF; i += 2) {
  313. printf ("%02x ", i);
  314. for (j = 0; j < 4; j++) {
  315. SMC_SELECT_BANK (dev, j);
  316. printf ("%04x ", SMC_inw (dev, i));
  317. }
  318. printf ("\n");
  319. }
  320. }