rtl8169_mac.c 6.0 KB

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