Forums before death by AOL, social media and spammers... "We can't have nice things"
|    alt.os.development    |    Operating system development chatter    |    4,255 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 3,616 of 4,255    |
|    Yehuda Elyasaf to All    |
|    rtl8139 NIC driver not sending packets (    |
|    16 Mar 23 14:10:05    |
   
   From: hvusvvnkl12345@gmail.com   
      
   Hi,   
   I wrote an rtl8139 NIC driver. It looks like it works, but when I send a   
   packet (simple ARP packet) an ISR is called (isr 3 - "Breakpoint"). I'm   
   running it with qemu.   
   I enabled NIC debug mode in qemu's source code and recompiled it, and got   
   the following logs from the NIC:   
    RTL8139: Set IRQ to 0 (0000 0000)   
    RTL8139: entered rtl8139_set_next_tctr_time   
    RTL8139: Config1 write val=0x00   
    RTL8139: Configuration registers are write-protected   
    RTL8139: ChipCmd write val=0x00000010   
    RTL8139: ChipCmd reset   
    RTL8139: Set IRQ to 0 (0000 0000)   
    RTL8139: entered rtl8139_set_next_tctr_time   
    RTL8139: receiver buffer is empty   
    RTL8139: ChipCmd read val=0x0001   
    RTL8139: TxConfig read val=0x74800000   
    RTL8139: ChipCmd write val=0x0000000c   
    RTL8139: ChipCmd enable receiver   
    RTL8139: ChipCmd enable transmitter   
    RTL8139: TxConfig write val=0x03000700   
    RTL8139: RxConfig write val=0x01001e3e   
    RTL8139: RxConfig write reset buffer size to 65536   
    RTL8139: RxBuf write val=0x00c25e94   
    RTL8139: IntrMask write(w) val=0xffff   
    RTL8139: Set IRQ to 0 (0000 e1ff)   
    RTL8139: TxStatus/TxAddr[0] read addr=0x10 size=0x4 val=0x00002000   
    RTL8139: TxAddr write offset=0x0 val=0x00c35e94   
    RTL8139: TxStatus write offset=0x0 val=0x0030003c descriptor=0   
    RTL8139: +++ transmitting from descriptor 0   
    RTL8139: +++ transmit reading 60 bytes from host memory at 0x00c35e94   
    RTL8139: +++ transmitted 60 bytes from descriptor 0   
    RTL8139: Set IRQ to 1 (0004 e1ff)   
    RTL8139: IntrStatus read(w) val=0x0004   
    RTL8139: IntrStatus write(w) val=0x0004   
    RTL8139: Set IRQ to 0 (0000 e1ff)   
    RTL8139: entered rtl8139_set_next_tctr_time   
    RTL8139: Set IRQ to 0 (0000 e1ff)   
      
   The logs look alright, I have no idea what the problem is.   
   I compared the logs with another OS's logs (PrettyOS) and got the very same   
   logs (except the RxBuffer address, which is randomly determined).   
      
   Can you help me please?   
      
   Here is the source code:   
   https://gitlab.com/yehudaelyasaf/PuTTYnOS/-/blob/NetworkStack/ke   
   nel/network/nic/rtl8139.c   
   #include "rtl8139.h"   
      
   #include "../network.h"   
   #include "../../io/pci.h"   
   #include "../../asm.h"   
   #include "../../../lib/printf.h"   
   #include "../../../lib/convert.h"   
   #include "../../../lib/queue.h"   
   #include "../../../lib/memory.h"   
      
   #define VENDOR_ID 0x10EC   
   #define DEVICE_ID 0x8139   
      
   #define RX_BUFFER_LEN 0x10000   
   #define TX_BUFFER_LEN 4096   
   #define QUEUE_BUFFER_LEN 128   
   #define SEND_MAX_SIZE 0x700   
      
   const int RTL_TRANSMIT_COMMAND[] = {0x10, 0x14, 0x18, 0x1C};   
   const int RTL_TRANSMIT_START[] = {0x20, 0x24, 0x28, 0x2C};   
      
   NICPacket RTLQueueBuffer[QUEUE_BUFFER_LEN] = {0};   
      
   char buffer[RX_BUFFER_LEN + TX_BUFFER_LEN];   
   char *rx_buffer, *tx_buffer;   
   Queue RTLQueue;   
      
   uint8_t RTL8139IrqNumber = 0;   
   uint32_t ioAddr = 0;   
      
   bool initRTL8139(NetwotkAdapter* nic){   
    kprint("\tScanning for NIC...\n");   
    uint32_t pciAddr = PCI_ScanForDevice(VENDOR_ID, DEVICE_ID);   
      
    if (pciAddr == -1){   
    kprint("\tCouldn't find NIC address on PCI!");   
    return false;   
    }   
      
    ioAddr = PCI_Read(pciAddr + 0x10);   
    //two last bits reperesent address type   
    ioAddr &= (~0x3);   
    RTL8139IrqNumber = PCI_Read(pciAddr + 0x3C);   
      
    if(ioAddr == -1){   
    kprint("\tCouldn't find NIC!");   
    return false;   
    }   
    else{   
    kprint("\tFound device: RTL8139\n");   
    }   
      
    uint16_t pciCommand = PCI_Read(pciAddr + 0x6);   
    pciCommand |= 1 << 2;   
    PCI_Write(pciAddr, pciCommand);   
      
    rx_buffer = buffer;   
    tx_buffer = buffer + RX_BUFFER_LEN;   
      
    //power on   
    out8bit(ioAddr + INIT_RTL_CONTROL_REGISTER, POWER_ON_CODE);   
    //reset card   
    out8bit( ioAddr + RTL_CONTROL_REGISTER, RESET_CODE);   
    while( (in8bit(ioAddr + RTL_CONTROL_REGISTER) & RESET_CODE));   
      
    memset(0, rx_buffer, RX_BUFFER_LEN);   
      
      
    out8bit(ioAddr + RTL_CONTROL_REGISTER, 0x0C); // Sets the RE and TE bits   
   high, start recieving packets   
    out32bit(ioAddr + TX_CONFIG, 0x03000700);   
    out32bit(ioAddr + RX_CONFIG, /*0xf*/0x01001e3e); //TODO: why?   
      
    irqInstallHandler(RTL8139IrqNumber, RTLIrqHandler);   
    out32bit(ioAddr + RBSTART, rx_buffer); // send uint32_t memory location to   
   RBSTART (0x30)   
    out16bit(ioAddr + IMR_ISR_FLAGS, 0xFFFF); // Sets the TOK and ROK bits high   
      
      
    for (int i = 0; i < 6; i++)   
    nic->MAC[i] = in8bit(ioAddr+i);   
      
    //print MAC adress   
    char MACStr[20];   
    MACtos(nic->MAC, MACStr);   
    printf("\tMAC: %s\n", MACStr);   
      
    nic->IOBase = ioAddr;   
    nic->send = RTLSendPacket;   
    nic->sendMaxLen = SEND_MAX_SIZE;   
      
    RTLQueue = (Queue){RTLQueueBuffer, 0, QUEUE_BUFFER_LEN, sizeof(NICPacket)};   
      
    return true;   
   }   
      
   void RTLIrqHandler(IsrFrame registers) {   
    kcprint("I GOT A MESSAGE\n", GREEN, DEFAULT_COLOR);   
    //printPacket("MSG", rx_buffer, 100);   
    while(1)   
    printf("GOT!\n");   
    for(int i=0; i
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca