Skip to content

Commit

Permalink
Kernel: Use TypedMapping<T volatile> in the RTL8168NetworkAdapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Hendiadyoin1 committed Nov 16, 2024
1 parent b411b7e commit f62f25c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 31 deletions.
26 changes: 11 additions & 15 deletions Kernel/Net/Realtek/RTL8168NetworkAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(StringView interfa
, PCI::Device(device_identifier)
, IRQHandler(irq)
, m_registers_io_window(move(registers_io_window))
, m_rx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(TXDescriptor) * (number_of_rx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value())
, m_tx_descriptors_region(MM.allocate_contiguous_kernel_region(Memory::page_round_up(sizeof(RXDescriptor) * (number_of_tx_descriptors + 1)).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value())
, m_rx_descriptors(Memory::allocate_contiguous_typed_array_kernel_region<RXDescriptor volatile>(number_of_rx_descriptors + 1, "RTL8168 RX"sv, Memory::Region::Access::ReadWrite).release_value_but_fixme_should_propagate_errors())
, m_tx_descriptors(Memory::allocate_contiguous_typed_array_kernel_region<TXDescriptor volatile>(number_of_tx_descriptors + 1, "RTL8168 TX"sv, Memory::Region::Access::ReadWrite).release_value_but_fixme_should_propagate_errors())
{
dmesgln_pci(*this, "Found @ {}", device_identifier.address());
dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window);
Expand Down Expand Up @@ -923,10 +923,10 @@ void RTL8168NetworkAdapter::start_hardware()
out16(REG_INT_MOD, 0x5151);

// point to tx descriptors
out64(REG_TXADDR, m_tx_descriptors_region->physical_page(0)->paddr().get());
out64(REG_TXADDR, m_tx_descriptors.paddr.get());

// point to rx descriptors
out64(REG_RXADDR, m_rx_descriptors_region->physical_page(0)->paddr().get());
out64(REG_RXADDR, m_rx_descriptors.paddr.get());

// configure tx: use the maximum dma transfer size, default interframe gap time.
out32(REG_TXCFG, TXCFG_IFG011 | TXCFG_MAX_DMA_UNLIMITED);
Expand Down Expand Up @@ -1252,9 +1252,8 @@ void RTL8168NetworkAdapter::set_phy_speed()

UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_rx_descriptors()
{
auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr();
for (size_t i = 0; i < number_of_rx_descriptors; ++i) {
auto& descriptor = rx_descriptors[i];
auto& descriptor = m_rx_descriptors[i];
auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(RX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 RX buffer"sv, Memory::Region::Access::ReadWrite).release_value();
memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes
m_rx_buffers_regions.append(move(region));
Expand All @@ -1265,14 +1264,13 @@ UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_rx_descriptors()
descriptor.buffer_address_low = physical_address & 0xFFFFFFFF;
descriptor.buffer_address_high = (u64)physical_address >> 32; // cast to prevent shift count >= with of type warnings in 32 bit systems
}
rx_descriptors[number_of_rx_descriptors - 1].flags = rx_descriptors[number_of_rx_descriptors - 1].flags | RXDescriptor::EndOfRing;
m_rx_descriptors[number_of_rx_descriptors - 1].flags = m_rx_descriptors[number_of_rx_descriptors - 1].flags | RXDescriptor::EndOfRing;
}

UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_tx_descriptors()
{
auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr();
for (size_t i = 0; i < number_of_tx_descriptors; ++i) {
auto& descriptor = tx_descriptors[i];
auto& descriptor = m_tx_descriptors[i];
auto region = MM.allocate_contiguous_kernel_region(Memory::page_round_up(TX_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(), "RTL8168 TX buffer"sv, Memory::Region::Access::ReadWrite).release_value();
memset(region->vaddr().as_ptr(), 0, region->size()); // MM already zeros out newly allocated pages, but we do it again in case that ever changes
m_tx_buffers_regions.append(move(region));
Expand All @@ -1282,7 +1280,7 @@ UNMAP_AFTER_INIT void RTL8168NetworkAdapter::initialize_tx_descriptors()
descriptor.buffer_address_low = physical_address & 0xFFFFFFFF;
descriptor.buffer_address_high = (u64)physical_address >> 32;
}
tx_descriptors[number_of_tx_descriptors - 1].flags = tx_descriptors[number_of_tx_descriptors - 1].flags | TXDescriptor::EndOfRing;
m_tx_descriptors[number_of_tx_descriptors - 1].flags = m_tx_descriptors[number_of_tx_descriptors - 1].flags | TXDescriptor::EndOfRing;
}

UNMAP_AFTER_INIT RTL8168NetworkAdapter::~RTL8168NetworkAdapter() = default;
Expand Down Expand Up @@ -1366,13 +1364,12 @@ void RTL8168NetworkAdapter::send_raw(ReadonlyBytes payload)
return;
}

auto* tx_descriptors = (TXDescriptor*)m_tx_descriptors_region->vaddr().as_ptr();
auto& free_descriptor = tx_descriptors[m_tx_free_index];
auto& free_descriptor = m_tx_descriptors[m_tx_free_index];

if ((free_descriptor.flags & TXDescriptor::Ownership) != 0) {
dbgln_if(RTL8168_DEBUG, "RTL8168: No free TX buffers, sleeping until one is available");
m_wait_queue.wait_forever("RTL8168NetworkAdapter"sv);
return send_raw(payload);
[[clang::musttail]] return send_raw(payload);
// if we woke up a TX descriptor is guaranteed to be available, so this should never recurse more than once
// but this can probably be done more cleanly
}
Expand All @@ -1390,10 +1387,9 @@ void RTL8168NetworkAdapter::send_raw(ReadonlyBytes payload)

void RTL8168NetworkAdapter::receive()
{
auto* rx_descriptors = (RXDescriptor*)m_rx_descriptors_region->vaddr().as_ptr();
for (u16 i = 0; i < number_of_rx_descriptors; ++i) {
auto descriptor_index = (m_rx_free_index + i) % number_of_rx_descriptors;
auto& descriptor = rx_descriptors[descriptor_index];
auto& descriptor = m_rx_descriptors[descriptor_index];

if ((descriptor.flags & RXDescriptor::Ownership) != 0) {
m_rx_free_index = descriptor_index;
Expand Down
32 changes: 16 additions & 16 deletions Kernel/Net/Realtek/RTL8168NetworkAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ class RTL8168NetworkAdapter final : public NetworkAdapter

bool determine_supported_version() const;

struct [[gnu::packed]] TXDescriptor {
u16 volatile frame_length; // top 2 bits are reserved
u16 volatile flags;
u16 volatile vlan_tag;
u16 volatile vlan_flags;
u32 volatile buffer_address_low;
u32 volatile buffer_address_high;
struct TXDescriptor {
u16 frame_length; // top 2 bits are reserved
u16 flags;
u16 vlan_tag;
u16 vlan_flags;
u32 buffer_address_low;
u32 buffer_address_high;

// flags bit field
static constexpr u16 Ownership = 0x8000u;
Expand All @@ -67,13 +67,13 @@ class RTL8168NetworkAdapter final : public NetworkAdapter

static_assert(AssertSize<TXDescriptor, 16u>());

struct [[gnu::packed]] RXDescriptor {
u16 volatile buffer_size; // top 2 bits are reserved
u16 volatile flags;
u16 volatile vlan_tag;
u16 volatile vlan_flags;
u32 volatile buffer_address_low;
u32 volatile buffer_address_high;
struct RXDescriptor {
u16 buffer_size; // top 2 bits are reserved
u16 flags;
u16 vlan_tag;
u16 vlan_flags;
u32 buffer_address_low;
u32 buffer_address_high;

// flags bit field
static constexpr u16 Ownership = 0x8000u;
Expand Down Expand Up @@ -211,10 +211,10 @@ class RTL8168NetworkAdapter final : public NetworkAdapter
bool m_version_uncertain { true };
NonnullOwnPtr<IOWindow> m_registers_io_window;
u32 m_ocp_base_address { 0 };
OwnPtr<Memory::Region> m_rx_descriptors_region;
Memory::TypedMapping<RXDescriptor volatile[]> m_rx_descriptors;
Vector<NonnullOwnPtr<Memory::Region>> m_rx_buffers_regions;
u16 m_rx_free_index { 0 };
OwnPtr<Memory::Region> m_tx_descriptors_region;
Memory::TypedMapping<TXDescriptor volatile[]> m_tx_descriptors;
Vector<NonnullOwnPtr<Memory::Region>> m_tx_buffers_regions;
u16 m_tx_free_index { 0 };
bool m_link_up { false };
Expand Down

0 comments on commit f62f25c

Please sign in to comment.