rtl.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2014-2018 K. Lange
  5. */
  6. #include <kernel/module.h>
  7. #include <kernel/logging.h>
  8. #include <kernel/printf.h>
  9. #include <kernel/pci.h>
  10. #include <kernel/mem.h>
  11. #include <kernel/pipe.h>
  12. #include <kernel/ipv4.h>
  13. #include <kernel/mod/net.h>
  14. #include <toaru/list.h>
  15. /* XXX move this to ipv4? */
  16. extern size_t print_dns_name(fs_node_t * tty, struct dns_packet * dns, size_t offset);
  17. static uint32_t rtl_device_pci = 0x00000000;
  18. static void find_rtl(uint32_t device, uint16_t vendorid, uint16_t deviceid, void * extra) {
  19. if ((vendorid == 0x10ec) && (deviceid == 0x8139)) {
  20. *((uint32_t *)extra) = device;
  21. }
  22. }
  23. #define RTL_PORT_MAC 0x00
  24. #define RTL_PORT_MAR 0x08
  25. #define RTL_PORT_TXSTAT 0x10
  26. #define RTL_PORT_TXBUF 0x20
  27. #define RTL_PORT_RBSTART 0x30
  28. #define RTL_PORT_CMD 0x37
  29. #define RTL_PORT_RXPTR 0x38
  30. #define RTL_PORT_RXADDR 0x3A
  31. #define RTL_PORT_IMR 0x3C
  32. #define RTL_PORT_ISR 0x3E
  33. #define RTL_PORT_TCR 0x40
  34. #define RTL_PORT_RCR 0x44
  35. #define RTL_PORT_RXMISS 0x4C
  36. #define RTL_PORT_CONFIG 0x52
  37. static list_t * net_queue = NULL;
  38. static spin_lock_t net_queue_lock = { 0 };
  39. static int rtl_irq = 0;
  40. static uint32_t rtl_iobase = 0;
  41. static uint8_t * rtl_rx_buffer;
  42. static uint8_t * rtl_tx_buffer[5];
  43. static uint8_t mac[6];
  44. static uint8_t * last_packet = NULL;
  45. static uintptr_t rtl_rx_phys;
  46. static uintptr_t rtl_tx_phys[5];
  47. static uint32_t cur_rx = 0;
  48. static int dirty_tx = 0;
  49. static int next_tx = 0;
  50. static list_t * rx_wait;
  51. static spin_lock_t _lock;
  52. static int next_tx_buf(void) {
  53. int out;
  54. spin_lock(_lock);
  55. out = next_tx;
  56. next_tx++;
  57. if (next_tx == 4) {
  58. next_tx = 0;
  59. }
  60. spin_unlock(_lock);
  61. return out;
  62. }
  63. void* rtl_dequeue() {
  64. while (!net_queue->length) {
  65. sleep_on(rx_wait);
  66. }
  67. spin_lock(net_queue_lock);
  68. node_t * n = list_dequeue(net_queue);
  69. void* value = (struct ethernet_packet *)n->value;
  70. free(n);
  71. spin_unlock(net_queue_lock);
  72. return value;
  73. }
  74. void rtl_enqueue(void * buffer) {
  75. /* XXX size? source? */
  76. spin_lock(net_queue_lock);
  77. list_insert(net_queue, buffer);
  78. spin_unlock(net_queue_lock);
  79. }
  80. uint8_t* rtl_get_mac() {
  81. return mac;
  82. }
  83. void rtl_send_packet(uint8_t* payload, size_t payload_size) {
  84. int my_tx = next_tx_buf();
  85. memcpy(rtl_tx_buffer[my_tx], payload, payload_size);
  86. outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
  87. outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, payload_size);
  88. }
  89. struct ethernet_packet* rtl_get_packet(void) {
  90. return (struct ethernet_packet*)rtl_dequeue();
  91. }
  92. static int rtl_irq_handler(struct regs *r) {
  93. uint16_t status = inports(rtl_iobase + RTL_PORT_ISR);
  94. if (!status) {
  95. return 0;
  96. }
  97. outports(rtl_iobase + RTL_PORT_ISR, status);
  98. irq_ack(rtl_irq);
  99. if (status & 0x01 || status & 0x02) {
  100. /* Receive */
  101. while((inportb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) {
  102. int offset = cur_rx % 0x2000;
  103. #if 0
  104. uint16_t buf_addr = inports(rtl_iobase + RTL_PORT_RXADDR);
  105. uint16_t buf_ptr = inports(rtl_iobase + RTL_PORT_RXPTR);
  106. uint8_t cmd = inportb(rtl_iobase + RTL_PORT_CMD);
  107. #endif
  108. uint32_t * buf_start = (uint32_t *)((uintptr_t)rtl_rx_buffer + offset);
  109. uint32_t rx_status = buf_start[0];
  110. int rx_size = rx_status >> 16;
  111. if (rx_status & (0x0020 | 0x0010 | 0x0004 | 0x0002)) {
  112. debug_print(WARNING, "rx error :(");
  113. } else {
  114. uint8_t * buf_8 = (uint8_t *)&(buf_start[1]);
  115. last_packet = malloc(rx_size);
  116. uintptr_t packet_end = (uintptr_t)buf_8 + rx_size;
  117. if (packet_end > (uintptr_t)rtl_rx_buffer + 0x2000) {
  118. size_t s = ((uintptr_t)rtl_rx_buffer + 0x2000) - (uintptr_t)buf_8;
  119. memcpy(last_packet, buf_8, s);
  120. memcpy((void *)((uintptr_t)last_packet + s), rtl_rx_buffer, rx_size - s);
  121. } else {
  122. memcpy(last_packet, buf_8, rx_size);
  123. }
  124. rtl_enqueue(last_packet);
  125. }
  126. cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
  127. outports(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16);
  128. }
  129. wakeup_queue(rx_wait);
  130. }
  131. if (status & 0x08 || status & 0x04) {
  132. unsigned int i = inportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * dirty_tx);
  133. (void)i;
  134. dirty_tx++;
  135. if (dirty_tx == 5) dirty_tx = 0;
  136. }
  137. return 1;
  138. }
  139. #if 0
  140. static void rtl_netd(void * data, char * name) {
  141. fs_node_t * tty = data;
  142. {
  143. fprintf(tty, "Sending DNS query...\n");
  144. uint8_t queries[] = {
  145. 3,'i','r','c',
  146. 8,'f','r','e','e','n','o','d','e',
  147. 3,'n','e','t',
  148. 0,
  149. 0x00, 0x01, /* A */
  150. 0x00, 0x01, /* IN */
  151. };
  152. int my_tx = next_tx_buf();
  153. size_t packet_size = write_dns_packet(rtl_tx_buffer[my_tx], sizeof(queries), queries);
  154. outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
  155. outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
  156. }
  157. sleep_on(rx_wait);
  158. parse_dns_response(tty, last_packet);
  159. {
  160. fprintf(tty, "Sending DNS query...\n");
  161. uint8_t queries[] = {
  162. 7,'n','y','a','n','c','a','t',
  163. 5,'d','a','k','k','o',
  164. 2,'u','s',
  165. 0,
  166. 0x00, 0x01, /* A */
  167. 0x00, 0x01, /* IN */
  168. };
  169. int my_tx = next_tx_buf();
  170. size_t packet_size = write_dns_packet(rtl_tx_buffer[my_tx], sizeof(queries), queries);
  171. outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
  172. outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
  173. }
  174. sleep_on(rx_wait);
  175. parse_dns_response(tty, last_packet);
  176. seq_no = krand();
  177. {
  178. fprintf(tty, "Sending TCP syn\n");
  179. int my_tx = next_tx_buf();
  180. uint8_t payload[] = { 0 };
  181. size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], payload, 0, (TCP_FLAGS_SYN | DATA_OFFSET_5));
  182. outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
  183. outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
  184. seq_no += 1;
  185. ack_no = 0;
  186. }
  187. {
  188. struct ethernet_packet * eth = net_receive();
  189. uint16_t eth_type = ntohs(eth->type);
  190. fprintf(tty, "Ethernet II, Src: (%2x:%2x:%2x:%2x:%2x:%2x), Dst: (%2x:%2x:%2x:%2x:%2x:%2x) [type=%4x)\n",
  191. eth->source[0], eth->source[1], eth->source[2],
  192. eth->source[3], eth->source[4], eth->source[5],
  193. eth->destination[0], eth->destination[1], eth->destination[2],
  194. eth->destination[3], eth->destination[4], eth->destination[5],
  195. eth_type);
  196. struct ipv4_packet * ipv4 = (struct ipv4_packet *)eth->payload;
  197. uint32_t src_addr = ntohl(ipv4->source);
  198. uint32_t dst_addr = ntohl(ipv4->destination);
  199. uint16_t length = ntohs(ipv4->length);
  200. char src_ip[16];
  201. char dst_ip[16];
  202. ip_ntoa(src_addr, src_ip);
  203. ip_ntoa(dst_addr, dst_ip);
  204. fprintf(tty, "IP packet [%s → %s] length=%d bytes\n",
  205. src_ip, dst_ip, length);
  206. struct tcp_header * tcp = (struct tcp_header *)ipv4->payload;
  207. if (seq_no != ntohl(tcp->ack_number)) {
  208. fprintf(tty, "[eth] Expected ack number of 0x%x, got 0x%x\n",
  209. seq_no,
  210. ntohl(tcp->ack_number));
  211. fprintf(tty, "[eth] Bailing...\n");
  212. return;
  213. }
  214. ack_no = ntohl(tcp->seq_number) + 1;
  215. free(eth);
  216. }
  217. {
  218. fprintf(tty, "Sending TCP ack\n");
  219. int my_tx = next_tx_buf();
  220. uint8_t payload[] = { 0 };
  221. size_t packet_size = write_tcp_packet(rtl_tx_buffer[my_tx], payload, 0, (TCP_FLAGS_ACK | DATA_OFFSET_5));
  222. outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * my_tx, rtl_tx_phys[my_tx]);
  223. outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * my_tx, packet_size);
  224. }
  225. fprintf(tty, "[eth] s-next=0x%x, r-next=0x%x\n", seq_no, ack_no);
  226. }
  227. #endif
  228. int init_rtl(void) {
  229. if (rtl_device_pci) {
  230. debug_print(NOTICE, "Located an RTL 8139: 0x%x\n", rtl_device_pci);
  231. uint16_t command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
  232. debug_print(NOTICE, "COMMAND register before: 0x%4x\n", command_reg);
  233. if (command_reg & (1 << 2)) {
  234. debug_print(NOTICE, "Bus mastering already enabled.\n");
  235. } else {
  236. command_reg |= (1 << 2); /* bit 2 */
  237. debug_print(NOTICE, "COMMAND register after: 0x%4x\n", command_reg);
  238. pci_write_field(rtl_device_pci, PCI_COMMAND, 4, command_reg);
  239. command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
  240. debug_print(NOTICE, "COMMAND register after: 0x%4x\n", command_reg);
  241. }
  242. rtl_irq = pci_get_interrupt(rtl_device_pci);
  243. debug_print(NOTICE, "Interrupt Line: %x\n", rtl_irq);
  244. irq_install_handler(rtl_irq, rtl_irq_handler, "rtl8139");
  245. uint32_t rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
  246. uint32_t rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4);
  247. debug_print(NOTICE, "BAR0: 0x%8x\n", rtl_bar0);
  248. debug_print(NOTICE, "BAR1: 0x%8x\n", rtl_bar1);
  249. rtl_iobase = 0x00000000;
  250. if (rtl_bar0 & 0x00000001) {
  251. rtl_iobase = rtl_bar0 & 0xFFFFFFFC;
  252. } else {
  253. debug_print(NOTICE, "This doesn't seem right! RTL8139 should be using an I/O BAR; this looks like a memory bar.");
  254. }
  255. debug_print(NOTICE, "RTL iobase: 0x%x\n", rtl_iobase);
  256. rx_wait = list_create();
  257. debug_print(NOTICE, "Determining mac address...\n");
  258. for (int i = 0; i < 6; ++i) {
  259. mac[i] = inports(rtl_iobase + RTL_PORT_MAC + i);
  260. }
  261. debug_print(NOTICE, "%2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  262. debug_print(NOTICE, "Enabling RTL8139.\n");
  263. outportb(rtl_iobase + RTL_PORT_CONFIG, 0x0);
  264. debug_print(NOTICE, "Resetting RTL8139.\n");
  265. outportb(rtl_iobase + RTL_PORT_CMD, 0x10);
  266. while ((inportb(rtl_iobase + 0x37) & 0x10) != 0) { }
  267. debug_print(NOTICE, "Done resetting RTL8139.\n");
  268. for (int i = 0; i < 5; ++i) {
  269. rtl_tx_buffer[i] = (void*)kvmalloc_p(0x1000, &rtl_tx_phys[i]);
  270. for (int j = 0; j < 60; ++j) {
  271. rtl_tx_buffer[i][j] = 0xF0;
  272. }
  273. }
  274. rtl_rx_buffer = (uint8_t *)kvmalloc_p(0x3000, &rtl_rx_phys);
  275. memset(rtl_rx_buffer, 0x00, 0x3000);
  276. debug_print(NOTICE, "Buffers:\n");
  277. debug_print(NOTICE, " rx 0x%x [phys 0x%x and 0x%x and 0x%x]\n", rtl_rx_buffer, rtl_rx_phys, map_to_physical((uintptr_t)rtl_rx_buffer + 0x1000), map_to_physical((uintptr_t)rtl_rx_buffer + 0x2000));
  278. for (int i = 0; i < 5; ++i) {
  279. debug_print(NOTICE, " tx 0x%x [phys 0x%x]\n", rtl_tx_buffer[i], rtl_tx_phys[i]);
  280. }
  281. debug_print(NOTICE, "Initializing receive buffer.\n");
  282. outportl(rtl_iobase + RTL_PORT_RBSTART, rtl_rx_phys);
  283. debug_print(NOTICE, "Enabling IRQs.\n");
  284. outports(rtl_iobase + RTL_PORT_IMR,
  285. 0x8000 | /* PCI error */
  286. 0x4000 | /* PCS timeout */
  287. 0x40 | /* Rx FIFO over */
  288. 0x20 | /* Rx underrun */
  289. 0x10 | /* Rx overflow */
  290. 0x08 | /* Tx error */
  291. 0x04 | /* Tx okay */
  292. 0x02 | /* Rx error */
  293. 0x01 /* Rx okay */
  294. ); /* TOK, ROK */
  295. debug_print(NOTICE, "Configuring transmit\n");
  296. outportl(rtl_iobase + RTL_PORT_TCR,
  297. 0
  298. );
  299. debug_print(NOTICE, "Configuring receive buffer.\n");
  300. outportl(rtl_iobase + RTL_PORT_RCR,
  301. (0) | /* 8K receive */
  302. 0x08 | /* broadcast */
  303. 0x01 /* all physical */
  304. );
  305. debug_print(NOTICE, "Enabling receive and transmit.\n");
  306. outportb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04);
  307. debug_print(NOTICE, "Resetting rx stats\n");
  308. outportl(rtl_iobase + RTL_PORT_RXMISS, 0);
  309. net_queue = list_create();
  310. debug_print(NOTICE, "Initializing netif functions\n");
  311. init_netif_funcs(rtl_get_mac, rtl_get_packet, rtl_send_packet, "RTL8139");
  312. debug_print(NOTICE, "Back from starting the worker thread.\n");
  313. } else {
  314. return -1;
  315. }
  316. return 0;
  317. }
  318. static int init(void) {
  319. pci_scan(&find_rtl, -1, &rtl_device_pci);
  320. if (!rtl_device_pci) {
  321. debug_print(NOTICE, "No RTL 8139 found");
  322. return 1;
  323. }
  324. init_rtl();
  325. return 0;
  326. }
  327. static int fini(void) {
  328. return 0;
  329. }
  330. MODULE_DEF(rtl, init, fini);
  331. MODULE_DEPENDS(net);