Serenity Operating System
at master 105 lines 3.5 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/OwnPtr.h> 10#include <Kernel/Bus/PCI/Access.h> 11#include <Kernel/Bus/PCI/Device.h> 12#include <Kernel/IOWindow.h> 13#include <Kernel/Interrupts/IRQHandler.h> 14#include <Kernel/Net/NetworkAdapter.h> 15#include <Kernel/Random.h> 16 17namespace Kernel { 18 19class E1000NetworkAdapter : public NetworkAdapter 20 , public PCI::Device 21 , public IRQHandler { 22public: 23 static ErrorOr<bool> probe(PCI::DeviceIdentifier const&); 24 static ErrorOr<NonnullLockRefPtr<NetworkAdapter>> create(PCI::DeviceIdentifier const&); 25 virtual ErrorOr<void> initialize(Badge<NetworkingManagement>) override; 26 27 virtual ~E1000NetworkAdapter() override; 28 29 virtual void send_raw(ReadonlyBytes) override; 30 virtual bool link_up() override { return m_link_up; }; 31 virtual i32 link_speed() override; 32 virtual bool link_full_duplex() override; 33 34 virtual StringView purpose() const override { return class_name(); } 35 virtual StringView device_name() const override { return "E1000"sv; } 36 virtual Type adapter_type() const override { return Type::Ethernet; } 37 38protected: 39 static constexpr size_t rx_buffer_size = 8192; 40 static constexpr size_t tx_buffer_size = 8192; 41 42 void setup_interrupts(); 43 void setup_link(); 44 45 E1000NetworkAdapter(PCI::DeviceIdentifier const&, u8 irq, 46 NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region, 47 NonnullOwnPtr<Memory::Region> tx_buffer_region, NonnullOwnPtr<Memory::Region> rx_descriptors_region, 48 NonnullOwnPtr<Memory::Region> tx_descriptors_region, NonnullOwnPtr<KString>); 49 50 virtual bool handle_irq(RegisterState const&) override; 51 virtual StringView class_name() const override { return "E1000NetworkAdapter"sv; } 52 53 struct [[gnu::packed]] e1000_rx_desc { 54 volatile uint64_t addr { 0 }; 55 volatile uint16_t length { 0 }; 56 volatile uint16_t checksum { 0 }; 57 volatile uint8_t status { 0 }; 58 volatile uint8_t errors { 0 }; 59 volatile uint16_t special { 0 }; 60 }; 61 62 struct [[gnu::packed]] e1000_tx_desc { 63 volatile uint64_t addr { 0 }; 64 volatile uint16_t length { 0 }; 65 volatile uint8_t cso { 0 }; 66 volatile uint8_t cmd { 0 }; 67 volatile uint8_t status { 0 }; 68 volatile uint8_t css { 0 }; 69 volatile uint16_t special { 0 }; 70 }; 71 72 virtual void detect_eeprom(); 73 virtual u32 read_eeprom(u8 address); 74 void read_mac_address(); 75 76 void initialize_rx_descriptors(); 77 void initialize_tx_descriptors(); 78 79 void out8(u16 address, u8); 80 void out16(u16 address, u16); 81 void out32(u16 address, u32); 82 u8 in8(u16 address); 83 u16 in16(u16 address); 84 u32 in32(u16 address); 85 86 void receive(); 87 88 static constexpr size_t number_of_rx_descriptors = 256; 89 static constexpr size_t number_of_tx_descriptors = 256; 90 91 NonnullOwnPtr<IOWindow> m_registers_io_window; 92 93 NonnullOwnPtr<Memory::Region> m_rx_descriptors_region; 94 NonnullOwnPtr<Memory::Region> m_tx_descriptors_region; 95 NonnullOwnPtr<Memory::Region> m_rx_buffer_region; 96 NonnullOwnPtr<Memory::Region> m_tx_buffer_region; 97 Array<void*, number_of_rx_descriptors> m_rx_buffers; 98 Array<void*, number_of_tx_descriptors> m_tx_buffers; 99 bool m_has_eeprom { false }; 100 bool m_link_up { false }; 101 EntropySource m_entropy_source; 102 103 WaitQueue m_wait_queue; 104}; 105}