boredos_mirror/src/net/nic/nic.c
2026-03-16 00:30:47 +01:00

147 lines
4.6 KiB
C

// Copyright (c) 2023-2026 Chris (boreddevnl)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "nic.h"
#include "pci.h"
#include "kutils.h"
extern int e1000_init(pci_device_t* pci_dev);
extern int rtl8139_init(pci_device_t* pci_dev);
extern int virtio_net_init(pci_device_t* pci_dev);
extern int e1000_send_packet(const void* data, size_t length);
extern int e1000_receive_packet(void* buffer, size_t buffer_size);
extern int e1000_get_mac(uint8_t* mac_out);
extern int rtl8139_send_packet(const void* data, size_t length);
extern int rtl8139_receive_packet(void* buffer, size_t buffer_size);
extern int rtl8139_get_mac(uint8_t* mac_out);
extern int virtio_net_send_packet(const void* data, size_t length);
extern int virtio_net_receive_packet(void* buffer, size_t buffer_size);
extern int virtio_net_get_mac(uint8_t* mac_out);
extern int rtl8111_init(pci_device_t* pci_dev);
extern int rtl8111_send_packet(const void* data, size_t length);
extern int rtl8111_receive_packet(void* buffer, size_t buffer_size);
extern int rtl8111_get_mac(uint8_t* mac_out);
static nic_driver_t active_nic_driver = {0};
static int nic_initialized = 0;
static int register_e1000(pci_device_t* dev) {
if (e1000_init(dev) == 0) {
active_nic_driver.name = "e1000";
active_nic_driver.init = e1000_init;
active_nic_driver.send_packet = e1000_send_packet;
active_nic_driver.receive_packet = e1000_receive_packet;
active_nic_driver.get_mac_address = e1000_get_mac;
return 0;
}
return -1;
}
static int register_rtl8139(pci_device_t* dev) {
if (rtl8139_init(dev) == 0) {
active_nic_driver.name = "rtl8139";
active_nic_driver.init = rtl8139_init;
active_nic_driver.send_packet = rtl8139_send_packet;
active_nic_driver.receive_packet = rtl8139_receive_packet;
active_nic_driver.get_mac_address = rtl8139_get_mac;
return 0;
}
return -1;
}
static int register_virtio_net(pci_device_t* dev) {
if (virtio_net_init(dev) == 0) {
active_nic_driver.name = "virtio-net";
active_nic_driver.init = virtio_net_init;
active_nic_driver.send_packet = virtio_net_send_packet;
active_nic_driver.receive_packet = virtio_net_receive_packet;
active_nic_driver.get_mac_address = virtio_net_get_mac;
return 0;
}
return -1;
}
static int register_rtl8111(pci_device_t* dev) {
if (rtl8111_init(dev) == 0) {
active_nic_driver.name = "rtl8111";
active_nic_driver.init = rtl8111_init;
active_nic_driver.send_packet = rtl8111_send_packet;
active_nic_driver.receive_packet = rtl8111_receive_packet;
active_nic_driver.get_mac_address = rtl8111_get_mac;
return 0;
}
return -1;
}
int nic_init(void) {
if (nic_initialized) return 0;
pci_device_t pci_dev;
if (pci_find_device(0x10EC, 0x8168, &pci_dev)) {
if (register_rtl8111(&pci_dev) == 0) {
nic_initialized = 1;
return 0;
}
}
if (pci_find_device(0x10EC, 0x8139, &pci_dev)) {
if (register_rtl8139(&pci_dev) == 0) {
nic_initialized = 1;
return 0;
}
}
if (pci_find_device(0x1AF4, 0x1000, &pci_dev)) {
if (register_virtio_net(&pci_dev) == 0) {
nic_initialized = 1;
return 0;
}
}
if (pci_find_device(0x1AF4, 0x1041, &pci_dev)) {
if (register_virtio_net(&pci_dev) == 0) {
nic_initialized = 1;
return 0;
}
}
if (pci_find_device(0x8086, 0x100E, &pci_dev)) {
if (register_e1000(&pci_dev) == 0) {
nic_initialized = 1;
return 0;
}
}
return -1;
}
nic_driver_t* nic_get_driver(void) {
if (!nic_initialized) return NULL;
return &active_nic_driver;
}
int nic_send_packet(const void* data, size_t length) {
if (!nic_initialized || !active_nic_driver.send_packet) return -1;
return active_nic_driver.send_packet(data, length);
}
int nic_receive_packet(void* buffer, size_t buffer_size) {
if (!nic_initialized || !active_nic_driver.receive_packet) return 0;
return active_nic_driver.receive_packet(buffer, buffer_size);
}
int nic_get_mac_address(uint8_t* mac_out) {
if (!nic_initialized || !active_nic_driver.get_mac_address) return -1;
return active_nic_driver.get_mac_address(mac_out);
}
const char* nic_get_active_name(void) {
if (!nic_initialized || !active_nic_driver.name) return NULL;
return active_nic_driver.name;
}