diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index 395416d1a7..c10bad3966 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -190,7 +190,20 @@ UNMAP_AFTER_INIT ErrorOr> E1000ENetworkAdapter: u8 irq = pci_device_identifier.interrupt_line().value(); auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier)); auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0)); - auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), irq, move(registers_io_window), move(interface_name)))); + + 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 adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), + irq, move(registers_io_window), + move(rx_buffer_region), + move(tx_buffer_region), + move(rx_descriptors_region), + move(tx_descriptors_region), + move(interface_name)))); + if (!adapter->initialize()) return Error::from_string_literal("E1000ENetworkAdapter: Unable to initialize adapter"); return adapter; @@ -217,8 +230,16 @@ UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize() return true; } -UNMAP_AFTER_INIT E1000ENetworkAdapter::E1000ENetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr interface_name) - : E1000NetworkAdapter(address, irq, move(registers_io_window), move(interface_name)) +UNMAP_AFTER_INIT E1000ENetworkAdapter::E1000ENetworkAdapter(PCI::Address address, u8 irq, + NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, + NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, + NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr interface_name) + : E1000NetworkAdapter(address, irq, move(registers_io_window), + move(rx_buffer_region), + move(tx_buffer_region), + move(rx_descriptors_region), + move(tx_descriptors_region), + move(interface_name)) { } diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.h b/Kernel/Net/Intel/E1000ENetworkAdapter.h index ea62860d1f..69ae52a6d4 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.h +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.h @@ -30,7 +30,10 @@ public: virtual StringView purpose() const override { return class_name(); } private: - E1000ENetworkAdapter(PCI::Address, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr); + E1000ENetworkAdapter(PCI::Address, u8 irq, + NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, + NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, + NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr); virtual StringView class_name() const override { return "E1000ENetworkAdapter"sv; } diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 7b5f4a11da..1810bd727b 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -168,9 +168,20 @@ UNMAP_AFTER_INIT ErrorOr> E1000NetworkAdapter::t u8 irq = pci_device_identifier.interrupt_line().value(); auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier)); auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0)); - auto adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), irq, move(registers_io_window), move(interface_name)))); - adapter->m_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)); - adapter->m_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_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 adapter = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), + irq, move(registers_io_window), + move(rx_buffer_region), + move(tx_buffer_region), + move(rx_descriptors_region), + move(tx_descriptors_region), + move(interface_name)))); + if (!adapter->initialize()) return Error::from_string_literal("E1000NetworkAdapter: Unable to initialize adapter"); return adapter; @@ -215,11 +226,18 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() return true; } -UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr interface_name) +UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq, + NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, + NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, + NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr interface_name) : NetworkAdapter(move(interface_name)) , PCI::Device(address) , 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_buffer_region(move(rx_buffer_region)) + , m_tx_buffer_region(move(tx_buffer_region)) { } @@ -308,10 +326,7 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::read_mac_address() UNMAP_AFTER_INIT void E1000NetworkAdapter::initialize_rx_descriptors() { auto* rx_descriptors = (e1000_tx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); - constexpr auto rx_buffer_size = 8192; constexpr auto rx_buffer_page_count = rx_buffer_size / PAGE_SIZE; - - m_rx_buffer_region = MM.allocate_contiguous_kernel_region(rx_buffer_size * number_of_rx_descriptors, "E1000 RX buffers"sv, Memory::Region::Access::ReadWrite).release_value(); for (size_t i = 0; i < number_of_rx_descriptors; ++i) { auto& descriptor = rx_descriptors[i]; m_rx_buffers[i] = m_rx_buffer_region->vaddr().as_ptr() + rx_buffer_size * i; @@ -331,10 +346,7 @@ 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_size = 8192; constexpr auto tx_buffer_page_count = tx_buffer_size / PAGE_SIZE; - m_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(); for (size_t i = 0; i < number_of_tx_descriptors; ++i) { auto& descriptor = tx_descriptors[i]; diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.h b/Kernel/Net/Intel/E1000NetworkAdapter.h index 4869c40c84..c4fa10cb84 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.h +++ b/Kernel/Net/Intel/E1000NetworkAdapter.h @@ -35,10 +35,17 @@ public: virtual StringView device_name() const override { return "E1000"sv; } protected: + static constexpr size_t rx_buffer_size = 8192; + static constexpr size_t tx_buffer_size = 8192; + void setup_interrupts(); void setup_link(); - E1000NetworkAdapter(PCI::Address, u8 irq, NonnullOwnPtr registers_io_window, NonnullOwnPtr); + E1000NetworkAdapter(PCI::Address, u8 irq, + NonnullOwnPtr registers_io_window, NonnullOwnPtr rx_buffer_region, + NonnullOwnPtr tx_buffer_region, NonnullOwnPtr rx_descriptors_region, + NonnullOwnPtr tx_descriptors_region, NonnullOwnPtr); + virtual bool handle_irq(RegisterState const&) override; virtual StringView class_name() const override { return "E1000NetworkAdapter"sv; } @@ -85,10 +92,10 @@ protected: NonnullOwnPtr m_registers_io_window; - OwnPtr m_rx_descriptors_region; - OwnPtr m_tx_descriptors_region; - OwnPtr m_rx_buffer_region; - OwnPtr m_tx_buffer_region; + NonnullOwnPtr m_rx_descriptors_region; + NonnullOwnPtr m_tx_descriptors_region; + NonnullOwnPtr m_rx_buffer_region; + NonnullOwnPtr m_tx_buffer_region; Array m_rx_buffers; Array m_tx_buffers; bool m_has_eeprom { false };