Improve a bit the RTL8139 driver

This commit is contained in:
Baptiste Wicht 2016-07-05 19:05:42 +02:00
parent 1750f4569f
commit 56e00b6e8b

View File

@ -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<uint16_t*>(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<uint16_t*>(buffer_rx + cur_rx);
auto packet_length = *reinterpret_cast<uint16_t*>(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