Page 1 of 1

Packet handler problemo. :(

Posted: Sat Feb 09, 2008 2:09 am
by 01000101
In my x86 version of DiNS, I'm having a network card driver issue. I'm writing the driver for 2 RTL8139 10/100 NIC's. What is happening is that, when I visit a site, say myspace, I will get approximately 3-4 "bad packet" execptions get thrown for the packet_size being equal to 0. I will post the exception handling in basic format later in the post, as well as the NIC resetting function. There has got to be something I am missing, I'm just not sure what. I have functions to handle both normal buffered packets as well as packets that loop from the end of the buffer to the beginning. I have the card set to 32k buffer size to allow the wrapping ability for packets and it is in 100tx full-duplex.

Should I not be flushing the RX/TX buffers before the reset is finished? Am I not allotting enough time for it to fully reset?
Also, I (sometimes) get seemingly random rx_status errors that will light up all the error bits PLUS the ROK bit, which... makes no sense.


bad packet handler:

Code: Select all

Inter_Status = inb(ioaddr + IntrStatus);
	Buffer_Status = inb(ioaddr + ChipCmd) & 0x01;
    
    status = inw(ioaddr + IntrStatus);
          
	outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
	
	ring_offs = eth->cur_rx % RX_BUF_LEN;
	rx_status = *(unsigned long*)(eth->rx_ring + ring_offs);
	rx_size = (rx_status >> 16) & 0xffff;
    
          
	if (rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign))
    { 
        printf("rx_status issue (%x) \n", rx_status);
        RTL8139_eth_Reset(eth);
    }
    else if (rx_size > 1540)
    {
        printf("rx_size (%x) > 1540! \n", rx_size);
        RTL8139_eth_Reset(eth);
    }
    else if(rx_size == 0)
    {
        printf("rx_size == 0 \n",0x00);
        RTL8139_eth_Reset(eth);
    }
	
    else
    {/* normal packet interception */}
reset:

Code: Select all


static void RTL8139_eth_Reset(eth_t *eth)
{
	int i = 0;
    unsigned long ioaddr = eth->ioaddr;
    printf("Resetting RTL8139: ");
	eth->cur_rx = 0;                                   // Reset Rx_Buffer position
	eth->cur_tx = 0;                                   // Reset Tx_Buffer position
    eth->ring_offs = 0;
    eth->DHCP_Completed = 0x00;
    eth->server_mode = 0x00;
    
    outportb(ioaddr + 0x37, 0x10);                         // Software Reset
    
    for(i=0;i<(RX_BUF_LEN + 16);i++)
    {eth->rx_ring[i] = '\0';}
          
    for(i=0; i < (1536*4); i++)
    {eth->tx_buffer[i] = '\0';} 

    while(((inportb(ioaddr + 0x37) >> 4) & 0x01) != 0x00); // Wait for reset to finish
    
    outportl(ioaddr + 0x30, (unsigned long)eth->rx_ring);  // Set the RX_Buffer memory location
    outportb(ioaddr + 0x37, 0x0C);                         // Enable Transmitter and Reciever
    outportw(ioaddr + 0x3C, 0x0001);                       // Set IMR (ROK only)
    outportw(ioaddr + 0x3E, 0x0001);                       // Set ISR (ROK only)
    outportw(ioaddr + 0x40, 0x0200);                       // Max DMA size = 64 bytes
    outportl(ioaddr + 0x44, 0x0000F70F);                   // Enable Promiscuous Mode || Rx Buffer Length = 64K 
    outportl(ioaddr + 0x4C, 0x00000000);                   // Clear RX_Missed
    outportb(ioaddr + 0x58, 0x08);                         // Speed = 100Mbps 
    outportw(ioaddr + 0x62, 0x2100);                       // Duplex = Full-Duplex
    printf("[OK]\n");
    printf("RX_Buffer is @ %x\n",(unsigned long)(eth->rx_ring));
}
Thanks in advance.

Posted: Sat Feb 09, 2008 8:16 am
by Dex
Maybe you could take a look at the menuet driver, to see if you can spot a difference.

Posted: Sun Feb 10, 2008 2:35 am
by 01000101
thanks. I checked it out and am making some adjustments. It takes me a little bit to change the code from ASM to C, but its not that bad.

it seems I might be adding a bit too much to my recieve handler, so im cutting it down to the basics and re-testing the driver with only base code.

Posted: Sun Feb 10, 2008 8:13 am
by 01000101
I have seemed to fix alot of problems with my driver, but I now have one that I just cant seem to figure out.

I can surf the web now, but my speed is impacted because about 2-3 times per page I get a packet error becuase the packet size is 0xFFF0... and that just cannot be. I have no idea why this is happening. At first I thought maybe an interrupt was getting fired without need, thus looking for an 'imaginary' packet, but thats not the case.