diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp index 85ea7d7a4022d7..a057c5d10ebe99 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp @@ -261,8 +261,8 @@ UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(StringView interfa , PCI::Device(device_identifier) , IRQHandler(irq) , m_registers_io_window(move(registers_io_window)) - , m_rx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(TXDescriptor) * (number_of_rx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value()) - , m_tx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(RXDescriptor) * (number_of_tx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value()) + , m_rx_descriptors(Memory::allocate_contiguous_typed_array_kernel_region(number_of_rx_descriptors + 1, "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value_but_fixme_should_propagate_errors()) + , m_tx_descriptors(Memory::allocate_contiguous_typed_array_kernel_region(number_of_tx_descriptors + 1, "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value_but_fixme_should_propagate_errors()) { dmesgln_pci(*this, "Found @ {}", device_identifier.address()); dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window); @@ -923,10 +923,10 @@ void RTL8168NetworkAdapter::start_hardware() out16(REG_INT_MOD, 0x5151); // point to tx descriptors - out64(REG_TXADDR, m_tx_descriptors_region->physical_page(0)->paddr().get()); + out64(REG_TXADDR, m_tx_descriptors.paddr.get()); // point to rx descriptors - out64(REG_RXADDR, m_rx_descriptors_region->physical_page(0)->paddr().get()); + out64(REG_RXADDR, m_rx_descriptors.paddr.get()); // configure tx: use the maximum dma transfer size, default interframe gap time. out32(REG_TXCFG, TXCFG_IFG011 | TXCFG_MAX_DMA_UNLIMITED); @@ -1252,9 +1252,8 @@ void RTL8168NetworkAdapter::set_phy_speed() UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_rx_descriptors() { - auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr(); for (size_t i = 0; i < number_of_rx_descriptors; ++i) { - auto& descriptor = rx_descriptors[i]; + auto& descriptor = m_rx_descriptors[i]; auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(RX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX buffer"sv, Memory::Region::Access::ReadWrite).release_value(); memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes m_rx_buffers_regions.append(move(region)); @@ -1265,14 +1264,13 @@ UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_rx_descriptors() descriptor.buffer_address_low = physical_address & 0xFFFFFFFF; descriptor.buffer_address_high = (u64)physical_address >> 32; // cast to prevent shift count >= with of type warnings in 32 bit systems } - rx_descriptors[number_of_rx_descriptors - 1].flags = rx_descriptors[number_of_rx_descriptors - 1].flags | RXDescriptor::EndOfRing; + m_rx_descriptors[number_of_rx_descriptors - 1].flags = m_rx_descriptors[number_of_rx_descriptors - 1].flags | RXDescriptor::EndOfRing; } UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_tx_descriptors() { - auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr(); for (size_t i = 0; i < number_of_tx_descriptors; ++i) { - auto& descriptor = tx_descriptors[i]; + auto& descriptor = m_tx_descriptors[i]; auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(TX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX buffer"sv, Memory::Region::Access::ReadWrite).release_value(); memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes m_tx_buffers_regions.append(move(region)); @@ -1282,7 +1280,7 @@ UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_tx_descriptors() descriptor.buffer_address_low = physical_address & 0xFFFFFFFF; descriptor.buffer_address_high = (u64)physical_address >> 32; } - tx_descriptors[number_of_tx_descriptors - 1].flags = tx_descriptors[number_of_tx_descriptors - 1].flags | TXDescriptor::EndOfRing; + m_tx_descriptors[number_of_tx_descriptors - 1].flags = m_tx_descriptors[number_of_tx_descriptors - 1].flags | TXDescriptor::EndOfRing; } UNMAP_AFTER_INIT RTL8168NetworkAdapter::~RTL8168NetworkAdapter() = default; @@ -1366,13 +1364,12 @@ void RTL8168NetworkAdapter::send_raw(ReadonlyBytes payload) return; } - auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr(); - auto& free_descriptor = tx_descriptors[m_tx_free_index]; + auto& free_descriptor = m_tx_descriptors[m_tx_free_index]; if ((free_descriptor.flags & TXDescriptor::Ownership) != 0) { dbgln_if(RTL8168_DEBUG, "RTL8168: No free TX buffers, sleeping until one is available"); m_wait_queue.wait_forever("RTL8168NetworkAdapter"sv); - return send_raw(payload); + [[clang::musttail]] return send_raw(payload); // if we woke up a TX descriptor is guaranteed to be available, so this should never recurse more than once // but this can probably be done more cleanly } @@ -1390,10 +1387,9 @@ void RTL8168NetworkAdapter::send_raw(ReadonlyBytes payload) void RTL8168NetworkAdapter::receive() { - auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr(); for (u16 i = 0; i < number_of_rx_descriptors; ++i) { auto descriptor_index = (m_rx_free_index + i) % number_of_rx_descriptors; - auto& descriptor = rx_descriptors[descriptor_index]; + auto& descriptor = m_rx_descriptors[descriptor_index]; if ((descriptor.flags & RXDescriptor::Ownership) != 0) { m_rx_free_index = descriptor_index; diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.h b/Kernel/Net/Realtek/RTL8168NetworkAdapter.h index dc0bdef7a0bfa4..8f080f2db58e49 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.h +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.h @@ -49,13 +49,13 @@ class RTL8168NetworkAdapter final : public NetworkAdapter bool determine_supported_version() const; - struct [[gnu::packed]] TXDescriptor { - u16 volatile frame_length; // top 2 bits are reserved - u16 volatile flags; - u16 volatile vlan_tag; - u16 volatile vlan_flags; - u32 volatile buffer_address_low; - u32 volatile buffer_address_high; + struct TXDescriptor { + u16 frame_length; // top 2 bits are reserved + u16 flags; + u16 vlan_tag; + u16 vlan_flags; + u32 buffer_address_low; + u32 buffer_address_high; // flags bit field static constexpr u16 Ownership = 0x8000u; @@ -67,13 +67,13 @@ class RTL8168NetworkAdapter final : public NetworkAdapter static_assert(AssertSize()); - struct [[gnu::packed]] RXDescriptor { - u16 volatile buffer_size; // top 2 bits are reserved - u16 volatile flags; - u16 volatile vlan_tag; - u16 volatile vlan_flags; - u32 volatile buffer_address_low; - u32 volatile buffer_address_high; + struct RXDescriptor { + u16 buffer_size; // top 2 bits are reserved + u16 flags; + u16 vlan_tag; + u16 vlan_flags; + u32 buffer_address_low; + u32 buffer_address_high; // flags bit field static constexpr u16 Ownership = 0x8000u; @@ -211,10 +211,10 @@ class RTL8168NetworkAdapter final : public NetworkAdapter bool m_version_uncertain { true }; NonnullOwnPtr m_registers_io_window; u32 m_ocp_base_address { 0 }; - OwnPtr m_rx_descriptors_region; + Memory::TypedMapping m_rx_descriptors; Vector> m_rx_buffers_regions; u16 m_rx_free_index { 0 }; - OwnPtr m_tx_descriptors_region; + Memory::TypedMapping m_tx_descriptors; Vector> m_tx_buffers_regions; u16 m_tx_free_index { 0 }; bool m_link_up { false };