rtl8169_mac.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. */
  19. #include <common.h>
  20. #include "rtl8169.h"
  21. static unsigned char *PCI_MEMR;
  22. static void mac_delay(unsigned int cnt)
  23. {
  24. udelay(cnt);
  25. }
  26. static void mac_pci_setup(void)
  27. {
  28. unsigned long pci_data;
  29. PCI_PAR = 0x00000010;
  30. PCI_PDR = 0x00001000;
  31. PCI_PAR = 0x00000004;
  32. pci_data = PCI_PDR;
  33. PCI_PDR = pci_data | 0x00000007;
  34. PCI_PAR = 0x00000010;
  35. PCI_MEMR = (unsigned char *)((PCI_PDR | 0xFE240050) & 0xFFFFFFF0);
  36. }
  37. static void EECS(int level)
  38. {
  39. unsigned char data = *PCI_MEMR;
  40. if (level)
  41. *PCI_MEMR = data | 0x08;
  42. else
  43. *PCI_MEMR = data & 0xf7;
  44. }
  45. static void EECLK(int level)
  46. {
  47. unsigned char data = *PCI_MEMR;
  48. if (level)
  49. *PCI_MEMR = data | 0x04;
  50. else
  51. *PCI_MEMR = data & 0xfb;
  52. }
  53. static void EEDI(int level)
  54. {
  55. unsigned char data = *PCI_MEMR;
  56. if (level)
  57. *PCI_MEMR = data | 0x02;
  58. else
  59. *PCI_MEMR = data & 0xfd;
  60. }
  61. static inline void sh7785lcr_bitset(unsigned short bit)
  62. {
  63. if (bit)
  64. EEDI(HIGH);
  65. else
  66. EEDI(LOW);
  67. EECLK(LOW);
  68. mac_delay(TIME1);
  69. EECLK(HIGH);
  70. mac_delay(TIME1);
  71. EEDI(LOW);
  72. }
  73. static inline unsigned char sh7785lcr_bitget(void)
  74. {
  75. unsigned char bit;
  76. EECLK(LOW);
  77. mac_delay(TIME1);
  78. bit = *PCI_MEMR & 0x01;
  79. EECLK(HIGH);
  80. mac_delay(TIME1);
  81. return bit;
  82. }
  83. static inline void sh7785lcr_setcmd(unsigned char command)
  84. {
  85. sh7785lcr_bitset(BIT_DUMMY);
  86. switch (command) {
  87. case MAC_EEP_READ:
  88. sh7785lcr_bitset(1);
  89. sh7785lcr_bitset(1);
  90. sh7785lcr_bitset(0);
  91. break;
  92. case MAC_EEP_WRITE:
  93. sh7785lcr_bitset(1);
  94. sh7785lcr_bitset(0);
  95. sh7785lcr_bitset(1);
  96. break;
  97. case MAC_EEP_ERACE:
  98. sh7785lcr_bitset(1);
  99. sh7785lcr_bitset(1);
  100. sh7785lcr_bitset(1);
  101. break;
  102. case MAC_EEP_EWEN:
  103. sh7785lcr_bitset(1);
  104. sh7785lcr_bitset(0);
  105. sh7785lcr_bitset(0);
  106. break;
  107. case MAC_EEP_EWDS:
  108. sh7785lcr_bitset(1);
  109. sh7785lcr_bitset(0);
  110. sh7785lcr_bitset(0);
  111. break;
  112. default:
  113. break;
  114. }
  115. }
  116. static inline unsigned short sh7785lcr_getdt(void)
  117. {
  118. unsigned short data = 0;
  119. int i;
  120. sh7785lcr_bitget(); /* DUMMY */
  121. for (i = 0 ; i < 16 ; i++) {
  122. data <<= 1;
  123. data |= sh7785lcr_bitget();
  124. }
  125. return data;
  126. }
  127. static inline void sh7785lcr_setadd(unsigned short address)
  128. {
  129. sh7785lcr_bitset(address & 0x0020); /* A5 */
  130. sh7785lcr_bitset(address & 0x0010); /* A4 */
  131. sh7785lcr_bitset(address & 0x0008); /* A3 */
  132. sh7785lcr_bitset(address & 0x0004); /* A2 */
  133. sh7785lcr_bitset(address & 0x0002); /* A1 */
  134. sh7785lcr_bitset(address & 0x0001); /* A0 */
  135. }
  136. static inline void sh7785lcr_setdata(unsigned short data)
  137. {
  138. sh7785lcr_bitset(data & 0x8000);
  139. sh7785lcr_bitset(data & 0x4000);
  140. sh7785lcr_bitset(data & 0x2000);
  141. sh7785lcr_bitset(data & 0x1000);
  142. sh7785lcr_bitset(data & 0x0800);
  143. sh7785lcr_bitset(data & 0x0400);
  144. sh7785lcr_bitset(data & 0x0200);
  145. sh7785lcr_bitset(data & 0x0100);
  146. sh7785lcr_bitset(data & 0x0080);
  147. sh7785lcr_bitset(data & 0x0040);
  148. sh7785lcr_bitset(data & 0x0020);
  149. sh7785lcr_bitset(data & 0x0010);
  150. sh7785lcr_bitset(data & 0x0008);
  151. sh7785lcr_bitset(data & 0x0004);
  152. sh7785lcr_bitset(data & 0x0002);
  153. sh7785lcr_bitset(data & 0x0001);
  154. }
  155. static void sh7785lcr_datawrite(const unsigned short *data, unsigned short address,
  156. unsigned int count)
  157. {
  158. unsigned int i;
  159. for (i = 0; i < count; i++) {
  160. EECS(HIGH);
  161. EEDI(LOW);
  162. mac_delay(TIME1);
  163. sh7785lcr_setcmd(MAC_EEP_WRITE);
  164. sh7785lcr_setadd(address++);
  165. sh7785lcr_setdata(*(data + i));
  166. EECLK(LOW);
  167. EEDI(LOW);
  168. EECS(LOW);
  169. mac_delay(TIME2);
  170. }
  171. }
  172. static void sh7785lcr_macerase(void)
  173. {
  174. unsigned int i;
  175. unsigned short pci_address = 7;
  176. for (i = 0; i < 3; i++) {
  177. EECS(HIGH);
  178. EEDI(LOW);
  179. mac_delay(TIME1);
  180. sh7785lcr_setcmd(MAC_EEP_ERACE);
  181. sh7785lcr_setadd(pci_address++);
  182. mac_delay(TIME1);
  183. EECLK(LOW);
  184. EEDI(LOW);
  185. EECS(LOW);
  186. }
  187. mac_delay(TIME2);
  188. printf("\n\nErace End\n");
  189. for (i = 0; i < 10; i++)
  190. mac_delay(TIME2);
  191. }
  192. static void sh7785lcr_macwrite(unsigned short *data)
  193. {
  194. sh7785lcr_macerase();
  195. sh7785lcr_datawrite(EEPROM_W_Data_8169_A, 0x0000, 7);
  196. sh7785lcr_datawrite(data, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
  197. sh7785lcr_datawrite(EEPROM_W_Data_8169_B, 0x000a, 54);
  198. }
  199. void sh7785lcr_macdtrd(unsigned char *buf, unsigned short address, unsigned int count)
  200. {
  201. unsigned int i;
  202. unsigned short wk;
  203. for (i = 0 ; i < count; i++) {
  204. EECS(HIGH);
  205. EEDI(LOW);
  206. mac_delay(TIME1);
  207. sh7785lcr_setcmd(MAC_EEP_READ);
  208. sh7785lcr_setadd(address++);
  209. wk = sh7785lcr_getdt();
  210. *buf++ = (unsigned char)(wk & 0xff);
  211. *buf++ = (unsigned char)((wk >> 8) & 0xff);
  212. EECLK(LOW);
  213. EEDI(LOW);
  214. EECS(LOW);
  215. }
  216. }
  217. static void sh7785lcr_macadrd(unsigned char *buf)
  218. {
  219. *PCI_MEMR = PCI_PROG;
  220. sh7785lcr_macdtrd(buf, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
  221. }
  222. static void sh7785lcr_eepewen(void)
  223. {
  224. *PCI_MEMR = PCI_PROG;
  225. mac_delay(TIME1);
  226. EECS(LOW);
  227. EECLK(LOW);
  228. EEDI(LOW);
  229. EECS(HIGH);
  230. mac_delay(TIME1);
  231. sh7785lcr_setcmd(MAC_EEP_EWEN);
  232. sh7785lcr_bitset(1);
  233. sh7785lcr_bitset(1);
  234. sh7785lcr_bitset(BIT_DUMMY);
  235. sh7785lcr_bitset(BIT_DUMMY);
  236. sh7785lcr_bitset(BIT_DUMMY);
  237. sh7785lcr_bitset(BIT_DUMMY);
  238. EECLK(LOW);
  239. EEDI(LOW);
  240. EECS(LOW);
  241. mac_delay(TIME1);
  242. }
  243. void mac_write(unsigned short *data)
  244. {
  245. mac_pci_setup();
  246. sh7785lcr_eepewen();
  247. sh7785lcr_macwrite(data);
  248. }
  249. void mac_read(void)
  250. {
  251. unsigned char data[6];
  252. mac_pci_setup();
  253. sh7785lcr_macadrd(data);
  254. printf("Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
  255. data[0], data[1], data[2], data[3], data[4], data[5]);
  256. }
  257. int do_set_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  258. {
  259. int i;
  260. unsigned char mac[6];
  261. char *s, *e;
  262. if (argc != 2) {
  263. cmd_usage(cmdtp);
  264. return 1;
  265. }
  266. s = argv[1];
  267. for (i = 0; i < 6; i++) {
  268. mac[i] = s ? simple_strtoul(s, &e, 16) : 0;
  269. if (s)
  270. s = (*e) ? e + 1 : e;
  271. }
  272. mac_write((unsigned short *)mac);
  273. return 0;
  274. }
  275. U_BOOT_CMD(
  276. setmac, 2, 1, do_set_mac,
  277. "setmac - write MAC address for RTL8110SCL\n",
  278. "\n"
  279. "setmac <mac address> - write MAC address for RTL8110SCL\n"
  280. );
  281. int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  282. {
  283. if (argc != 1) {
  284. cmd_usage(cmdtp);
  285. return 1;
  286. }
  287. mac_read();
  288. return 0;
  289. }
  290. U_BOOT_CMD(
  291. printmac, 1, 1, do_print_mac,
  292. "printmac - print MAC address for RTL8110\n",
  293. "\n"
  294. " - print MAC address for RTL8110\n"
  295. );