Skip to content

Commit

Permalink
Kernel: Use TypedMapping<T volatie[]> in the E1000[E]NetworkAdapters
Browse files Browse the repository at this point in the history
  • Loading branch information
Hendiadyoin1 committed Nov 16, 2024
1 parent ee9696f commit b411b7e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 53 deletions.
12 changes: 6 additions & 6 deletions Kernel/Net/Intel/E1000ENetworkAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NetworkAdapter>> 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_contiguous_typed_array_kernel_region<RxDescriptor volatile>(number_of_rx_descriptors, "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite));
auto tx_descriptors_region = TRY(Memory::allocate_contiguous_typed_array_kernel_region<TxDescriptor volatile>(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,
Expand Down Expand Up @@ -238,13 +238,13 @@ UNMAP_AFTER_INIT ErrorOr<void> E1000ENetworkAdapter::initialize(Badge<Networking
UNMAP_AFTER_INIT E1000ENetworkAdapter::E1000ENetworkAdapter(StringView interface_name,
PCI::DeviceIdentifier const& device_identifier, u8 irq,
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
NonnullOwnPtr<Memory::Region> tx_buffer_region, NonnullOwnPtr<Memory::Region> rx_descriptors_region,
NonnullOwnPtr<Memory::Region> tx_descriptors_region)
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
Memory::TypedMapping<TxDescriptor volatile[]> 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))
{
}

Expand Down
4 changes: 2 additions & 2 deletions Kernel/Net/Intel/E1000ENetworkAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class E1000ENetworkAdapter final
private:
E1000ENetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const&, u8 irq,
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
NonnullOwnPtr<Memory::Region> tx_buffer_region, NonnullOwnPtr<Memory::Region> rx_descriptors_region,
NonnullOwnPtr<Memory::Region> tx_descriptors_region);
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
Memory::TypedMapping<TxDescriptor volatile[]> tx_descriptors);

virtual StringView class_name() const override { return "E1000ENetworkAdapter"sv; }

Expand Down
40 changes: 18 additions & 22 deletions Kernel/Net/Intel/E1000NetworkAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,16 @@ UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NetworkAdapter>> 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_contiguous_typed_array_kernel_region<RxDescriptor volatile>(number_of_rx_descriptors, "E1000 RX Descriptors"sv, Memory::Region::Access::ReadWrite));
auto tx_descriptors = TRY(Memory::allocate_contiguous_typed_array_kernel_region<TxDescriptor volatile>(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<void> E1000NetworkAdapter::initialize(Badge<NetworkingManagement>)
Expand Down Expand Up @@ -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<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
NonnullOwnPtr<Memory::Region> tx_buffer_region, NonnullOwnPtr<Memory::Region> rx_descriptors_region,
NonnullOwnPtr<Memory::Region> tx_descriptors_region)
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
Memory::TypedMapping<TxDescriptor volatile[]> 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))
{
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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());
Expand All @@ -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);
}
}
Expand Down
50 changes: 27 additions & 23 deletions Kernel/Net/Intel/E1000NetworkAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,36 +40,39 @@ class E1000NetworkAdapter : public NetworkAdapter
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<RxDescriptor, 16>());

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<TxDescriptor, 16>());

void setup_interrupts();
void setup_link();

E1000NetworkAdapter(StringView, PCI::DeviceIdentifier const&, u8 irq,
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
NonnullOwnPtr<Memory::Region> tx_buffer_region, NonnullOwnPtr<Memory::Region> rx_descriptors_region,
NonnullOwnPtr<Memory::Region> tx_descriptors_region);
NonnullOwnPtr<Memory::Region> tx_buffer_region,
Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
Memory::TypedMapping<TxDescriptor volatile[]> 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();
Expand All @@ -91,8 +94,9 @@ class E1000NetworkAdapter : public NetworkAdapter

NonnullOwnPtr<IOWindow> m_registers_io_window;

NonnullOwnPtr<Memory::Region> m_rx_descriptors_region;
NonnullOwnPtr<Memory::Region> m_tx_descriptors_region;
Memory::TypedMapping<RxDescriptor volatile[]> m_rx_descriptors;
Memory::TypedMapping<TxDescriptor volatile[]> m_tx_descriptors;

NonnullOwnPtr<Memory::Region> m_rx_buffer_region;
NonnullOwnPtr<Memory::Region> m_tx_buffer_region;
Array<void*, number_of_rx_descriptors> m_rx_buffers;
Expand Down

0 comments on commit b411b7e

Please sign in to comment.