// 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; }