smc91111_eeprom.c 8.0 KB

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