From 56e00b6e8b047b5dee69f12912dc9a92ec423018 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Tue, 5 Jul 2016 19:05:42 +0200 Subject: [PATCH] Improve a bit the RTL8139 driver --- kernel/src/rtl8139.cpp | 49 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/kernel/src/rtl8139.cpp b/kernel/src/rtl8139.cpp index 47a8ec18..dbea0dcd 100644 --- a/kernel/src/rtl8139.cpp +++ b/kernel/src/rtl8139.cpp @@ -17,10 +17,12 @@ #define MAC4 0x04 #define RBSTART 0x30 #define CMD 0x37 -#define IMR 0x3C -#define ISR 0x3E -#define RCR 0x44 +#define IMR 0x3C //Interrupt mask register +#define ISR 0x3E //Interrupt status register +#define RCR 0x44 //Receive Config Register #define CONFIG_1 0x52 +#define RX_BUF_PTR 0x38 +#define RX_BUF_ADDR 0x3A #define RCR_AAP (1 << 0) /* Accept All Packets */ #define RCR_APM (1 << 1) /* Accept Physical Match Packets */ @@ -34,6 +36,8 @@ struct rtl8139_t { uint32_t iobase; uint64_t phys_buffer_rx; uint64_t buffer_rx; + + uint64_t cur_rx; //Index inside the buffer }; //TODO Add a way so that the interrupt handler is able to pass a void ptr to the handler @@ -45,8 +49,44 @@ void packet_handler(interrupt::syscall_regs*){ auto& desc = *saved_desc; + //This should be a packet header + uint16_t header = *reinterpret_cast(desc.buffer_rx); + + logging::logf(logging::log_level::TRACE, "rtl8139: Packet Received %u\n", uint64_t(header)); + + // Get the interrupt status + auto status = in_word(desc.iobase + ISR); + // Acknowledge the handling of the packet - out_word(desc.iobase + ISR, 0x1); + out_word(desc.iobase + ISR, status); + +#define RX_OK 0x01 +#define CMD_NOT_EMPTY 0x01 + + if(status & RX_OK){ + logging::logf(logging::log_level::TRACE, "rtl8139: Receive status OK\n"); + + auto cur_rx = desc.cur_rx; + auto buffer_rx = desc.buffer_rx; + + while((in_byte(desc.iobase + CMD) & CMD_NOT_EMPTY) == 0){ + auto packet_header = *reinterpret_cast(buffer_rx + cur_rx); + auto packet_length = *reinterpret_cast(buffer_rx + cur_rx + 2); + auto packet_only_length = packet_length - 4; + + logging::logf(logging::log_level::TRACE, "rtl8139: Handle Packet Received %u\n", uint64_t(packet_header)); + logging::logf(logging::log_level::TRACE, "rtl8139: Handle Packet Received %u\n", uint64_t(packet_length)); + + cur_rx = (cur_rx + packet_length + 4 + 3) & ~3; + out_word(desc.iobase + RX_BUF_PTR, cur_rx - 16); + } + + logging::logf(logging::log_level::TRACE, "rtl8139: Packet Handled\n"); + + desc.cur_rx = cur_rx; + } else { + logging::logf(logging::log_level::TRACE, "rtl8139: Receive status not OK\n"); + } } } //end of anonymous namespace @@ -92,6 +132,7 @@ void rtl8139::init_driver(network::interface_descriptor& interface, pci::device_ desc->phys_buffer_rx = buffer_rx_phys; desc->buffer_rx = buffer_rx_virt; + desc->cur_rx = 0; // 6. Register IRQ handler