Here is my code:
Code: Select all
#define RX_BUF_LEN 8192 + 16 + 1500
#define RX_READ_POINTER_MASK (~3)
uint nic_base;
uint rx_buffer;
uint cpptr;
extern void set_idt_handler(int i, void (*handler));
extern void nic_irq();
void rtl8139_handler()
{
int status = inw(nic_base + 0x3e);
if(status & (1 << 0))
{
printf("\nrtl8139: debug: received packet");
u16* pointer = (u16*)(rx_buffer + cpptr); // packet pointer
u16 pLen = *(t + 1); // packet len
// data pointer
pointer = pointer + 2;
void * packet_data = malloc(pLen);
memcpy(packet_data, pointer, pLen);
mem_dump(packet_data, pLen, 15);
printf("\n packet len %d", pLen);
cpptr = (cpptr + packet_length + 4 + 3) & RX_READ_POINTER_MASK;
if (cpptr > RX_BUF_LEN)
cpptr -= RX_BUF_LEN;
outw(nic_base + 0x38, cpptr - 0x10);
}
outw(nic_base + 0x3E, 0x5);
}
void rtl8139_init()
{
uint8_t bus;
uint8_t slot;
uint8_t func;
PCIFindDevice2(&bus, &slot, &func, 0x8139, 0x10EC);
if(bus == 0xFF) return;
if(slot == 0xFF) return;
if(func == 0xFF) return;
PciBar bar;
PciGetBar(&bar, PCI_MAKE_ID(bus, slot, func), 0);
uint32_t nic_addr = bar.u.port;
printf("\nrtl8139: driver started");
// Enable PCI Bus Mastering for NIC
unsigned short cfg = PciRead16(PCI_MAKE_ID(bus, slot, func), 4);
PciWrite16(PCI_MAKE_ID(bus, slot, func), 4, cfg | 2);
// turn on
outb(bar.u.port + 0x52, 0);
printf("\nrtl8139: turned on");
// Send reset command to NIC
printf("\nrtl8139: reseting card");
outb(bar.u.port + 0x37, 0x10);
// Wait.....
while(inb(bar.u.port + 0x37) & 0x10){}
// Allocate rx_buffer
rx_buffer = malloc(RX_BUF_LEN);
// set RX-buffer and interrupts
outl(bar.u.port + 0x30, (uint)rx_buffer);
// set IMR + ISR
outw(bar.u.port + 0x3C, 0x0005);
// Configuring receive buffer (RCR)
outd(bar.u.port + 0x44, 0xf | (1 << 7));
// Enable Receive and Transmitter
outb(bar.u.port + 0x37, 0x0C);
uint8_t irq = (uint8_t)PCIGetIRQ(bus, slot, func);
__asm("cli");
set_idt_handler(irq+32, &nic_irq);
__asm("sti");
nic_base = bar.u.port;
}