rtl8169_mac.c 6.0 KB

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