Serenity Operating System
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}