-
Notifications
You must be signed in to change notification settings - Fork 1
Development #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Development #69
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,30 @@ | ||
#ifndef VOIDFRAME_PCI_H | ||
#define VOIDFRAME_PCI_H | ||
#ifndef PCI_H | ||
#define PCI_H | ||
|
||
#define PCI_CONFIG_ADDRESS 0xCF8 | ||
#define PCI_CONFIG_DATA 0xCFC | ||
#include "stdint.h" // Or your equivalent for standard types | ||
|
||
// A structure to hold information about a discovered PCI device | ||
typedef struct { | ||
uint8_t bus; | ||
uint8_t device; | ||
uint8_t function; | ||
uint16_t vendor_id; | ||
uint16_t device_id; | ||
uint8_t class_code; | ||
uint8_t subclass; | ||
uint8_t prog_if; // Programming Interface | ||
} PciDevice; | ||
|
||
static PciDevice found_device; | ||
static int device_found_flag; | ||
static uint16_t target_vendor_id; | ||
static uint16_t target_device_id; | ||
// Callback function pointer type | ||
typedef void (*PciDeviceCallback)(PciDevice device); | ||
|
||
// Function prototypes | ||
void PciEnumerate(); | ||
int PciFindDevice(uint16_t vendor_id, uint16_t device_id, PciDevice* out_device); | ||
uint32_t PciConfigReadDWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); | ||
|
||
#endif // VOIDFRAME_PCI_H | ||
#endif // PCI_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef PACKET_H | ||
#define PACKET_H | ||
|
||
#include <stdint.h> | ||
|
||
// Endianness conversion - crucial for network packets | ||
// Network byte order is Big Endian, x86 is Little Endian. | ||
static inline uint16_t bswap16(uint16_t v) { | ||
return (uint16_t)((v << 8) | (v >> 8)); | ||
} | ||
#define HTONS(x) bswap16((uint16_t)(x)) | ||
#define NTOHS(x) bswap16((uint16_t)(x)) | ||
|
||
// Ethernet Header (14 bytes) | ||
typedef struct { | ||
uint8_t dest_mac[6]; | ||
uint8_t src_mac[6]; | ||
uint16_t ethertype; | ||
} __attribute__((packed)) EthernetHeader; | ||
|
||
// ARP Packet (28 bytes) | ||
typedef struct { | ||
uint16_t hardware_type; // 1 for Ethernet | ||
uint16_t protocol_type; // 0x0800 for IPv4 | ||
uint8_t hardware_addr_len; // 6 for MAC | ||
uint8_t protocol_addr_len; // 4 for IP | ||
uint16_t opcode; // 1 for request, 2 for reply | ||
uint8_t sender_mac[6]; | ||
uint8_t sender_ip[4]; | ||
uint8_t target_mac[6]; | ||
uint8_t target_ip[4]; | ||
} __attribute__((packed)) ArpPacket; | ||
|
||
// Full ARP-over-Ethernet Packet (42 bytes) | ||
typedef struct { | ||
EthernetHeader eth; | ||
ArpPacket arp; | ||
} __attribute__((packed)) FullArpPacket; | ||
|
||
_Static_assert(sizeof(EthernetHeader) == 14, "EthernetHeader must be 14 bytes"); | ||
_Static_assert(sizeof(ArpPacket) == 28, "ArpPacket must be 28 bytes"); | ||
_Static_assert(sizeof(FullArpPacket) == 42, "FullArpPacket must be 42 bytes"); | ||
|
||
#endif // PACKET_H |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,2 +1,121 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "RTL8139.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Console.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Io.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "KernelHeap.h" // For allocating memory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "MemOps.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "VMem.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Global device object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static Rtl8139Device rtl_device; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void Rtl8139_Init() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Searching for RTL8139 (10EC:8139)...\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (PciFindDevice(0x10EC, 0x8139, &rtl_device.pci_info) != 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("RTL8139 Network Card not found.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Found RTL8139!\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 1: Read BAR0 and get the I/O base address --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const uint32_t bar0 = PciConfigReadDWord(rtl_device.pci_info.bus, rtl_device.pci_info.device, rtl_device.pci_info.function, 0x10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (bar0 & 0x1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// I/O mapped | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.io_base = bar0 & ~0x3; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("RTL8139 BAR0 is memory mapped, not supported.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("I/O Base: 0x"); PrintKernelHex(rtl_device.io_base); PrintKernel("\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 2: Power on and Reset --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outb(rtl_device.io_base + REG_CONFIG_1, 0x00); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outb(rtl_device.io_base + REG_COMMAND, CMD_RESET); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while ((inb(rtl_device.io_base + REG_COMMAND) & CMD_RESET) != 0) { /* wait */ } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("RTL8139 reset complete.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 2.1: Reading MAC address --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Reading MAC Address: "); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (int i = 0; i < 6; i++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.mac_address[i] = inb(rtl_device.io_base + REG_MAC0 + i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernelHex(rtl_device.mac_address[i]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (i < 5) PrintKernel(":"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 3: Allocate Buffers for DMA --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// NOTE: This MUST be physically contiguous memory! For now, we assume KernelMemoryAlloc does this. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// In a real OS, you'd need a proper physical memory manager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.rx_buffer = KernelMemoryAlloc(RX_BUFFER_SIZE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!rtl_device.rx_buffer) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Failed to allocate RX buffer.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (int i = 0; i < TX_BUFFER_COUNT; i++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.tx_buffers[i] = KernelMemoryAlloc(2048); // 2K per TX buffer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!rtl_device.tx_buffers[i]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Failed to allocate TX buffer.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Clean up previously allocated buffers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (int j = 0; j < i; j++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
KernelFree(rtl_device.tx_buffers[j]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
KernelFree(rtl_device.rx_buffer); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.current_tx_buffer = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("DMA buffers allocated.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 4: Tell the card where the receive buffer is --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The hardware needs the PHYSICAL address of the buffer. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint32_t rx_phys_addr = VIRT_TO_PHYS(rtl_device.rx_buffer); // Assuming identity mapping for now | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outl(rtl_device.io_base + REG_RX_BUFFER_START, rx_phys_addr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Receive buffer configured.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- Part 5: Enable the Receiver and Transmitter --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// This is the final step to "turn on" the card. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outb(rtl_device.io_base + REG_COMMAND, CMD_TX_ENABLE | CMD_RX_ENABLE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Transmitter and Receiver enabled.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Configure Rx register: accept broadcast, multicast, and packets for our MAC (AB+AM+APM) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// and wrap packets that are too long. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outl(rtl_device.io_base + REG_RX_CONFIG, (1 << 7) | (1 << 3) | (1 << 2) | (1 << 1)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("RTL8139 initialization finished!\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void Rtl8139_SendPacket(void* data, uint32_t len) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (len > 2048) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Packet too large to send.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Get the I/O and memory addresses for the current transmit descriptor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int tx_index = rtl_device.current_tx_buffer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint32_t tx_addr_reg = REG_TX_ADDR_0 + (tx_index * 4); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint32_t tx_stat_reg = REG_TX_STATUS_0 + (tx_index * 4); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t* tx_buffer = rtl_device.tx_buffers[tx_index]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Copy the packet data to our DMA-safe buffer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FastMemcpy(tx_buffer, data, len); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Tell the card where the data is (physical address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint32_t tx_phys_addr = (uint32_t)tx_buffer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outl(rtl_device.io_base + tx_addr_reg, tx_phys_addr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Tell the card the length of the data and start sending! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outl(rtl_device.io_base + tx_stat_reg, len); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+97
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Check if previous transmission completed before reusing TX buffer. The code doesn't verify if the previous transmission using this buffer has completed. This could lead to corrupting an in-flight packet. Add a check for the TX_HOST_OWNS bit in the status register before using the buffer: // Get the I/O and memory addresses for the current transmit descriptor
int tx_index = rtl_device.current_tx_buffer;
uint32_t tx_addr_reg = REG_TX_ADDR_0 + (tx_index * 4);
uint32_t tx_stat_reg = REG_TX_STATUS_0 + (tx_index * 4);
+
+ // Check if the buffer is available (bit 13 = TX_HOST_OWNS)
+ uint32_t tx_status = inl(rtl_device.io_base + tx_stat_reg);
+ if (!(tx_status & (1 << 13))) {
+ PrintKernel("TX buffer not available, transmission in progress.\n");
+ return;
+ }
+
uint8_t* tx_buffer = rtl_device.tx_buffers[tx_index]; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PrintKernel("Sent packet of "); PrintKernelInt(len); PrintKernel(" bytes.\n"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Move to the next transmit buffer for the next send operation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rtl_device.current_tx_buffer = (tx_index + 1) % TX_BUFFER_COUNT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const Rtl8139Device* GetRtl8139Device() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return &rtl_device; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,60 @@ | ||
#ifndef VOIDFRAME_RTL8139_H | ||
#define VOIDFRAME_RTL8139_H | ||
#ifndef RTL8139_H | ||
#define RTL8139_H | ||
|
||
#define MAC0 0x00 | ||
#define MAR0 0x08 | ||
#define RBSTART 0x30 | ||
#define CMD 0x37 | ||
#define IMR 0x3C | ||
#define ISR 0x3E | ||
#include <stdint.h> | ||
#include "PCI/PCI.h" | ||
|
||
#endif // VOIDFRAME_RTL8139_H | ||
// ============================================================================= | ||
// RTL8139 Register Offsets (from the I/O base address) | ||
// ============================================================================= | ||
#define REG_MAC0 0x00 // MAC Address (6 bytes) | ||
#define REG_MAR0 0x08 // Multicast Address Register (8 bytes) | ||
#define REG_TX_STATUS_0 0x10 // Transmit Status of Descriptor 0 (4 bytes) | ||
#define REG_TX_ADDR_0 0x20 // Transmit Address of Descriptor 0 (4 bytes) | ||
#define REG_RX_BUFFER_START 0x30 // Receive Buffer Start Address (RBSTART) | ||
#define REG_COMMAND 0x37 // Command Register (1 byte) | ||
#define REG_CAPR 0x38 // Current Address of Packet Read (2 bytes) | ||
#define REG_IMR 0x3C // Interrupt Mask Register (2 bytes) | ||
#define REG_ISR 0x3E // Interrupt Service Register (2 bytes) | ||
#define REG_TX_CONFIG 0x40 // Tx Config Register (4 bytes) | ||
#define REG_RX_CONFIG 0x44 // Rx Config Register (4 bytes) | ||
#define REG_CONFIG_1 0x52 // Config Register 1 (1 byte) | ||
|
||
// ============================================================================= | ||
// Command Register (REG_COMMAND) Bits | ||
// ============================================================================= | ||
#define CMD_BUFFER_EMPTY (1 << 0) // Is receive buffer empty? | ||
#define CMD_TX_ENABLE (1 << 2) // Enable Transmitter | ||
#define CMD_RX_ENABLE (1 << 3) // Enable Receiver | ||
#define CMD_RESET (1 << 4) // Software Reset | ||
|
||
// ============================================================================= | ||
// Interrupt Service/Mask Register (ISR/IMR) Bits | ||
// ============================================================================= | ||
#define ISR_RX_OK (1 << 0) // Receive OK | ||
#define ISR_TX_OK (1 << 2) // Transmit OK | ||
#define ISR_RX_ERR (1 << 1) // Receive Error | ||
#define ISR_TX_ERR (1 << 3) // Transmit Error | ||
|
||
// ============================================================================= | ||
// Driver Configuration Constants | ||
// ============================================================================= | ||
#define RX_BUFFER_SIZE (8192 + 16) // 8K + 16-byte header | ||
#define TX_BUFFER_COUNT 4 // Use all 4 hardware transmit buffers | ||
|
||
// Device state structure | ||
typedef struct { | ||
PciDevice pci_info; | ||
uint32_t io_base; | ||
uint8_t mac_address[6]; | ||
uint8_t* rx_buffer; | ||
uint8_t* tx_buffers[TX_BUFFER_COUNT]; | ||
int current_tx_buffer; | ||
} Rtl8139Device; | ||
|
||
// Function Prototypes | ||
void Rtl8139_Init(); | ||
void Rtl8139_SendPacket(void* data, uint32_t len); | ||
const Rtl8139Device* GetRtl8139Device(); | ||
|
||
#endif // RTL8139_H |
Uh oh!
There was an error while loading. Please reload this page.