diff options
-rw-r--r-- | Kernel/Net/Intel/E1000ENetworkAdapter.cpp | 21 | ||||
-rw-r--r-- | Kernel/Net/Intel/E1000ENetworkAdapter.h | 6 | ||||
-rw-r--r-- | Kernel/Net/Intel/E1000NetworkAdapter.cpp | 49 | ||||
-rw-r--r-- | Kernel/Net/Intel/E1000NetworkAdapter.h | 6 | ||||
-rw-r--r-- | Kernel/Net/LoopbackAdapter.h | 2 | ||||
-rw-r--r-- | Kernel/Net/NE2000/NetworkAdapter.cpp | 24 | ||||
-rw-r--r-- | Kernel/Net/NE2000/NetworkAdapter.h | 4 | ||||
-rw-r--r-- | Kernel/Net/NetworkAdapter.h | 2 | ||||
-rw-r--r-- | Kernel/Net/NetworkingManagement.cpp | 36 | ||||
-rw-r--r-- | Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp | 33 | ||||
-rw-r--r-- | Kernel/Net/Realtek/RTL8139NetworkAdapter.h | 4 | ||||
-rw-r--r-- | Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp | 26 | ||||
-rw-r--r-- | Kernel/Net/Realtek/RTL8168NetworkAdapter.h | 4 |
13 files changed, 131 insertions, 86 deletions
diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp index c10bad3966..8c39d0e133 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.cpp @@ -181,12 +181,15 @@ static bool is_valid_device_id(u16 device_id) } } -UNMAP_AFTER_INIT ErrorOr<LockRefPtr<E1000ENetworkAdapter>> E1000ENetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr<bool> E1000ENetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) { if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Intel) - return nullptr; - if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) - return nullptr; + return false; + return is_valid_device_id(pci_device_identifier.hardware_id().device_id); +} + +UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> E1000ENetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) +{ 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)); @@ -196,20 +199,16 @@ UNMAP_AFTER_INIT ErrorOr<LockRefPtr<E1000ENetworkAdapter>> E1000ENetworkAdapter: 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(), + return 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; } -UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize() +UNMAP_AFTER_INIT ErrorOr<void> E1000ENetworkAdapter::initialize(Badge<NetworkingManagement>) { dmesgln("E1000e: Found @ {}", pci_address()); enable_bus_mastering(pci_address()); @@ -227,7 +226,7 @@ UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize() setup_link(); setup_interrupts(); - return true; + return {}; } UNMAP_AFTER_INIT E1000ENetworkAdapter::E1000ENetworkAdapter(PCI::Address address, u8 irq, diff --git a/Kernel/Net/Intel/E1000ENetworkAdapter.h b/Kernel/Net/Intel/E1000ENetworkAdapter.h index 69ae52a6d4..3b90205864 100644 --- a/Kernel/Net/Intel/E1000ENetworkAdapter.h +++ b/Kernel/Net/Intel/E1000ENetworkAdapter.h @@ -21,9 +21,9 @@ namespace Kernel { class E1000ENetworkAdapter final : public E1000NetworkAdapter { public: - static ErrorOr<LockRefPtr<E1000ENetworkAdapter>> try_to_initialize(PCI::DeviceIdentifier const&); - - virtual bool initialize() override; + static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); + static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; virtual ~E1000ENetworkAdapter() override; diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.cpp b/Kernel/Net/Intel/E1000NetworkAdapter.cpp index 1810bd727b..a256db16f8 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.cpp +++ b/Kernel/Net/Intel/E1000NetworkAdapter.cpp @@ -159,12 +159,15 @@ UNMAP_AFTER_INIT static bool is_valid_device_id(u16 device_id) } } -UNMAP_AFTER_INIT ErrorOr<LockRefPtr<E1000NetworkAdapter>> E1000NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr<bool> E1000NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) { if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Intel) - return nullptr; - if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) - return nullptr; + return false; + return is_valid_device_id(pci_device_identifier.hardware_id().device_id); +} + +UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> E1000NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) +{ 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)); @@ -174,34 +177,16 @@ UNMAP_AFTER_INIT ErrorOr<LockRefPtr<E1000NetworkAdapter>> E1000NetworkAdapter::t 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(), + return 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; -} - -UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_link() -{ - u32 flags = in32(REG_CTRL); - out32(REG_CTRL, flags | ECTRL_SLU); -} - -UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_interrupts() -{ - out32(REG_INTERRUPT_RATE, 6000); // Interrupt rate of 1.536 milliseconds - out32(REG_INTERRUPT_MASK_SET, INTERRUPT_LSC | INTERRUPT_RXT0 | INTERRUPT_RXO); - in32(REG_INTERRUPT_CAUSE_READ); - enable_irq(); } -UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() +UNMAP_AFTER_INIT ErrorOr<void> E1000NetworkAdapter::initialize(Badge<NetworkingManagement>) { dmesgln_pci(*this, "Found @ {}", pci_address()); @@ -223,7 +208,21 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() m_link_up = ((in32(REG_STATUS) & STATUS_LU) != 0); - return true; + return {}; +} + +UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_link() +{ + u32 flags = in32(REG_CTRL); + out32(REG_CTRL, flags | ECTRL_SLU); +} + +UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_interrupts() +{ + out32(REG_INTERRUPT_RATE, 6000); // Interrupt rate of 1.536 milliseconds + out32(REG_INTERRUPT_MASK_SET, INTERRUPT_LSC | INTERRUPT_RXT0 | INTERRUPT_RXO); + in32(REG_INTERRUPT_CAUSE_READ); + enable_irq(); } UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq, diff --git a/Kernel/Net/Intel/E1000NetworkAdapter.h b/Kernel/Net/Intel/E1000NetworkAdapter.h index c4fa10cb84..5bc557059d 100644 --- a/Kernel/Net/Intel/E1000NetworkAdapter.h +++ b/Kernel/Net/Intel/E1000NetworkAdapter.h @@ -20,9 +20,9 @@ class E1000NetworkAdapter : public NetworkAdapter , public PCI::Device , public IRQHandler { public: - static ErrorOr<LockRefPtr<E1000NetworkAdapter>> try_to_initialize(PCI::DeviceIdentifier const&); - - virtual bool initialize(); + static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); + static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; virtual ~E1000NetworkAdapter() override; diff --git a/Kernel/Net/LoopbackAdapter.h b/Kernel/Net/LoopbackAdapter.h index 15391b7ede..47365ee099 100644 --- a/Kernel/Net/LoopbackAdapter.h +++ b/Kernel/Net/LoopbackAdapter.h @@ -18,6 +18,8 @@ public: static LockRefPtr<LoopbackAdapter> try_create(); virtual ~LoopbackAdapter() override; + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override { VERIFY_NOT_REACHED(); } + virtual void send_raw(ReadonlyBytes) override; virtual StringView class_name() const override { return "LoopbackAdapter"sv; } virtual bool link_up() override { return true; } diff --git a/Kernel/Net/NE2000/NetworkAdapter.cpp b/Kernel/Net/NE2000/NetworkAdapter.cpp index 3df63f0be9..8d758926a5 100644 --- a/Kernel/Net/NE2000/NetworkAdapter.cpp +++ b/Kernel/Net/NE2000/NetworkAdapter.cpp @@ -138,7 +138,7 @@ struct [[gnu::packed]] received_packet_header { u16 length; }; -UNMAP_AFTER_INIT ErrorOr<LockRefPtr<NE2000NetworkAdapter>> NE2000NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr<bool> NE2000NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) { constexpr auto ne2k_ids = Array { PCI::HardwareID { 0x10EC, 0x8029 }, // RealTek RTL-8029(AS) @@ -155,19 +155,18 @@ UNMAP_AFTER_INIT ErrorOr<LockRefPtr<NE2000NetworkAdapter>> NE2000NetworkAdapter: PCI::HardwareID { 0x12c3, 0x5598 }, // Holtek HT80229 PCI::HardwareID { 0x8c4a, 0x1980 }, // Winbond W89C940 (misprogrammed) }; - if (!ne2k_ids.span().contains_slow(pci_device_identifier.hardware_id())) - return nullptr; + return ne2k_ids.span().contains_slow(pci_device_identifier.hardware_id()); +} + +UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> NE2000NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) +{ 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)); return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) NE2000NetworkAdapter(pci_device_identifier.address(), irq, move(registers_io_window), move(interface_name)))); } -UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<KString> interface_name) - : NetworkAdapter(move(interface_name)) - , PCI::Device(address) - , IRQHandler(irq) - , m_registers_io_window(move(registers_io_window)) +UNMAP_AFTER_INIT ErrorOr<void> NE2000NetworkAdapter::initialize(Badge<NetworkingManagement>) { dmesgln_pci(*this, "Found @ {}", pci_address()); @@ -181,6 +180,15 @@ UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address set_mac_address(m_mac_address); dmesgln_pci(*this, "MAC address: {}", m_mac_address.to_string()); enable_irq(); + return {}; +} + +UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<KString> interface_name) + : NetworkAdapter(move(interface_name)) + , PCI::Device(address) + , IRQHandler(irq) + , m_registers_io_window(move(registers_io_window)) +{ } UNMAP_AFTER_INIT NE2000NetworkAdapter::~NE2000NetworkAdapter() = default; diff --git a/Kernel/Net/NE2000/NetworkAdapter.h b/Kernel/Net/NE2000/NetworkAdapter.h index 33328fa0a2..6b73dcd939 100644 --- a/Kernel/Net/NE2000/NetworkAdapter.h +++ b/Kernel/Net/NE2000/NetworkAdapter.h @@ -20,7 +20,9 @@ class NE2000NetworkAdapter final : public NetworkAdapter , public PCI::Device , public IRQHandler { public: - static ErrorOr<LockRefPtr<NE2000NetworkAdapter>> try_to_initialize(PCI::DeviceIdentifier const&); + static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); + static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; virtual ~NE2000NetworkAdapter() override; diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h index 6e8bdd1782..e3b0424df3 100644 --- a/Kernel/Net/NetworkAdapter.h +++ b/Kernel/Net/NetworkAdapter.h @@ -42,6 +42,7 @@ struct PacketWithTimestamp final : public AtomicRefCounted<PacketWithTimestamp> IntrusiveListNode<PacketWithTimestamp, LockRefPtr<PacketWithTimestamp>> packet_node; }; +class NetworkingManagement; class NetworkAdapter : public AtomicRefCounted<NetworkAdapter> , public LockWeakable<NetworkAdapter> { @@ -51,6 +52,7 @@ public: virtual ~NetworkAdapter(); virtual StringView class_name() const = 0; + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) = 0; StringView name() const { return m_name->view(); } MACAddress mac_address() { return m_mac_address; } diff --git a/Kernel/Net/NetworkingManagement.cpp b/Kernel/Net/NetworkingManagement.cpp index 2da3aef1e9..7191e1c182 100644 --- a/Kernel/Net/NetworkingManagement.cpp +++ b/Kernel/Net/NetworkingManagement.cpp @@ -93,18 +93,34 @@ ErrorOr<NonnullOwnPtr<KString>> NetworkingManagement::generate_interface_name_fr return name; } +struct PCINetworkDriverInitializer { + ErrorOr<bool> (*probe)(PCI::DeviceIdentifier const&) = nullptr; + ErrorOr<NonnullLockRefPtr<NetworkAdapter>> (*create)(PCI::DeviceIdentifier const&) = nullptr; +}; + +static constexpr PCINetworkDriverInitializer s_initializers[] = { + { RTL8168NetworkAdapter::probe, RTL8168NetworkAdapter::create }, + { RTL8139NetworkAdapter::probe, RTL8139NetworkAdapter::create }, + { NE2000NetworkAdapter::probe, NE2000NetworkAdapter::create }, + { E1000NetworkAdapter::probe, E1000NetworkAdapter::create }, + { E1000ENetworkAdapter::probe, E1000ENetworkAdapter::create }, +}; + UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> NetworkingManagement::determine_network_device(PCI::DeviceIdentifier const& device_identifier) const { - if (auto candidate = TRY(E1000NetworkAdapter::try_to_initialize(device_identifier))) - return candidate.release_nonnull(); - if (auto candidate = TRY(E1000ENetworkAdapter::try_to_initialize(device_identifier))) - return candidate.release_nonnull(); - if (auto candidate = TRY(RTL8139NetworkAdapter::try_to_initialize(device_identifier))) - return candidate.release_nonnull(); - if (auto candidate = TRY(RTL8168NetworkAdapter::try_to_initialize(device_identifier))) - return candidate.release_nonnull(); - if (auto candidate = TRY(NE2000NetworkAdapter::try_to_initialize(device_identifier))) - return candidate.release_nonnull(); + for (auto& initializer : s_initializers) { + auto initializer_probe_found_driver_match_or_error = initializer.probe(device_identifier); + if (initializer_probe_found_driver_match_or_error.is_error()) { + dmesgln("Networking: Failed to probe device {}, due to {}", device_identifier.address(), initializer_probe_found_driver_match_or_error.error()); + continue; + } + auto initializer_probe_found_driver_match = initializer_probe_found_driver_match_or_error.release_value(); + if (initializer_probe_found_driver_match) { + auto adapter = TRY(initializer.create(device_identifier)); + TRY(adapter->initialize({})); + return adapter; + } + } return Error::from_string_literal("Unsupported network adapter"); } diff --git a/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp index 54e7a2241a..362f6a8397 100644 --- a/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp +++ b/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp @@ -112,11 +112,14 @@ namespace Kernel { #define RX_BUFFER_SIZE 32768 #define TX_BUFFER_SIZE PACKET_SIZE_MAX -UNMAP_AFTER_INIT ErrorOr<LockRefPtr<RTL8139NetworkAdapter>> RTL8139NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr<bool> RTL8139NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) { constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 }; - if (pci_device_identifier.hardware_id() != rtl8139_id) - return nullptr; + return pci_device_identifier.hardware_id() == rtl8139_id; +} + +UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> RTL8139NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) +{ u8 irq = pci_device_identifier.interrupt_line().value(); auto rx_buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(RX_BUFFER_SIZE + PACKET_SIZE_MAX)), "RTL8139 RX"sv, Memory::Region::Access::ReadWrite)); auto packet_buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(PACKET_SIZE_MAX)), "RTL8139 Packet buffer"sv, Memory::Region::Access::ReadWrite)); @@ -125,15 +128,9 @@ UNMAP_AFTER_INIT ErrorOr<LockRefPtr<RTL8139NetworkAdapter>> RTL8139NetworkAdapte return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RTL8139NetworkAdapter(pci_device_identifier.address(), irq, move(rx_buffer), move(packet_buffer), move(registers_io_window), move(interface_name)))); } -UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr<Memory::Region> rx_buffer, NonnullOwnPtr<Memory::Region> packet_buffer, NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<KString> interface_name) - : NetworkAdapter(move(interface_name)) - , PCI::Device(address) - , IRQHandler(irq) - , m_registers_io_window(move(registers_io_window)) - , m_rx_buffer(move(rx_buffer)) - , m_packet_buffer(move(packet_buffer)) +UNMAP_AFTER_INIT ErrorOr<void> RTL8139NetworkAdapter::initialize(Badge<NetworkingManagement>) { - m_tx_buffers.ensure_capacity(RTL8139_TX_BUFFER_COUNT); + TRY(m_tx_buffers.try_ensure_capacity(RTL8139_TX_BUFFER_COUNT)); dmesgln_pci(*this, "Found @ {}", pci_address()); @@ -148,7 +145,8 @@ UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address addre dbgln("RTL8139: RX buffer: {}", m_rx_buffer->physical_page(0)->paddr()); for (int i = 0; i < RTL8139_TX_BUFFER_COUNT; i++) { - m_tx_buffers.append(MM.allocate_contiguous_kernel_region(Memory::page_round_up(TX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8139 TX"sv, Memory::Region::Access::Write | Memory::Region::Access::Read).release_value()); + auto buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(TX_BUFFER_SIZE)), "RTL8139 TX"sv, Memory::Region::Access::Write | Memory::Region::Access::Read)); + m_tx_buffers.append(move(buffer)); dbgln("RTL8139: TX buffer {}: {}", i, m_tx_buffers[i]->physical_page(0)->paddr()); } @@ -159,6 +157,17 @@ UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address addre dmesgln_pci(*this, "MAC address: {}", mac.to_string()); enable_irq(); + return {}; +} + +UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr<Memory::Region> rx_buffer, NonnullOwnPtr<Memory::Region> packet_buffer, NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<KString> interface_name) + : NetworkAdapter(move(interface_name)) + , PCI::Device(address) + , IRQHandler(irq) + , m_registers_io_window(move(registers_io_window)) + , m_rx_buffer(move(rx_buffer)) + , m_packet_buffer(move(packet_buffer)) +{ } UNMAP_AFTER_INIT RTL8139NetworkAdapter::~RTL8139NetworkAdapter() = default; diff --git a/Kernel/Net/Realtek/RTL8139NetworkAdapter.h b/Kernel/Net/Realtek/RTL8139NetworkAdapter.h index 73cbaa2438..c1a9ec746d 100644 --- a/Kernel/Net/Realtek/RTL8139NetworkAdapter.h +++ b/Kernel/Net/Realtek/RTL8139NetworkAdapter.h @@ -22,7 +22,9 @@ class RTL8139NetworkAdapter final : public NetworkAdapter , public PCI::Device , public IRQHandler { public: - static ErrorOr<LockRefPtr<RTL8139NetworkAdapter>> try_to_initialize(PCI::DeviceIdentifier const&); + static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); + static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; virtual ~RTL8139NetworkAdapter() override; diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp index 5d5f7d8a25..92dc5a97c2 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp @@ -182,12 +182,17 @@ namespace Kernel { #define TX_BUFFER_SIZE 0x1FF8 #define RX_BUFFER_SIZE 0x1FF8 // FIXME: this should be increased (0x3FFF) -UNMAP_AFTER_INIT ErrorOr<LockRefPtr<RTL8168NetworkAdapter>> RTL8168NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) +UNMAP_AFTER_INIT ErrorOr<bool> RTL8168NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) { if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Realtek) - return nullptr; + return false; if (pci_device_identifier.hardware_id().device_id != 0x8168) - return nullptr; + return false; + return true; +} + +UNMAP_AFTER_INIT ErrorOr<NonnullLockRefPtr<NetworkAdapter>> RTL8168NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) +{ 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)); @@ -249,21 +254,17 @@ UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(PCI::Address addre { dmesgln_pci(*this, "Found @ {}", pci_address()); dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window); +} +UNMAP_AFTER_INIT ErrorOr<void> RTL8168NetworkAdapter::initialize(Badge<NetworkingManagement>) +{ identify_chip_version(); dmesgln_pci(*this, "Version detected - {} ({}{})", possible_device_name(), (u8)m_version, m_version_uncertain ? "?" : ""); if (!determine_supported_version()) { dmesgln_pci(*this, "Aborting initialization! Support for your chip version ({}) is not implemented yet, please open a GH issue and include this message.", (u8)m_version); - return; // Each ChipVersion requires a specific implementation of configure_phy and hardware_quirks + return Error::from_errno(ENODEV); // Each ChipVersion requires a specific implementation of configure_phy and hardware_quirks } - - initialize(); - startup(); -} - -void RTL8168NetworkAdapter::initialize() -{ // set initial REG_RXCFG auto rx_config = RXCFG_MAX_DMA_UNLIMITED; if (m_version <= ChipVersion::Version3) { @@ -344,6 +345,9 @@ void RTL8168NetworkAdapter::initialize() // notify TODO(); } + + startup(); + return {}; } void RTL8168NetworkAdapter::startup() diff --git a/Kernel/Net/Realtek/RTL8168NetworkAdapter.h b/Kernel/Net/Realtek/RTL8168NetworkAdapter.h index 3a552306f9..b7dc57f1d4 100644 --- a/Kernel/Net/Realtek/RTL8168NetworkAdapter.h +++ b/Kernel/Net/Realtek/RTL8168NetworkAdapter.h @@ -22,7 +22,9 @@ class RTL8168NetworkAdapter final : public NetworkAdapter , public PCI::Device , public IRQHandler { public: - static ErrorOr<LockRefPtr<RTL8168NetworkAdapter>> try_to_initialize(PCI::DeviceIdentifier const&); + static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); + static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); + virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; virtual ~RTL8168NetworkAdapter() override; |