home bbs files messages ]

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; idata, packet.size); // deep copy   
       RTLSendNextPacketInQueue();   
   }   
      
   bool RTLSendNextPacketInQueue() {   
       int i = 0;   
       for (; i < 4 && in16bit(ioAddr + RTL_TRANSMIT_COMMAND[i]) & (1 << 15);   
   i++);   
       if (i == 4) // no pairs which arent used   
           return false; // return false, it couldn't send the next packet.   
      
       NICPacket *packet = queueHead(RTLQueue);   
       if (!packet) // no packet in queue   
           return false;   
      
       memcpy(packet->data, tx_buffer, packet->size);   
      
       printPacket("aaaaa", tx_buffer, packet->size);   
      
       out32bit(ioAddr + RTL_TRANSMIT_START[i], tx_buffer);   
       out32bit(ioAddr + RTL_TRANSMIT_COMMAND[i], ((uint32_t)packet->size) | (48   
   << 16));   
       while(true) kprint("a");   
      
       queuePop(&RTLQueue, 0);   
       return true;   
   }   
      
      
   https://gitlab.com/yehudaelyasaf/PuTTYnOS/-/blob/NetworkStack/ke   
   nel/network/nic/rtl8139.h:   
   #pragma once   
      
   #include    
   #include "../../cpu/isr.h"   
   #include "../network.h"   
      
   #define MAC_ADDRES_GROUPS 6   
      
   enum RTL8139{   
       MAC0                        = 0x0,   
       INIT_RTL_CONTROL_REGISTER   = 0x52,   
       RBSTART                     = 0x30,   
       RTL_CONTROL_REGISTER        = 0x37,   
       IMR_ISR_FLAGS               = 0x3C,   
       TX_CONFIG                   = 0x40,   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca