|
@@ -140,7 +140,10 @@ void RTL8139NetworkAdapter::detect(const PCI::Address& address)
|
|
|
RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq)
|
|
|
: PCI::Device(address, irq)
|
|
|
, m_io_base(PCI::get_BAR0(pci_address()) & ~1)
|
|
|
+ , m_rx_buffer(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(RX_BUFFER_SIZE + PACKET_SIZE_MAX), "RTL8139 RX", Region::Access::Read | Region::Access::Write))
|
|
|
+ , m_packet_buffer(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(PACKET_SIZE_MAX), "RTL8139 Packet buffer", Region::Access::Read | Region::Access::Write))
|
|
|
{
|
|
|
+ m_tx_buffers.ensure_capacity(RTL8139_TX_BUFFER_COUNT);
|
|
|
set_interface_name("rtl8139");
|
|
|
|
|
|
klog() << "RTL8139: Found at PCI address " << String::format("%w", pci_address().seg()) << ":" << String::format("%b", pci_address().bus()) << ":" << String::format("%b", pci_address().slot()) << "." << String::format("%b", pci_address().function());
|
|
@@ -154,17 +157,13 @@ RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq)
|
|
|
// we add space to account for overhang from the last packet - the rtl8139
|
|
|
// can optionally guarantee that packets will be contiguous by
|
|
|
// purposefully overrunning the rx buffer
|
|
|
- m_rx_buffer_addr = (FlatPtr)virtual_to_low_physical(kmalloc_aligned(RX_BUFFER_SIZE + PACKET_SIZE_MAX, 16));
|
|
|
- klog() << "RTL8139: RX buffer: " << PhysicalAddress(m_rx_buffer_addr);
|
|
|
+ klog() << "RTL8139: RX buffer: " << m_rx_buffer->vmobject().physical_pages()[0]->paddr();
|
|
|
|
|
|
- auto tx_buffer_addr = (FlatPtr)virtual_to_low_physical(kmalloc_aligned(TX_BUFFER_SIZE * 4, 16));
|
|
|
for (int i = 0; i < RTL8139_TX_BUFFER_COUNT; i++) {
|
|
|
- m_tx_buffer_addr[i] = tx_buffer_addr + TX_BUFFER_SIZE * i;
|
|
|
- klog() << "RTL8139: TX buffer " << i << ": " << PhysicalAddress(m_tx_buffer_addr[i]);
|
|
|
+ m_tx_buffers.append(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(TX_BUFFER_SIZE), "RTL8139 TX", Region::Access::Write | Region::Access::Read));
|
|
|
+ klog() << "RTL8139: TX buffer " << i << ": " << m_tx_buffers[i]->vmobject().physical_pages()[0]->paddr();
|
|
|
}
|
|
|
|
|
|
- m_packet_buffer = (FlatPtr)kmalloc(PACKET_SIZE_MAX);
|
|
|
-
|
|
|
reset();
|
|
|
|
|
|
read_mac_address();
|
|
@@ -250,7 +249,7 @@ void RTL8139NetworkAdapter::reset()
|
|
|
// device might be in sleep mode, this will take it out
|
|
|
out8(REG_CONFIG1, 0);
|
|
|
// set up rx buffer
|
|
|
- out32(REG_RXBUF, m_rx_buffer_addr);
|
|
|
+ out32(REG_RXBUF, m_rx_buffer->vmobject().physical_pages()[0]->paddr().get());
|
|
|
// reset missed packet counter
|
|
|
out8(REG_MPC, 0);
|
|
|
// "basic mode control register" options - 100mbit, full duplex, auto
|
|
@@ -268,7 +267,7 @@ void RTL8139NetworkAdapter::reset()
|
|
|
out32(REG_TXCFG, TXCFG_TXRR_ZERO | TXCFG_MAX_DMA_1K | TXCFG_IFG11);
|
|
|
// tell the chip where we want it to DMA from for outgoing packets.
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
- out32(REG_TXADDR0 + (i * 4), m_tx_buffer_addr[i]);
|
|
|
+ out32(REG_TXADDR0 + (i * 4), m_tx_buffers[i]->vmobject().physical_pages()[0]->paddr().get());
|
|
|
// re-lock config registers
|
|
|
out8(REG_CFG9346, CFG9346_NONE);
|
|
|
// enable rx/tx again in case they got turned off (apparently some cards
|
|
@@ -320,8 +319,8 @@ void RTL8139NetworkAdapter::send_raw(const u8* data, size_t length)
|
|
|
m_tx_next_buffer = (hw_buffer + 1) % 4;
|
|
|
}
|
|
|
|
|
|
- memcpy((void*)low_physical_to_virtual(m_tx_buffer_addr[hw_buffer]), data, length);
|
|
|
- memset((void*)(low_physical_to_virtual(m_tx_buffer_addr[hw_buffer]) + length), 0, TX_BUFFER_SIZE - length);
|
|
|
+ memcpy(m_tx_buffers[hw_buffer]->vaddr().as_ptr(), data, length);
|
|
|
+ memset(m_tx_buffers[hw_buffer]->vaddr().as_ptr() + length, 0, TX_BUFFER_SIZE - length);
|
|
|
|
|
|
// the rtl8139 will not actually emit packets onto the network if they're
|
|
|
// smaller than 64 bytes. the rtl8139 adds a checksum to the end of each
|
|
@@ -339,17 +338,17 @@ void RTL8139NetworkAdapter::send_raw(const u8* data, size_t length)
|
|
|
|
|
|
void RTL8139NetworkAdapter::receive()
|
|
|
{
|
|
|
- auto* start_of_packet = (const u8*)(low_physical_to_virtual(m_rx_buffer_addr) + m_rx_buffer_offset);
|
|
|
+ auto* start_of_packet = m_rx_buffer->vaddr().as_ptr() + m_rx_buffer_offset;
|
|
|
|
|
|
u16 status = *(const u16*)(start_of_packet + 0);
|
|
|
u16 length = *(const u16*)(start_of_packet + 2);
|
|
|
|
|
|
#ifdef RTL8139_DEBUG
|
|
|
- klog() << "RTL8139NetworkAdapter::receive status=0x" << String::format("%x",status) << " length=" << length << " offset=" << m_rx_buffer_offset;
|
|
|
+ klog() << "RTL8139NetworkAdapter::receive status=0x" << String::format("%x", status) << " length=" << length << " offset=" << m_rx_buffer_offset;
|
|
|
#endif
|
|
|
|
|
|
if (!(status & RX_OK) || (status & (RX_INVALID_SYMBOL_ERROR | RX_CRC_ERROR | RX_FRAME_ALIGNMENT_ERROR)) || (length >= PACKET_SIZE_MAX) || (length < PACKET_SIZE_MIN)) {
|
|
|
- klog() << "RTL8139NetworkAdapter::receive got bad packet status=0x" << String::format("%x",status) << " length=" << length;
|
|
|
+ klog() << "RTL8139NetworkAdapter::receive got bad packet status=0x" << String::format("%x", status) << " length=" << length;
|
|
|
reset();
|
|
|
return;
|
|
|
}
|
|
@@ -357,13 +356,13 @@ void RTL8139NetworkAdapter::receive()
|
|
|
// we never have to worry about the packet wrapping around the buffer,
|
|
|
// since we set RXCFG_WRAP_INHIBIT, which allows the rtl8139 to write data
|
|
|
// past the end of the alloted space.
|
|
|
- memcpy((u8*)m_packet_buffer, (const u8*)(start_of_packet + 4), length - 4);
|
|
|
+ memcpy(m_packet_buffer->vaddr().as_ptr(), (const u8*)(start_of_packet + 4), length - 4);
|
|
|
// let the card know that we've read this data
|
|
|
m_rx_buffer_offset = ((m_rx_buffer_offset + length + 4 + 3) & ~3) % RX_BUFFER_SIZE;
|
|
|
out16(REG_CAPR, m_rx_buffer_offset - 0x10);
|
|
|
m_rx_buffer_offset %= RX_BUFFER_SIZE;
|
|
|
|
|
|
- did_receive((const u8*)m_packet_buffer, length - 4);
|
|
|
+ did_receive(m_packet_buffer->vaddr().as_ptr(), length - 4);
|
|
|
}
|
|
|
|
|
|
void RTL8139NetworkAdapter::out8(u16 address, u8 data)
|