diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index 65f4ed519f2..222c8b0d77b 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -201,8 +201,8 @@ UNMAP_AFTER_INIT ErrorOr> E1000ENetworkAdapter::cr auto rx_buffer_region = TRY(MM.allocate_contiguous_kernel_region(rx_buffer_size * number_of_rx_descriptors, "E1000 RX buffers"sv, Memory::Region::Access::ReadWrite)); auto tx_buffer_region = MM.allocate_contiguous_kernel_region(tx_buffer_size * number_of_tx_descriptors, "E1000 TX buffers"sv, Memory::Region::Access::ReadWrite).release_value(); - auto rx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_rx_desc) * number_of_rx_descriptors)), "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); - auto tx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_tx_desc) * number_of_tx_descriptors)), "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); + auto rx_descriptors_region = TRY(Memory::allocate_dma_region_as_typed_array(number_of_rx_descriptors, "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); + auto tx_descriptors_region = TRY(Memory::allocate_dma_region_as_typed_array(number_of_tx_descriptors, "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) E1000ENetworkAdapter(interface_name.representable_view(), pci_device_identifier, @@ -238,13 +238,13 @@ UNMAP_AFTER_INIT ErrorOr E1000ENetworkAdapter::initialize(Badge registers_io_window, NonnullOwnPtr rx_buffer_region, - NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, - NonnullOwnPtr tx_descriptors_region) + NonnullOwnPtr tx_buffer_region, Memory::TypedMapping rx_descriptors, + Memory::TypedMapping tx_descriptors) : E1000NetworkAdapter(interface_name, device_identifier, irq, move(registers_io_window), move(rx_buffer_region), move(tx_buffer_region), - move(rx_descriptors_region), - move(tx_descriptors_region)) + move(rx_descriptors), + move(tx_descriptors)) { } diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.h b/Kernel/Net/Intel/E1000ENetworkAdapter.h index e6598cf6911..59252ef26ac 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.h +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.h @@ -31,8 +31,8 @@ public: private: E1000ENetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, - NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, - NonnullOwnPtr tx_descriptors_region); + NonnullOwnPtr tx_buffer_region, Memory::TypedMapping rx_descriptors, + Memory::TypedMapping tx_descriptors); virtual StringView class_name() const override { return "E1000ENetworkAdapter"sv; } diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 182c66de813..2f685c37f2d 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -174,16 +174,16 @@ UNMAP_AFTER_INIT ErrorOr> E1000NetworkAdapter::cre auto rx_buffer_region = TRY(MM.allocate_contiguous_kernel_region(rx_buffer_size * number_of_rx_descriptors, "E1000 RX buffers"sv, Memory::Region::Access::ReadWrite)); auto tx_buffer_region = MM.allocate_contiguous_kernel_region(tx_buffer_size * number_of_tx_descriptors, "E1000 TX buffers"sv, Memory::Region::Access::ReadWrite).release_value(); - auto rx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_rx_desc) * number_of_rx_descriptors)), "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); - auto tx_descriptors_region = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(sizeof(e1000_tx_desc) * number_of_tx_descriptors)), "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); + auto rx_descriptors = TRY(Memory::allocate_dma_region_as_typed_array(number_of_rx_descriptors, "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite)); + auto tx_descriptors = TRY(Memory::allocate_dma_region_as_typed_array(number_of_tx_descriptors, "E1000 TX Descriptors"sv, Memory::Region::Access::ReadWrite)); return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) E1000NetworkAdapter(interface_name.representable_view(), pci_device_identifier, irq, move(registers_io_window), move(rx_buffer_region), move(tx_buffer_region), - move(rx_descriptors_region), - move(tx_descriptors_region)))); + move(rx_descriptors), + move(tx_descriptors)))); } UNMAP_AFTER_INIT ErrorOr E1000NetworkAdapter::initialize(Badge) @@ -229,14 +229,14 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_interrupts() UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const& device_identifier, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, - NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, - NonnullOwnPtr tx_descriptors_region) + NonnullOwnPtr tx_buffer_region, Memory::TypedMapping rx_descriptors, + Memory::TypedMapping tx_descriptors) : NetworkAdapter(interface_name) , PCI::Device(device_identifier) , IRQHandler(irq) , m_registers_io_window(move(registers_io_window)) - , m_rx_descriptors_region(move(rx_descriptors_region)) - , m_tx_descriptors_region(move(tx_descriptors_region)) + , m_rx_descriptors(move(rx_descriptors)) + , m_tx_descriptors(move(tx_descriptors)) , m_rx_buffer_region(move(rx_buffer_region)) , m_tx_buffer_region(move(tx_buffer_region)) { @@ -326,18 +326,17 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::read_mac_address() UNMAP_AFTER_INIT void E1000NetworkAdapter::initialize_rx_descriptors() { - auto* rx_descriptors = (e1000_rx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); constexpr auto rx_buffer_page_count = rx_buffer_size / PAGE_SIZE; for (size_t i = 0; i < number_of_rx_descriptors; ++i) { - auto& descriptor = rx_descriptors[i]; + auto& descriptor = m_rx_descriptors[i]; m_rx_buffers[i] = m_rx_buffer_region->vaddr().as_ptr() + rx_buffer_size * i; descriptor.addr = m_rx_buffer_region->physical_page(rx_buffer_page_count * i)->paddr().get(); descriptor.status = 0; } - out32(REG_RXDESCLO, m_rx_descriptors_region->physical_page(0)->paddr().get()); + out32(REG_RXDESCLO, m_rx_descriptors.paddr.get()); out32(REG_RXDESCHI, 0); - out32(REG_RXDESCLEN, number_of_rx_descriptors * sizeof(e1000_rx_desc)); + out32(REG_RXDESCLEN, number_of_rx_descriptors * sizeof(RxDescriptor)); out32(REG_RXDESCHEAD, 0); out32(REG_RXDESCTAIL, number_of_rx_descriptors - 1); @@ -346,19 +345,18 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::initialize_rx_descriptors() UNMAP_AFTER_INIT void E1000NetworkAdapter::initialize_tx_descriptors() { - auto* tx_descriptors = (e1000_tx_desc*)m_tx_descriptors_region->vaddr().as_ptr(); constexpr auto tx_buffer_page_count = tx_buffer_size / PAGE_SIZE; for (size_t i = 0; i < number_of_tx_descriptors; ++i) { - auto& descriptor = tx_descriptors[i]; + auto& descriptor = m_tx_descriptors[i]; m_tx_buffers[i] = m_tx_buffer_region->vaddr().as_ptr() + tx_buffer_size * i; descriptor.addr = m_tx_buffer_region->physical_page(tx_buffer_page_count * i)->paddr().get(); descriptor.cmd = 0; } - out32(REG_TXDESCLO, m_tx_descriptors_region->physical_page(0)->paddr().get()); + out32(REG_TXDESCLO, m_tx_descriptors.paddr.get()); out32(REG_TXDESCHI, 0); - out32(REG_TXDESCLEN, number_of_tx_descriptors * sizeof(e1000_tx_desc)); + out32(REG_TXDESCLEN, number_of_tx_descriptors * sizeof(TxDescriptor)); out32(REG_TXDESCHEAD, 0); out32(REG_TXDESCTAIL, 0); @@ -407,8 +405,7 @@ void E1000NetworkAdapter::send_raw(ReadonlyBytes payload) disable_irq(); size_t tx_current = in32(REG_TXDESCTAIL) % number_of_tx_descriptors; dbgln_if(E1000_DEBUG, "E1000: Sending packet ({} bytes)", payload.size()); - auto* tx_descriptors = (e1000_tx_desc*)m_tx_descriptors_region->vaddr().as_ptr(); - auto& descriptor = tx_descriptors[tx_current]; + auto& descriptor = m_tx_descriptors[tx_current]; VERIFY(payload.size() <= 8192); auto* vptr = (void*)m_tx_buffers[tx_current]; memcpy(vptr, payload.data(), payload.size()); @@ -432,19 +429,18 @@ void E1000NetworkAdapter::send_raw(ReadonlyBytes payload) void E1000NetworkAdapter::receive() { - auto* rx_descriptors = (e1000_rx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); u32 rx_current; for (;;) { rx_current = in32(REG_RXDESCTAIL) % number_of_rx_descriptors; rx_current = (rx_current + 1) % number_of_rx_descriptors; - if (!(rx_descriptors[rx_current].status & 1)) + if (!(m_rx_descriptors[rx_current].status & 1)) break; auto* buffer = m_rx_buffers[rx_current]; - u16 length = rx_descriptors[rx_current].length; + u16 length = m_rx_descriptors[rx_current].length; VERIFY(length <= 8192); dbgln_if(E1000_DEBUG, "E1000: Received 1 packet @ {:p} ({} bytes)", buffer, length); did_receive({ buffer, length }); - rx_descriptors[rx_current].status = 0; + m_rx_descriptors[rx_current].status = 0; out32(REG_RXDESCTAIL, rx_current); } } diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.h b/Kernel/Net/Intel/E1000NetworkAdapter.h index ce8e4d4c844..3b3eeff8635 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.h +++ b/Kernel/Net/Intel/E1000NetworkAdapter.h @@ -40,36 +40,39 @@ protected: static constexpr size_t rx_buffer_size = 8192; static constexpr size_t tx_buffer_size = 8192; + struct RxDescriptor { + uint64_t addr { 0 }; + uint16_t length { 0 }; + uint16_t checksum { 0 }; + uint8_t status { 0 }; + uint8_t errors { 0 }; + uint16_t special { 0 }; + }; + static_assert(AssertSize()); + + struct TxDescriptor { + uint64_t addr { 0 }; + uint16_t length { 0 }; + uint8_t cso { 0 }; + uint8_t cmd { 0 }; + uint8_t status { 0 }; + uint8_t css { 0 }; + uint16_t special { 0 }; + }; + static_assert(AssertSize()); + void setup_interrupts(); void setup_link(); E1000NetworkAdapter(StringView, PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, - NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, - NonnullOwnPtr tx_descriptors_region); + NonnullOwnPtr tx_buffer_region, + Memory::TypedMapping rx_descriptors, + Memory::TypedMapping tx_descriptors); virtual bool handle_irq() override; virtual StringView class_name() const override { return "E1000NetworkAdapter"sv; } - struct [[gnu::packed]] e1000_rx_desc { - uint64_t volatile addr { 0 }; - uint16_t volatile length { 0 }; - uint16_t volatile checksum { 0 }; - uint8_t volatile status { 0 }; - uint8_t volatile errors { 0 }; - uint16_t volatile special { 0 }; - }; - - struct [[gnu::packed]] e1000_tx_desc { - uint64_t volatile addr { 0 }; - uint16_t volatile length { 0 }; - uint8_t volatile cso { 0 }; - uint8_t volatile cmd { 0 }; - uint8_t volatile status { 0 }; - uint8_t volatile css { 0 }; - uint16_t volatile special { 0 }; - }; - virtual void detect_eeprom(); virtual u32 read_eeprom(u8 address); void read_mac_address(); @@ -91,8 +94,9 @@ protected: NonnullOwnPtr m_registers_io_window; - NonnullOwnPtr m_rx_descriptors_region; - NonnullOwnPtr m_tx_descriptors_region; + Memory::TypedMapping m_rx_descriptors; + Memory::TypedMapping m_tx_descriptors; + NonnullOwnPtr m_rx_buffer_region; NonnullOwnPtr m_tx_buffer_region; Array m_rx_buffers;