diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index fc1ff6795c..9ac92a4897 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -239,7 +239,6 @@ set(KERNEL_SOURCES Net/Intel/E1000ENetworkAdapter.cpp Net/Intel/E1000NetworkAdapter.cpp Net/NE2000/NetworkAdapter.cpp - Net/Realtek/RTL8139NetworkAdapter.cpp Net/Realtek/RTL8168NetworkAdapter.cpp Net/IPv4Socket.cpp Net/LocalSocket.cpp diff --git a/Kernel/Debug.h.in b/Kernel/Debug.h.in index a0c94e52d5..62b95a770e 100644 --- a/Kernel/Debug.h.in +++ b/Kernel/Debug.h.in @@ -271,10 +271,6 @@ #cmakedefine01 ROUTING_DEBUG #endif -#ifndef RTL8139_DEBUG -#cmakedefine01 RTL8139_DEBUG -#endif - #ifndef RTL8168_DEBUG #cmakedefine01 RTL8168_DEBUG #endif diff --git a/Kernel/Net/NetworkingManagement.cpp b/Kernel/Net/NetworkingManagement.cpp index 7191e1c182..9e7e424c2a 100644 --- a/Kernel/Net/NetworkingManagement.cpp +++ b/Kernel/Net/NetworkingManagement.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -100,7 +99,6 @@ struct PCINetworkDriverInitializer { static constexpr PCINetworkDriverInitializer s_initializers[] = { { RTL8168NetworkAdapter::probe, RTL8168NetworkAdapter::create }, - { RTL8139NetworkAdapter::probe, RTL8139NetworkAdapter::create }, { NE2000NetworkAdapter::probe, NE2000NetworkAdapter::create }, { E1000NetworkAdapter::probe, E1000NetworkAdapter::create }, { E1000ENetworkAdapter::probe, E1000ENetworkAdapter::create }, diff --git a/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp b/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp deleted file mode 100644 index 362f6a8397..0000000000 --- a/Kernel/Net/Realtek/RTL8139NetworkAdapter.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (c) 2018-2021, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include - -namespace Kernel { - -#define REG_MAC 0x00 -#define REG_MAR0 0x08 -#define REG_MAR4 0x12 -#define REG_TXSTATUS0 0x10 -#define REG_TXADDR0 0x20 -#define REG_RXBUF 0x30 -#define REG_COMMAND 0x37 -#define REG_CAPR 0x38 -#define REG_IMR 0x3C -#define REG_ISR 0x3E -#define REG_TXCFG 0x40 -#define REG_RXCFG 0x44 -#define REG_MPC 0x4C -#define REG_CFG9346 0x50 -#define REG_CONFIG1 0x52 -#define REG_MSR 0x58 -#define REG_BMCR 0x62 -#define REG_ANLPAR 0x68 - -#define TX_STATUS_OWN 0x2000 -#define TX_STATUS_THRESHOLD_MAX 0x3F0000 - -#define COMMAND_RX_EMPTY 0x01 -#define COMMAND_TX_ENABLE 0x04 -#define COMMAND_RX_ENABLE 0x08 -#define COMMAND_RESET 0x10 - -#define INT_RXOK 0x01 -#define INT_RXERR 0x02 -#define INT_TXOK 0x04 -#define INT_TXERR 0x08 -#define INT_RX_BUFFER_OVERFLOW 0x10 -#define INT_LINK_CHANGE 0x20 -#define INT_RX_FIFO_OVERFLOW 0x40 -#define INT_LENGTH_CHANGE 0x2000 -#define INT_SYSTEM_ERROR 0x8000 - -#define CFG9346_NONE 0x00 -#define CFG9346_EEM0 0x40 -#define CFG9346_EEM1 0x80 - -#define TXCFG_TXRR_ZERO 0x00 -#define TXCFG_MAX_DMA_16B 0x000 -#define TXCFG_MAX_DMA_32B 0x100 -#define TXCFG_MAX_DMA_64B 0x200 -#define TXCFG_MAX_DMA_128B 0x300 -#define TXCFG_MAX_DMA_256B 0x400 -#define TXCFG_MAX_DMA_512B 0x500 -#define TXCFG_MAX_DMA_1K 0x600 -#define TXCFG_MAX_DMA_2K 0x700 -#define TXCFG_IFG11 0x3000000 - -#define RXCFG_AAP 0x01 -#define RXCFG_APM 0x02 -#define RXCFG_AM 0x04 -#define RXCFG_AB 0x08 -#define RXCFG_AR 0x10 -#define RXCFG_WRAP_INHIBIT 0x80 -#define RXCFG_MAX_DMA_16B 0x000 -#define RXCFG_MAX_DMA_32B 0x100 -#define RXCFG_MAX_DMA_64B 0x200 -#define RXCFG_MAX_DMA_128B 0x300 -#define RXCFG_MAX_DMA_256B 0x400 -#define RXCFG_MAX_DMA_512B 0x500 -#define RXCFG_MAX_DMA_1K 0x600 -#define RXCFG_MAX_DMA_UNLIMITED 0x0700 -#define RXCFG_RBLN_8K 0x0000 -#define RXCFG_RBLN_16K 0x0800 -#define RXCFG_RBLN_32K 0x1000 -#define RXCFG_RBLN_64K 0x1800 -#define RXCFG_FTH_NONE 0xE000 - -#define MSR_LINKB 0x02 -#define MSR_SPEED_10 0x08 -#define MSR_RX_FLOW_CONTROL_ENABLE 0x40 - -#define BMCR_SPEED 0x2000 -#define BMCR_AUTO_NEGOTIATE 0x1000 -#define BMCR_DUPLEX 0x0100 - -#define ANLPAR_10FD 0x0040 -#define ANLPAR_TXFD 0x0100 - -#define RX_MULTICAST 0x8000 -#define RX_PHYSICAL_MATCH 0x4000 -#define RX_BROADCAST 0x2000 -#define RX_INVALID_SYMBOL_ERROR 0x20 -#define RX_RUNT 0x10 -#define RX_LONG 0x08 -#define RX_CRC_ERROR 0x04 -#define RX_FRAME_ALIGNMENT_ERROR 0x02 -#define RX_OK 0x01 - -#define PACKET_SIZE_MAX 0x600 -#define PACKET_SIZE_MIN 0x16 - -#define RX_BUFFER_SIZE 32768 -#define TX_BUFFER_SIZE PACKET_SIZE_MAX - -UNMAP_AFTER_INIT ErrorOr RTL8139NetworkAdapter::probe(PCI::DeviceIdentifier const& pci_device_identifier) -{ - constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 }; - return pci_device_identifier.hardware_id() == rtl8139_id; -} - -UNMAP_AFTER_INIT ErrorOr> RTL8139NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier) -{ - u8 irq = pci_device_identifier.interrupt_line().value(); - auto rx_buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(RX_BUFFER_SIZE + PACKET_SIZE_MAX)), "RTL8139 RX"sv, Memory::Region::Access::ReadWrite)); - auto packet_buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(PACKET_SIZE_MAX)), "RTL8139 Packet buffer"sv, Memory::Region::Access::ReadWrite)); - auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier)); - auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0)); - return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) RTL8139NetworkAdapter(pci_device_identifier.address(), irq, move(rx_buffer), move(packet_buffer), move(registers_io_window), move(interface_name)))); -} - -UNMAP_AFTER_INIT ErrorOr RTL8139NetworkAdapter::initialize(Badge) -{ - TRY(m_tx_buffers.try_ensure_capacity(RTL8139_TX_BUFFER_COUNT)); - - dmesgln_pci(*this, "Found @ {}", pci_address()); - - enable_bus_mastering(pci_address()); - - dmesgln_pci(*this, "I/O port base: {}", m_registers_io_window); - dmesgln_pci(*this, "Interrupt line: {}", interrupt_number()); - - // we add space to account for overhang from the last packet - the rtl8139 - // can optionally guarantee that packets will be contiguous by - // purposefully overrunning the rx buffer - dbgln("RTL8139: RX buffer: {}", m_rx_buffer->physical_page(0)->paddr()); - - for (int i = 0; i < RTL8139_TX_BUFFER_COUNT; i++) { - auto buffer = TRY(MM.allocate_contiguous_kernel_region(TRY(Memory::page_round_up(TX_BUFFER_SIZE)), "RTL8139 TX"sv, Memory::Region::Access::Write | Memory::Region::Access::Read)); - m_tx_buffers.append(move(buffer)); - dbgln("RTL8139: TX buffer {}: {}", i, m_tx_buffers[i]->physical_page(0)->paddr()); - } - - reset(); - - read_mac_address(); - auto const& mac = mac_address(); - dmesgln_pci(*this, "MAC address: {}", mac.to_string()); - - enable_irq(); - return {}; -} - -UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq, NonnullOwnPtr rx_buffer, NonnullOwnPtr packet_buffer, NonnullOwnPtr registers_io_window, NonnullOwnPtr interface_name) - : NetworkAdapter(move(interface_name)) - , PCI::Device(address) - , IRQHandler(irq) - , m_registers_io_window(move(registers_io_window)) - , m_rx_buffer(move(rx_buffer)) - , m_packet_buffer(move(packet_buffer)) -{ -} - -UNMAP_AFTER_INIT RTL8139NetworkAdapter::~RTL8139NetworkAdapter() = default; - -bool RTL8139NetworkAdapter::handle_irq(RegisterState const&) -{ - bool was_handled = false; - for (;;) { - int status = in16(REG_ISR); - out16(REG_ISR, status); - - m_entropy_source.add_random_event(status); - - dbgln_if(RTL8139_DEBUG, "RTL8139: handle_irq status={:#04x}", status); - - if ((status & (INT_RXOK | INT_RXERR | INT_TXOK | INT_TXERR | INT_RX_BUFFER_OVERFLOW | INT_LINK_CHANGE | INT_RX_FIFO_OVERFLOW | INT_LENGTH_CHANGE | INT_SYSTEM_ERROR)) == 0) - break; - - was_handled = true; - if (status & INT_RXOK) { - dbgln_if(RTL8139_DEBUG, "RTL8139: RX ready"); - receive(); - } - if (status & INT_RXERR) { - dmesgln_pci(*this, "RX error - resetting device"); - reset(); - } - if (status & INT_TXOK) { - dbgln_if(RTL8139_DEBUG, "RTL8139: TX complete"); - } - if (status & INT_TXERR) { - dmesgln_pci(*this, "TX error - resetting device"); - reset(); - } - if (status & INT_RX_BUFFER_OVERFLOW) { - dmesgln_pci(*this, "RX buffer overflow"); - } - if (status & INT_LINK_CHANGE) { - m_link_up = (in8(REG_MSR) & MSR_LINKB) == 0; - dmesgln_pci(*this, "Link status changed up={}", m_link_up); - } - if (status & INT_RX_FIFO_OVERFLOW) { - dmesgln_pci(*this, "RX FIFO overflow"); - } - if (status & INT_LENGTH_CHANGE) { - dmesgln_pci(*this, "Cable length change"); - } - if (status & INT_SYSTEM_ERROR) { - dmesgln_pci(*this, "System error - resetting device"); - reset(); - } - } - return was_handled; -} - -void RTL8139NetworkAdapter::reset() -{ - m_rx_buffer_offset = 0; - m_tx_next_buffer = 0; - - // reset the device to clear out all the buffers and config - out8(REG_COMMAND, COMMAND_RESET); - while ((in8(REG_COMMAND) & COMMAND_RESET) != 0) - ; - - // unlock config registers - out8(REG_CFG9346, CFG9346_EEM0 | CFG9346_EEM1); - // turn on multicast - out32(REG_MAR0, 0xffffffff); - out32(REG_MAR4, 0xffffffff); - // enable rx/tx - out8(REG_COMMAND, COMMAND_RX_ENABLE | COMMAND_TX_ENABLE); - // device might be in sleep mode, this will take it out - out8(REG_CONFIG1, 0); - // set up rx buffer - out32(REG_RXBUF, m_rx_buffer->physical_page(0)->paddr().get()); - // reset missed packet counter - out8(REG_MPC, 0); - // "basic mode control register" options - 100mbit, full duplex, auto - // negotiation - out16(REG_BMCR, BMCR_SPEED | BMCR_AUTO_NEGOTIATE | BMCR_DUPLEX); - // enable flow control - out8(REG_MSR, MSR_RX_FLOW_CONTROL_ENABLE); - // configure rx: accept physical (MAC) match, multicast, and broadcast, - // use the optional contiguous packet feature, the maximum dma transfer - // size, a 32k buffer, and no fifo threshold - out32(REG_RXCFG, RXCFG_APM | RXCFG_AM | RXCFG_AB | RXCFG_WRAP_INHIBIT | RXCFG_MAX_DMA_UNLIMITED | RXCFG_RBLN_32K | RXCFG_FTH_NONE); - // configure tx: default retry count (16), max DMA burst size of 1024 - // bytes, interframe gap time of the only allowable value. the DMA burst - // size is important - silent failures have been observed with 2048 bytes. - out32(REG_TXCFG, TXCFG_TXRR_ZERO | TXCFG_MAX_DMA_1K | TXCFG_IFG11); - // tell the chip where we want it to DMA from for outgoing packets. - for (int i = 0; i < 4; i++) - out32(REG_TXADDR0 + (i * 4), m_tx_buffers[i]->physical_page(0)->paddr().get()); - // re-lock config registers - out8(REG_CFG9346, CFG9346_NONE); - // enable rx/tx again in case they got turned off (apparently some cards - // do this?) - out8(REG_COMMAND, COMMAND_RX_ENABLE | COMMAND_TX_ENABLE); - - // choose irqs, then clear any pending - out16(REG_IMR, INT_RXOK | INT_RXERR | INT_TXOK | INT_TXERR | INT_RX_BUFFER_OVERFLOW | INT_LINK_CHANGE | INT_RX_FIFO_OVERFLOW | INT_LENGTH_CHANGE | INT_SYSTEM_ERROR); - out16(REG_ISR, 0xffff); - - // Set the initial link up status. - m_link_up = (in8(REG_MSR) & MSR_LINKB) == 0; -} - -UNMAP_AFTER_INIT void RTL8139NetworkAdapter::read_mac_address() -{ - MACAddress mac {}; - for (int i = 0; i < 6; i++) - mac[i] = in8(REG_MAC + i); - set_mac_address(mac); -} - -void RTL8139NetworkAdapter::send_raw(ReadonlyBytes payload) -{ - dbgln_if(RTL8139_DEBUG, "RTL8139: send_raw length={}", payload.size()); - - if (payload.size() > PACKET_SIZE_MAX) { - dmesgln_pci(*this, "Packet was too big; discarding"); - return; - } - - int hw_buffer = -1; - for (int i = 0; i < RTL8139_TX_BUFFER_COUNT; i++) { - int potential_buffer = (m_tx_next_buffer + i) % 4; - - auto status = in32(REG_TXSTATUS0 + (potential_buffer * 4)); - if (status & TX_STATUS_OWN) { - hw_buffer = potential_buffer; - break; - } - } - - if (hw_buffer == -1) { - dmesgln_pci(*this, "Hardware buffers full; discarding packet"); - return; - } - - dbgln_if(RTL8139_DEBUG, "RTL8139: Chose buffer {}", hw_buffer); - m_tx_next_buffer = (hw_buffer + 1) % 4; - - memcpy(m_tx_buffers[hw_buffer]->vaddr().as_ptr(), payload.data(), payload.size()); - memset(m_tx_buffers[hw_buffer]->vaddr().as_ptr() + payload.size(), 0, TX_BUFFER_SIZE - payload.size()); - - // the rtl8139 will not actually emit packets onto the network if they're - // smaller than 64 bytes. the rtl8139 adds a checksum to the end of each - // packet, and that checksum is four bytes long, so we pad the packet to - // 60 bytes if necessary to make sure the whole thing is large enough. - auto length = payload.size(); - if (length < 60) { - dbgln_if(RTL8139_DEBUG, "RTL8139: adjusting payload size from {} to 60", length); - length = 60; - } - - out32(REG_TXSTATUS0 + (hw_buffer * 4), length); -} - -void RTL8139NetworkAdapter::receive() -{ - auto* start_of_packet = m_rx_buffer->vaddr().as_ptr() + m_rx_buffer_offset; - - u16 status = *(u16 const*)(start_of_packet + 0); - u16 length = *(u16 const*)(start_of_packet + 2); - - dbgln_if(RTL8139_DEBUG, "RTL8139: receive, status={:#04x}, length={}, offset={}", status, length, m_rx_buffer_offset); - - if (!(status & RX_OK) || (status & (RX_INVALID_SYMBOL_ERROR | RX_CRC_ERROR | RX_FRAME_ALIGNMENT_ERROR)) || (length >= PACKET_SIZE_MAX) || (length < PACKET_SIZE_MIN)) { - dmesgln_pci(*this, "receive got bad packet, status={:#04x}, length={}", status, length); - reset(); - return; - } - - // we never have to worry about the packet wrapping around the buffer, - // since we set RXCFG_WRAP_INHIBIT, which allows the rtl8139 to write data - // past the end of the allotted space. - memcpy(m_packet_buffer->vaddr().as_ptr(), (u8 const*)(start_of_packet + 4), length - 4); - // let the card know that we've read this data - m_rx_buffer_offset = ((m_rx_buffer_offset + length + 4 + 3) & ~3) % RX_BUFFER_SIZE; - out16(REG_CAPR, m_rx_buffer_offset - 0x10); - m_rx_buffer_offset %= RX_BUFFER_SIZE; - - did_receive({ m_packet_buffer->vaddr().as_ptr(), (size_t)(length - 4) }); -} - -void RTL8139NetworkAdapter::out8(u16 address, u8 data) -{ - m_registers_io_window->write8(address, data); -} - -void RTL8139NetworkAdapter::out16(u16 address, u16 data) -{ - m_registers_io_window->write16(address, data); -} - -void RTL8139NetworkAdapter::out32(u16 address, u32 data) -{ - m_registers_io_window->write32(address, data); -} - -u8 RTL8139NetworkAdapter::in8(u16 address) -{ - return m_registers_io_window->read8(address); -} - -u16 RTL8139NetworkAdapter::in16(u16 address) -{ - return m_registers_io_window->read16(address); -} - -u32 RTL8139NetworkAdapter::in32(u16 address) -{ - return m_registers_io_window->read32(address); -} - -bool RTL8139NetworkAdapter::link_full_duplex() -{ - // Note: this code assumes auto-negotiation is enabled (which is now always the case) and - // bases the duplex state on the link partner advertisement. - // If non-auto-negotiation is ever implemented this should be changed. - u16 anlpar = in16(REG_ANLPAR); - return !!(anlpar & (ANLPAR_TXFD | ANLPAR_10FD)); -} - -i32 RTL8139NetworkAdapter::link_speed() -{ - if (!link_up()) - return NetworkAdapter::LINKSPEED_INVALID; - - u16 msr = in16(REG_MSR); - return msr & MSR_SPEED_10 ? 10 : 100; -} - -} diff --git a/Kernel/Net/Realtek/RTL8139NetworkAdapter.h b/Kernel/Net/Realtek/RTL8139NetworkAdapter.h deleted file mode 100644 index c1a9ec746d..0000000000 --- a/Kernel/Net/Realtek/RTL8139NetworkAdapter.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace Kernel { - -#define RTL8139_TX_BUFFER_COUNT 4 - -class RTL8139NetworkAdapter final : public NetworkAdapter - , public PCI::Device - , public IRQHandler { -public: - static ErrorOr probe(PCI::DeviceIdentifier const&); - static ErrorOr> create(PCI::DeviceIdentifier const&); - virtual ErrorOr initialize(Badge) override; - - virtual ~RTL8139NetworkAdapter() override; - - virtual void send_raw(ReadonlyBytes) override; - virtual bool link_up() override { return m_link_up; } - virtual i32 link_speed() override; - virtual bool link_full_duplex() override; - - virtual StringView purpose() const override { return class_name(); } - virtual StringView device_name() const override { return "RTL8139"sv; } - -private: - RTL8139NetworkAdapter(PCI::Address, u8 irq, NonnullOwnPtr rx_buffer, NonnullOwnPtr packet_buffer, NonnullOwnPtr registers_io_window, NonnullOwnPtr); - virtual bool handle_irq(RegisterState const&) override; - virtual StringView class_name() const override { return "RTL8139NetworkAdapter"sv; } - - void reset(); - void read_mac_address(); - - void receive(); - - void out8(u16 address, u8 data); - void out16(u16 address, u16 data); - void out32(u16 address, u32 data); - u8 in8(u16 address); - u16 in16(u16 address); - u32 in32(u16 address); - - NonnullOwnPtr m_registers_io_window; - u8 m_interrupt_line { 0 }; - NonnullOwnPtr m_rx_buffer; - u16 m_rx_buffer_offset { 0 }; - Vector> m_tx_buffers; - u8 m_tx_next_buffer { 0 }; - NonnullOwnPtr m_packet_buffer; - bool m_link_up { false }; - EntropySource m_entropy_source; -}; -} diff --git a/Meta/CMake/all_the_debug_macros.cmake b/Meta/CMake/all_the_debug_macros.cmake index 577f40ca46..21716bb034 100644 --- a/Meta/CMake/all_the_debug_macros.cmake +++ b/Meta/CMake/all_the_debug_macros.cmake @@ -158,7 +158,6 @@ set(RESIZE_DEBUG ON) set(RESOURCE_DEBUG ON) set(ROUTING_DEBUG ON) set(RSA_PARSE_DEBUG ON) -set(RTL8139_DEBUG ON) set(RTL8168_DEBUG ON) set(SAFE_SYSCALL_DEBUG ON) set(SB16_DEBUG ON)