Files
banan-os/kernel/include/kernel/Networking/RTL8169/RTL8169.h

86 lines
2.2 KiB
C++

#pragma once
#include <BAN/UniqPtr.h>
#include <kernel/Interruptable.h>
#include <kernel/Memory/DMARegion.h>
#include <kernel/Networking/NetworkInterface.h>
#include <kernel/PCI.h>
namespace Kernel
{
class RTL8169 final : public NetworkInterface, public Interruptable
{
public:
static bool probe(PCI::Device&);
static BAN::ErrorOr<BAN::RefPtr<RTL8169>> create(PCI::Device&);
virtual BAN::MACAddress get_mac_address() const override { return m_mac_address; }
virtual bool link_up() override { return m_link_up; }
virtual int link_speed() override;
virtual size_t payload_mtu() const override { return 0x1FF8 - sizeof(EthernetHeader); }
virtual void handle_irq() override;
protected:
RTL8169(PCI::Device& pci_device)
: NetworkInterface(Type::Ethernet)
, m_pci_device(pci_device)
{ }
~RTL8169();
BAN::ErrorOr<void> initialize();
virtual BAN::ErrorOr<void> send_raw_bytes(BAN::Span<const BAN::ConstByteSpan> buffers) override;
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
BAN::ErrorOr<void> reset();
BAN::ErrorOr<void> initialize_rx();
BAN::ErrorOr<void> initialize_tx();
void enable_link();
BAN::ErrorOr<void> enable_interrupt();
void receive_thread();
protected:
PCI::Device& m_pci_device;
BAN::UniqPtr<PCI::BarRegion> m_io_bar_region;
private:
static constexpr size_t m_rx_descriptor_count = 256;
static constexpr size_t m_tx_descriptor_count = 256;
BAN::UniqPtr<DMARegion> m_rx_buffer_region;
BAN::UniqPtr<DMARegion> m_tx_buffer_region;
BAN::UniqPtr<DMARegion> m_rx_descriptor_region;
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
BAN::Atomic<bool> m_rx_thread_should_die { false };
BAN::Atomic<bool> m_rx_thread_is_dead { true };
uint32_t m_rx_head { 0 };
SpinLock m_rx_lock;
ThreadBlocker m_rx_blocker;
BAN::Atomic<uint32_t> m_tx_head { 0 };
BAN::Atomic<uint32_t> m_tx_commit { 0 };
SpinLock m_tx_lock;
ThreadBlocker m_tx_blocker;
BAN::MACAddress m_mac_address {};
BAN::Atomic<bool> m_link_up { false };
friend class BAN::RefPtr<RTL8169>;
};
}