summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Net/Intel/E1000ENetworkAdapter.cpp21
-rw-r--r--Kernel/Net/Intel/E1000ENetworkAdapter.h6
-rw-r--r--Kernel/Net/Intel/E1000NetworkAdapter.cpp49
-rw-r--r--Kernel/Net/Intel/E1000NetworkAdapter.h6
-rw-r--r--Kernel/Net/LoopbackAdapter.h2
-rw-r--r--Kernel/Net/NE2000/NetworkAdapter.cpp24
-rw-r--r--Kernel/Net/NE2000/NetworkAdapter.h4
-rw-r--r--Kernel/Net/NetworkAdapter.h2
-rw-r--r--Kernel/Net/NetworkingManagement.cpp36
-rw-r--r--Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp33
-rw-r--r--Kernel/Net/Realtek/RTL8139NetworkAdapter.h4
-rw-r--r--Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp26
-rw-r--r--Kernel/Net/Realtek/RTL8168NetworkAdapter.h4
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;