NE2000NetworkAdapter.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/MACAddress.h>
  27. #include <Kernel/Debug.h>
  28. #include <Kernel/IO.h>
  29. #include <Kernel/Net/NE2000NetworkAdapter.h>
  30. namespace Kernel {
  31. /**
  32. * The NE2000 is an ancient 10 Mib/s Ethernet network card standard by Novell
  33. * from the late 80s. Based on National Semiconductor's DP8390 Ethernet chip
  34. * or compatible, they were known to be extremely bare-bones but also very
  35. * cheap entry-level cards.
  36. *
  37. * QEMU supports them with the ne2k_{isa,pci} devices, physical incarnations
  38. * were available from different manufacturers for the ISA bus and later on
  39. * the PCI bus, including:
  40. * - Realtek's RTL8029
  41. * - VIA Technologies, Inc.'s VT86C926
  42. *
  43. * Official documentation from National Semiconductor includes:
  44. * - Datasheet "DP8390D/NS32490D NIC Network Interface Controller"
  45. * - Application Note 874 "Writing Drivers for the DP8390 NIC Family of Ethernet Controllers"
  46. *
  47. * This driver supports only the PCI variant.
  48. *
  49. * Remember, friends don't let friends use NE2000 network cards :^)
  50. */
  51. // Page 0 registers
  52. static constexpr u8 REG_RW_COMMAND = 0x00;
  53. static constexpr u8 BIT_COMMAND_STOP = (0b1 << 0);
  54. static constexpr u8 BIT_COMMAND_START = (0b1 << 1);
  55. static constexpr u8 BIT_COMMAND_TXP = (0b1 << 2);
  56. static constexpr u8 BIT_COMMAND_DMA_READ = (0b001 << 3);
  57. static constexpr u8 BIT_COMMAND_DMA_WRITE = (0b010 << 3);
  58. static constexpr u8 BIT_COMMAND_DMA_SEND = (0b011 << 3);
  59. static constexpr u8 BIT_COMMAND_DMA_ABORT = (0b100 << 3);
  60. static constexpr u8 BIT_COMMAND_DMA_FIELD = (0b111 << 3);
  61. static constexpr u8 BIT_COMMAND_PAGE1 = (0b01 << 6);
  62. static constexpr u8 BIT_COMMAND_PAGE2 = (0b10 << 6);
  63. static constexpr u8 BIT_COMMAND_PAGE_FIELD = (0b11 << 6);
  64. static constexpr u8 REG_WR_PAGESTART = 0x01;
  65. static constexpr u8 REG_WR_PAGESTOP = 0x02;
  66. static constexpr u8 REG_RW_BOUNDARY = 0x03;
  67. static constexpr u8 REG_RD_TRANSMITSTATUS = 0x04;
  68. static constexpr u8 REG_WR_TRANSMITPAGE = 0x04;
  69. static constexpr u8 REG_RD_NCR = 0x05;
  70. static constexpr u8 REG_WR_TRANSMITBYTECOUNT0 = 0x05;
  71. static constexpr u8 REG_WR_TRANSMITBYTECOUNT1 = 0x06;
  72. static constexpr u8 REG_RW_INTERRUPTSTATUS = 0x07;
  73. static constexpr u8 REG_RD_CRDMA0 = 0x08;
  74. static constexpr u8 REG_WR_REMOTESTARTADDRESS0 = 0x08;
  75. static constexpr u8 REG_RD_CRDMA1 = 0x09;
  76. static constexpr u8 REG_WR_REMOTESTARTADDRESS1 = 0x09;
  77. static constexpr u8 REG_WR_REMOTEBYTECOUNT0 = 0x0a;
  78. static constexpr u8 REG_WR_REMOTEBYTECOUNT1 = 0x0b;
  79. static constexpr u8 REG_RD_RECEIVESTATUS = 0x0c;
  80. static constexpr u8 BIT_RECEIVESTATUS_PRX = (0b1 << 0);
  81. static constexpr u8 BIT_RECEIVESTATUS_CRC = (0b1 << 1);
  82. static constexpr u8 BIT_RECEIVESTATUS_FAE = (0b1 << 2);
  83. static constexpr u8 BIT_RECEIVESTATUS_FO = (0b1 << 3);
  84. static constexpr u8 BIT_RECEIVESTATUS_MPA = (0b1 << 4);
  85. static constexpr u8 REG_WR_RECEIVECONFIGURATION = 0x0c;
  86. static constexpr u8 BIT_RECEIVECONFIGURATION_SEP = (0b1 << 0);
  87. static constexpr u8 BIT_RECEIVECONFIGURATION_AR = (0b1 << 1);
  88. static constexpr u8 BIT_RECEIVECONFIGURATION_AB = (0b1 << 2);
  89. static constexpr u8 BIT_RECEIVECONFIGURATION_AM = (0b1 << 3);
  90. static constexpr u8 BIT_RECEIVECONFIGURATION_PRO = (0b1 << 4);
  91. static constexpr u8 BIT_RECEIVECONFIGURATION_MON = (0b1 << 5);
  92. static constexpr u8 REG_RD_FAE_TALLY = 0x0d;
  93. static constexpr u8 REG_WR_TRANSMITCONFIGURATION = 0x0d;
  94. static constexpr u8 BIT_WR_TRANSMITCONFIGURATION_LOOPBACK = (0b10 << 0);
  95. static constexpr u8 REG_RD_CRC_TALLY = 0x0e;
  96. static constexpr u8 REG_WR_DATACONFIGURATION = 0x0e;
  97. static constexpr u8 BIT_DATACONFIGURATION_WTS = (0b1 << 0);
  98. static constexpr u8 BIT_DATACONFIGURATION_BOS = (0b1 << 1);
  99. static constexpr u8 BIT_DATACONFIGURATION_LS = (0b1 << 2);
  100. static constexpr u8 BIT_DATACONFIGURATION_FIFO_8B = (0b10 << 5);
  101. static constexpr u8 REG_RD_MISS_PKT_TALLY = 0x0f;
  102. static constexpr u8 REG_WR_INTERRUPTMASK = 0x0f;
  103. static constexpr u8 BIT_INTERRUPTMASK_PRX = (0b1 << 0);
  104. static constexpr u8 BIT_INTERRUPTMASK_PTX = (0b1 << 1);
  105. static constexpr u8 BIT_INTERRUPTMASK_RXE = (0b1 << 2);
  106. static constexpr u8 BIT_INTERRUPTMASK_TXE = (0b1 << 3);
  107. static constexpr u8 BIT_INTERRUPTMASK_OVW = (0b1 << 4);
  108. static constexpr u8 BIT_INTERRUPTMASK_CNT = (0b1 << 5);
  109. static constexpr u8 BIT_INTERRUPTMASK_RDC = (0b1 << 6);
  110. static constexpr u8 BIT_INTERRUPTMASK_RST = (0b1 << 7);
  111. static constexpr u8 REG_RW_IOPORT = 0x10;
  112. // Page 1 registers
  113. static constexpr u8 REG_RW_PHYSICALADDRESS0 = 0x01;
  114. static constexpr u8 REG_RW_CURRENT = 0x07;
  115. static constexpr int NE2K_PAGE_SIZE = 256;
  116. static constexpr int NE2K_RAM_BEGIN = 16384;
  117. static constexpr int NE2K_RAM_END = 32768;
  118. static constexpr int NE2K_RAM_SIZE = NE2K_RAM_END - NE2K_RAM_BEGIN;
  119. static constexpr int NE2K_RAM_SEND_BEGIN = 16384;
  120. static constexpr int NE2K_RAM_SEND_END = 16384 + 6 * 256;
  121. static constexpr int NE2K_RAM_SEND_SIZE = NE2K_RAM_SEND_END - NE2K_RAM_SEND_BEGIN;
  122. static constexpr int NE2K_RAM_RECV_BEGIN = NE2K_RAM_SEND_END;
  123. static constexpr int NE2K_RAM_RECV_END = NE2K_RAM_END;
  124. static constexpr int NE2K_RAM_RECV_SIZE = NE2K_RAM_RECV_END - NE2K_RAM_RECV_BEGIN;
  125. static_assert(NE2K_RAM_BEGIN % NE2K_PAGE_SIZE == 0);
  126. static_assert(NE2K_RAM_END % NE2K_PAGE_SIZE == 0);
  127. static_assert(NE2K_RAM_SEND_BEGIN % NE2K_PAGE_SIZE == 0);
  128. static_assert(NE2K_RAM_SEND_END % NE2K_PAGE_SIZE == 0);
  129. static_assert(NE2K_RAM_RECV_BEGIN % NE2K_PAGE_SIZE == 0);
  130. static_assert(NE2K_RAM_RECV_END % NE2K_PAGE_SIZE == 0);
  131. struct [[gnu::packed]] received_packet_header {
  132. u8 status;
  133. u8 next_packet_page;
  134. u16 length;
  135. };
  136. UNMAP_AFTER_INIT void NE2000NetworkAdapter::detect()
  137. {
  138. static const auto ne2k_ids = Array<PCI::ID, 11> {
  139. PCI::ID { 0x10EC, 0x8029 }, // RealTek RTL-8029(AS)
  140. // List of clones, taken from Linux's ne2k-pci.c
  141. PCI::ID { 0x1050, 0x0940 }, // Winbond 89C940
  142. PCI::ID { 0x11f6, 0x1401 }, // Compex RL2000
  143. PCI::ID { 0x8e2e, 0x3000 }, // KTI ET32P2
  144. PCI::ID { 0x4a14, 0x5000 }, // NetVin NV5000SC
  145. PCI::ID { 0x1106, 0x0926 }, // Via 86C926
  146. PCI::ID { 0x10bd, 0x0e34 }, // SureCom NE34
  147. PCI::ID { 0x1050, 0x5a5a }, // Winbond W89C940F
  148. PCI::ID { 0x12c3, 0x0058 }, // Holtek HT80232
  149. PCI::ID { 0x12c3, 0x5598 }, // Holtek HT80229
  150. PCI::ID { 0x8c4a, 0x1980 }, // Winbond W89C940 (misprogrammed)
  151. };
  152. PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
  153. if (address.is_null())
  154. return;
  155. if (!ne2k_ids.span().contains_slow(id))
  156. return;
  157. u8 irq = PCI::get_interrupt_line(address);
  158. [[maybe_unused]] auto& unused = adopt(*new NE2000NetworkAdapter(address, irq)).leak_ref();
  159. });
  160. }
  161. UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq)
  162. : PCI::Device(address, irq)
  163. , m_io_base(PCI::get_BAR0(pci_address()) & ~3)
  164. {
  165. set_interface_name("ne2k");
  166. dmesgln("NE2000: Found @ {}", pci_address());
  167. m_interrupt_line = PCI::get_interrupt_line(pci_address());
  168. dmesgln("NE2000: Port base: {}", m_io_base);
  169. dmesgln("NE2000: Interrupt line: {}", m_interrupt_line);
  170. int ram_errors = ram_test();
  171. dmesgln("NE2000: RAM test {}, got {} byte errors", (ram_errors > 0 ? "OK" : "KO"), ram_errors);
  172. reset();
  173. set_mac_address(m_mac_address);
  174. dmesgln("NE2000: MAC address: {}", m_mac_address.to_string().characters());
  175. enable_irq();
  176. }
  177. UNMAP_AFTER_INIT NE2000NetworkAdapter::~NE2000NetworkAdapter()
  178. {
  179. }
  180. void NE2000NetworkAdapter::handle_irq(const RegisterState&)
  181. {
  182. u8 status = in8(REG_RW_INTERRUPTSTATUS);
  183. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Got interrupt, status=0x{}", String::format("%02x", status));
  184. if (status & BIT_INTERRUPTMASK_PRX) {
  185. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Interrupt for packet received");
  186. }
  187. if (status & BIT_INTERRUPTMASK_PTX) {
  188. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Interrupt for packet sent");
  189. }
  190. if (status & BIT_INTERRUPTMASK_RXE) {
  191. u8 fae = in8(REG_RD_FAE_TALLY);
  192. u8 crc = in8(REG_RD_CRC_TALLY);
  193. u8 miss = in8(REG_RD_MISS_PKT_TALLY);
  194. dmesgln("NE2000NetworkAdapter: Packet reception error framing={} crc={} missed={}", fae, crc, miss);
  195. // TODO: handle counters
  196. }
  197. if (status & BIT_INTERRUPTMASK_TXE) {
  198. dmesgln("NE2000NetworkAdapter: Packet transmission error");
  199. }
  200. if (status & BIT_INTERRUPTMASK_OVW) {
  201. dmesgln("NE2000NetworkAdapter: Ring buffer reception overflow error");
  202. // TODO: handle counters
  203. }
  204. if (status & BIT_INTERRUPTMASK_CNT) {
  205. dmesgln("NE2000NetworkAdapter: Counter overflow error");
  206. // TODO: handle counters
  207. }
  208. if (status & BIT_INTERRUPTMASK_RST) {
  209. dmesgln("NE2000NetworkAdapter: NIC requires reset due to packet reception overflow");
  210. // TODO: proper reset procedure
  211. reset();
  212. }
  213. receive();
  214. m_wait_queue.wake_all();
  215. out8(REG_RW_INTERRUPTSTATUS, status);
  216. }
  217. int NE2000NetworkAdapter::ram_test()
  218. {
  219. IOAddress io(PCI::get_BAR0(pci_address()) & ~3);
  220. int errors = 0;
  221. out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_STOP);
  222. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  223. out8(REG_WR_DATACONFIGURATION, BIT_DATACONFIGURATION_FIFO_8B | BIT_DATACONFIGURATION_WTS);
  224. #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  225. out8(REG_WR_DATACONFIGURATION, BIT_DATACONFIGURATION_FIFO_8B | BIT_DATACONFIGURATION_BOS | BIT_DATACONFIGURATION_WTS);
  226. #else
  227. # error Unknown byte order
  228. #endif
  229. out8(REG_WR_REMOTEBYTECOUNT0, 0x00);
  230. out8(REG_WR_REMOTEBYTECOUNT1, 0x00);
  231. out8(REG_WR_RECEIVECONFIGURATION, BIT_RECEIVECONFIGURATION_MON);
  232. out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_START);
  233. auto buffer = ByteBuffer::create_uninitialized(NE2K_RAM_SIZE);
  234. const u8 patterns[3] = { 0x5a, 0xff, 0x00 };
  235. for (int i = 0; i < 3; ++i) {
  236. for (size_t j = 0; j < buffer.size(); ++j)
  237. buffer[j] = patterns[i];
  238. rdma_write(NE2K_RAM_BEGIN, buffer);
  239. rdma_read(NE2K_RAM_BEGIN, buffer);
  240. for (size_t j = 0; j < buffer.size(); ++j) {
  241. if (buffer[j] != patterns[i]) {
  242. if (errors < 16)
  243. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Bad adapter RAM @ {} expected={} got={}", PhysicalAddress(NE2K_RAM_BEGIN + j), patterns[i], buffer[j]);
  244. else if (errors == 16)
  245. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Too many RAM errors, silencing further output");
  246. errors++;
  247. }
  248. }
  249. }
  250. return errors;
  251. }
  252. void NE2000NetworkAdapter::reset()
  253. {
  254. const u8 interrupt_mask = BIT_INTERRUPTMASK_PRX | BIT_INTERRUPTMASK_PTX | BIT_INTERRUPTMASK_RXE | BIT_INTERRUPTMASK_TXE | BIT_INTERRUPTMASK_OVW | BIT_INTERRUPTMASK_CNT;
  255. u8 prom[32];
  256. // Taken from DP8390D's datasheet section 11.0, "Initialization Procedures"
  257. out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_STOP);
  258. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  259. out8(REG_WR_DATACONFIGURATION, BIT_DATACONFIGURATION_FIFO_8B | BIT_DATACONFIGURATION_WTS);
  260. #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  261. out8(REG_WR_DATACONFIGURATION, BIT_DATACONFIGURATION_FIFO_8B | BIT_DATACONFIGURATION_BOS | BIT_DATACONFIGURATION_WTS);
  262. #else
  263. # error Unknown byte order
  264. #endif
  265. out8(REG_WR_REMOTEBYTECOUNT0, 0x00);
  266. out8(REG_WR_REMOTEBYTECOUNT1, 0x00);
  267. out8(REG_WR_RECEIVECONFIGURATION, BIT_RECEIVECONFIGURATION_AB | BIT_RECEIVECONFIGURATION_AR);
  268. out8(REG_WR_TRANSMITCONFIGURATION, BIT_WR_TRANSMITCONFIGURATION_LOOPBACK);
  269. m_ring_read_ptr = NE2K_RAM_RECV_BEGIN >> 8;
  270. out8(REG_WR_PAGESTART, NE2K_RAM_RECV_BEGIN >> 8);
  271. out8(REG_RW_BOUNDARY, NE2K_RAM_RECV_BEGIN >> 8);
  272. out8(REG_WR_PAGESTOP, NE2K_RAM_RECV_END >> 8);
  273. out8(REG_RW_INTERRUPTSTATUS, 0xff);
  274. out8(REG_WR_INTERRUPTMASK, interrupt_mask);
  275. rdma_read(0, Bytes(prom, sizeof(prom)));
  276. for (int i = 0; i < 6; i++) {
  277. m_mac_address[i] = prom[i * 2];
  278. }
  279. out8(REG_RW_COMMAND, BIT_COMMAND_PAGE1 | BIT_COMMAND_DMA_ABORT | BIT_COMMAND_STOP);
  280. for (int i = 0; i < 6; i++) {
  281. out8(REG_RW_PHYSICALADDRESS0 + i, m_mac_address[i]);
  282. }
  283. out8(REG_RW_CURRENT, NE2K_RAM_RECV_BEGIN >> 8);
  284. out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_START);
  285. out8(REG_WR_TRANSMITCONFIGURATION, 0xe0);
  286. }
  287. void NE2000NetworkAdapter::rdma_read(size_t address, Bytes payload)
  288. {
  289. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: DMA read @ {} length={}", PhysicalAddress(address), payload.size());
  290. u8 command = in8(REG_RW_COMMAND) & ~(BIT_COMMAND_PAGE_FIELD | BIT_COMMAND_DMA_FIELD);
  291. out8(REG_RW_COMMAND, command | BIT_COMMAND_DMA_ABORT);
  292. out8(REG_RW_INTERRUPTSTATUS, BIT_INTERRUPTMASK_RDC);
  293. out8(REG_WR_REMOTEBYTECOUNT0, payload.size());
  294. out8(REG_WR_REMOTEBYTECOUNT1, payload.size() >> 8);
  295. out8(REG_WR_REMOTESTARTADDRESS0, address);
  296. out8(REG_WR_REMOTESTARTADDRESS1, address >> 8);
  297. command = in8(REG_RW_COMMAND) & ~(BIT_COMMAND_DMA_FIELD);
  298. out8(REG_RW_COMMAND, command | BIT_COMMAND_DMA_READ);
  299. for (size_t i = 0; i < payload.size(); i += 2) {
  300. u16 data = in16(REG_RW_IOPORT);
  301. payload[i] = data;
  302. if (i != payload.size() - 1)
  303. payload[i + 1] = data >> 8;
  304. }
  305. while (!(in8(REG_RW_INTERRUPTSTATUS) & BIT_INTERRUPTMASK_RDC))
  306. ;
  307. }
  308. void NE2000NetworkAdapter::rdma_write(size_t address, ReadonlyBytes payload)
  309. {
  310. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: DMA write @ {} length={}", PhysicalAddress(address), payload.size());
  311. u8 command = in8(REG_RW_COMMAND) & ~(BIT_COMMAND_PAGE_FIELD | BIT_COMMAND_DMA_FIELD);
  312. out8(REG_RW_COMMAND, command | BIT_COMMAND_DMA_ABORT);
  313. out8(REG_RW_INTERRUPTSTATUS, BIT_INTERRUPTMASK_RDC);
  314. out8(REG_WR_REMOTEBYTECOUNT0, payload.size());
  315. out8(REG_WR_REMOTEBYTECOUNT1, payload.size() >> 8);
  316. out8(REG_WR_REMOTESTARTADDRESS0, address);
  317. out8(REG_WR_REMOTESTARTADDRESS1, address >> 8);
  318. command = in8(REG_RW_COMMAND) & ~(BIT_COMMAND_DMA_FIELD);
  319. out8(REG_RW_COMMAND, command | BIT_COMMAND_DMA_WRITE);
  320. for (size_t i = 0; i < payload.size(); i += 2) {
  321. u16 data = payload[i];
  322. if (i != payload.size() - 1)
  323. data |= payload[i + 1] << 8;
  324. out16(REG_RW_IOPORT, data);
  325. }
  326. while (!(in8(REG_RW_INTERRUPTSTATUS) & BIT_INTERRUPTMASK_RDC))
  327. ;
  328. }
  329. void NE2000NetworkAdapter::send_raw(ReadonlyBytes payload)
  330. {
  331. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Sending packet length={}", payload.size());
  332. if (payload.size() > NE2K_RAM_SEND_SIZE) {
  333. dmesgln("NE2000NetworkAdapter: Packet to send was too big; discarding");
  334. return;
  335. }
  336. while (in8(REG_RW_COMMAND) & BIT_COMMAND_TXP)
  337. m_wait_queue.wait_forever("NE2000NetworkAdapter");
  338. disable_irq();
  339. size_t packet_size = payload.size();
  340. if (packet_size < 64)
  341. packet_size = 64;
  342. rdma_write(NE2K_RAM_SEND_BEGIN, payload);
  343. out8(REG_WR_TRANSMITPAGE, NE2K_RAM_SEND_BEGIN >> 8);
  344. out8(REG_WR_TRANSMITBYTECOUNT0, packet_size);
  345. out8(REG_WR_TRANSMITBYTECOUNT1, packet_size >> 8);
  346. out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_TXP | BIT_COMMAND_START);
  347. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Packet submitted for transmission");
  348. enable_irq();
  349. }
  350. void NE2000NetworkAdapter::receive()
  351. {
  352. while (true) {
  353. out8(REG_RW_COMMAND, BIT_COMMAND_PAGE1 | in8(REG_RW_COMMAND));
  354. u8 current = in8(REG_RW_CURRENT);
  355. out8(REG_RW_COMMAND, in8(REG_RW_COMMAND) & ~BIT_COMMAND_PAGE_FIELD);
  356. if (m_ring_read_ptr == current)
  357. break;
  358. size_t header_address = m_ring_read_ptr << 8;
  359. received_packet_header header;
  360. rdma_read(header_address, Bytes(reinterpret_cast<u8*>(&header), sizeof(header)));
  361. bool packet_ok = header.status & BIT_RECEIVESTATUS_PRX;
  362. dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Packet received {} length={}", (packet_ok ? "intact" : "damaged"), header.length);
  363. if (packet_ok) {
  364. auto packet = ByteBuffer::create_uninitialized(sizeof(received_packet_header) + header.length);
  365. int bytes_left = packet.size();
  366. int current_offset = 0;
  367. int ring_offset = header_address;
  368. while (bytes_left > 0) {
  369. int copy_size = min(bytes_left, NE2K_PAGE_SIZE);
  370. rdma_read(ring_offset, packet.span().slice(current_offset, copy_size));
  371. current_offset += copy_size;
  372. ring_offset += copy_size;
  373. bytes_left -= copy_size;
  374. if (ring_offset == NE2K_RAM_RECV_END)
  375. ring_offset = NE2K_RAM_RECV_BEGIN;
  376. }
  377. did_receive(packet.span().slice(sizeof(received_packet_header)));
  378. }
  379. if (header.next_packet_page == NE2K_RAM_RECV_BEGIN)
  380. out8(REG_RW_BOUNDARY, (NE2K_RAM_RECV_END >> 8) - 1);
  381. else
  382. out8(REG_RW_BOUNDARY, header.next_packet_page - 1);
  383. m_ring_read_ptr = header.next_packet_page;
  384. }
  385. }
  386. void NE2000NetworkAdapter::out8(u16 address, u8 data)
  387. {
  388. m_io_base.offset(address).out(data);
  389. }
  390. void NE2000NetworkAdapter::out16(u16 address, u16 data)
  391. {
  392. m_io_base.offset(address).out(data);
  393. }
  394. u8 NE2000NetworkAdapter::in8(u16 address)
  395. {
  396. u8 data = m_io_base.offset(address).in<u8>();
  397. return data;
  398. }
  399. u16 NE2000NetworkAdapter::in16(u16 address)
  400. {
  401. return m_io_base.offset(address).in<u16>();
  402. }
  403. }