9 #include <drv/rtl8139.h>
10 #include <net/cards.h>
13 #include <net/endianess.h>
14 #include <net/ethernet.h>
15 #include <debug/hexview.h>
17 #include "lib/string.h"
20 #include "net/stack.h"
22 uint8_t rtl8139_busnum, rtl8139_slot, rtl8139_func;
23 uint32_t rtl8139_io_base, rtl8139_mem_base, rtl8139_bar_type;
25 size_t rtl8139_phys_buffer = 0;
26 char* rtl8139_virt_buffer = (
char*)0;
29 uint8_t rtl8139_mac[6];
31 uint8_t TSAD_array[4] = {0x20, 0x24, 0x28, 0x2C};
32 uint8_t TSD_array[4] = {0x10, 0x14, 0x18, 0x1C};
34 size_t rtl8139_current_tx_index = 0;
36 void* rtl8139_transfer_buffer;
37 size_t rtl8139_transfer_buffer_phys;
39 void rtl8139_send_packet(
void* data,
size_t length);
40 void rtl8139_receive_packet();
42 bool rtl8139_in_irq =
false;
44 #define NETCARD_NAME ("RTL8139")
46 void rtl8139_netcard_get_mac(uint8_t mac[6]) {
49 memcpy(mac, rtl8139_mac, 6);
55 rtl8139_netcard_get_mac,
60 qemu_log(
"Initializing RTL8139...");
63 &rtl8139_busnum, &rtl8139_slot, &rtl8139_func);
65 uint16_t devnum =
pci_get_device(rtl8139_busnum, rtl8139_slot, rtl8139_func);
67 qemu_log(
"RTL8139 ID: %d (%x)", devnum, devnum);
69 if(devnum == PCI_VENDOR_NO_DEVICE) {
70 qemu_log(
"RTL8139 is not connected!");
73 qemu_log(
"Detected RTL8139");
78 pci_enable_bus_mastering(rtl8139_busnum, rtl8139_slot, rtl8139_func);
80 qemu_log(
"Enabled Bus Mastering for RTL8139!");
85 rtl8139_bar_type = ret & 0x1;
86 rtl8139_io_base = ret & (~0x3);
87 rtl8139_mem_base = ret & (~0xf);
89 qemu_log(
"RTL8139 BAR TYPE: %d; IO BASE: %x; MEMORY BASE: %x", rtl8139_bar_type, rtl8139_io_base, rtl8139_mem_base);
94 rtl8139_virt_buffer = kmalloc_common(RTL8139_BUFFER_PAGE_COUNT, PAGE_SIZE);
95 rtl8139_phys_buffer = virt2phys(get_kernel_page_directory(), (virtual_addr_t) rtl8139_virt_buffer);
97 rtl8139_transfer_buffer = kmalloc_common(65535, PAGE_SIZE);
98 rtl8139_transfer_buffer_phys = virt2phys(get_kernel_page_directory(), (virtual_addr_t)rtl8139_transfer_buffer);
100 rtl8139_init_buffer();
102 qemu_log(
"RTL8139 Physical buffer at: %x", rtl8139_phys_buffer);
105 rtl8139_enable_rx_tx();
107 rtl8139_init_interrupts();
112 netcard_add(&rtl8139_netcard);
115 void rtl8139_read_mac() {
116 uint32_t mac_part1 = inl(rtl8139_io_base + MAC0_5);
117 uint16_t mac_part2 = inw(rtl8139_io_base + MAC0_5 + 4);
119 rtl8139_mac[0] = (mac_part1 >> 0) & 0xFF;
120 rtl8139_mac[1] = mac_part1 >> 8;
121 rtl8139_mac[2] = mac_part1 >> 16;
122 rtl8139_mac[3] = mac_part1 >> 24;
124 rtl8139_mac[4] = mac_part2 >> 0;
125 rtl8139_mac[5] = mac_part2 >> 8;
127 qemu_log(
"Mac is: %x:%x:%x:%x:%x:%x", rtl8139_mac[0], rtl8139_mac[1], rtl8139_mac[2], rtl8139_mac[3], rtl8139_mac[4], rtl8139_mac[5]);
130 void rtl8139_enable_rx_tx() {
131 outb(rtl8139_io_base + CMD, 0x0C);
134 void rtl8139_setup_rcr() {
141 outl(rtl8139_io_base + 0x44, 0xf | (1 << 7));
144 void rtl8139_wake_up() {
145 outb(rtl8139_io_base + CONFIG_1, 0x0);
148 void rtl8139_sw_reset() {
149 outb(rtl8139_io_base + CMD, 0x10);
151 while((inb(rtl8139_io_base + CMD) & 0x10) != 0)
155 void rtl8139_init_buffer() {
156 outl(rtl8139_io_base + RBSTART, rtl8139_phys_buffer);
160 qemu_log(
"Received RTL8139 interrupt!");
162 rtl8139_in_irq =
true;
164 uint16_t status = inw(rtl8139_io_base + 0x3e);
167 qemu_log(
"Packet sent");
171 qemu_log(
"Packet received!\n");
174 rtl8139_receive_packet();
177 outw(rtl8139_io_base + 0x3E, 0x05);
179 rtl8139_in_irq =
false;
182 void rtl8139_send_packet(
void *data,
size_t length) {
189 qemu_log(
"Sending packet");
191 memset(rtl8139_transfer_buffer, 0, 65535);
193 memcpy(rtl8139_transfer_buffer, data, length);
202 outl(rtl8139_io_base + TSAD_array[rtl8139_current_tx_index], (uint32_t)rtl8139_transfer_buffer_phys);
203 outl(rtl8139_io_base + TSD_array[rtl8139_current_tx_index++], length);
207 if(rtl8139_current_tx_index > 3)
208 rtl8139_current_tx_index = 0;
210 qemu_log(
"Send packet end");
213 size_t rtl8139_current_packet_ptr = 0;
216 void rtl8139_receive_packet() {
217 uint16_t* packet = (uint16_t*)(rtl8139_virt_buffer + rtl8139_current_packet_ptr);
219 EthernetPacked* e_pack = (EthernetPacked*)packet;
221 qemu_log(
"[Net] [RTL8139] Получен пакет!");
222 qemu_log(
" |-- Заголовок данных: %x",e_pack->Header);
223 qemu_log(
" |-- Длина данных: %d",e_pack->Size);
224 qemu_log(
" |-- Источник: %x:%x:%x:%x:%x:%x",e_pack->MAC_SOURCE[0] ,e_pack->MAC_SOURCE[1],e_pack->MAC_SOURCE[2], e_pack->MAC_SOURCE[3] ,e_pack->MAC_SOURCE[4] ,e_pack->MAC_SOURCE[5]);
225 qemu_log(
" |-- Кому: %x:%x:%x:%x:%x:%x", e_pack->MAC_DEVICE[0], e_pack->MAC_DEVICE[1], e_pack->MAC_DEVICE[2], e_pack->MAC_DEVICE[3], e_pack->MAC_DEVICE[4], e_pack->MAC_DEVICE[5]);
226 qemu_log(
" |-- Тип данных: %x", bit_flip_short(e_pack->Type));
232 uint16_t packet_header = e_pack->Header;
233 uint16_t packet_length = e_pack->Size;
235 uint16_t* packet_data = packet + 2;
237 qemu_log(
"[Net] [RTL8139] Данные с пакета:\n");
241 if(packet_header == HARDWARE_TYPE_ETHERNET) {
244 qemu_note(
"Processing packet...");
245 ethernet_handle_packet(&rtl8139_netcard, (ethernet_frame_t *) packet_data, packet_length);
246 qemu_ok(
"Packet processing is finished!");
249 rtl8139_current_packet_ptr = (rtl8139_current_packet_ptr + packet_length + 7) & RX_READ_POINTER_MASK;
251 if(rtl8139_current_packet_ptr > 8192)
252 rtl8139_current_packet_ptr -= 8192;
254 outw(rtl8139_io_base + CAPR, rtl8139_current_packet_ptr - 0x10);
257 void rtl8139_init_interrupts() {
258 outw(rtl8139_io_base + IMR, 0x0005);
269 rtl8139_irq = word & 0xff;
271 qemu_log(
"RTL8139 IRQ: %x", rtl8139_irq);
273 register_interrupt_handler(32 + rtl8139_irq, rtl8139_handler);
275 qemu_log(
"Initialized RTl8139 interrupts!");
struct registers __attribute__((packed))
Структура данных пакета от мыши
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
uint16_t pci_read_confspc_word(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset)
[PCI] Чтение 16-битных полей из пространства механизма конфигураций 1
void pci_find_device(uint16_t vendor, uint16_t device, uint8_t *bus_ret, uint8_t *slot_ret, uint8_t *func_ret)
[PCI] Поиск устройства по ID-поставшика и устройства
uint16_t pci_get_device(uint8_t bus, uint8_t slot, uint8_t function)
[PCI] Получение ID-Устройства