X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FNetwork%2FRTL8139%2Frtl8139.c;h=bb479554f4f9069ece305e6b3e0c43b437d59856;hb=e6795eb552a6be88b7870dae14a958ab391bfae8;hp=d77fe27300512dc86c97305f9e8507220a4ec94c;hpb=abe6c6cf7fac39102e20cd28687b24c67f4952f8;p=tpg%2Facess2.git diff --git a/Modules/Network/RTL8139/rtl8139.c b/Modules/Network/RTL8139/rtl8139.c index d77fe273..bb479554 100644 --- a/Modules/Network/RTL8139/rtl8139.c +++ b/Modules/Network/RTL8139/rtl8139.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include // === CONSTANTS === @@ -80,8 +80,9 @@ typedef struct sCard char *TransmitBuffers[4]; tPAddr PhysTransmitBuffers[4]; - BOOL TransmitInUse; // Flags for each transmit descriptor - int CurTXDecscriptor; + tMutex TransmitInUse[4]; + tMutex CurTXProtector; //!< Protects \a .CurTXDescriptor + int CurTXDescriptor; char Name[2]; tVFS_Node Node; @@ -125,7 +126,7 @@ int RTL8139_Install(char **Options) Uint16 base; tCard *card; - giRTL8139_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID, 0); + giRTL8139_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID); Log_Debug("RTL8139", "%i cards", giRTL8139_CardCount); if( giRTL8139_CardCount == 0 ) return MODULE_ERR_NOTNEEDED; @@ -133,10 +134,17 @@ int RTL8139_Install(char **Options) gaRTL8139_Cards = calloc( giRTL8139_CardCount, sizeof(tCard) ); //while( (id = PCI_GetDevice(0x10EC, 0x8139, 0, id)) != -1 ) - while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, 0, i)) != -1 ) + while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, i)) != -1 ) { card = &gaRTL8139_Cards[i]; - base = PCI_AssignPort( id, 0, 0x100 ); + base = PCI_GetBAR( id, 0 ); + if( !(base & 1) ) { + Log_Warning("RTL8139", "Driver does not support MMIO, skipping card"); + card->IOBase = 0; + card->IRQ = 0; + continue ; + } + base &= ~1; card->IOBase = base; card->IRQ = PCI_GetIRQ( id ); @@ -153,7 +161,7 @@ int RTL8139_Install(char **Options) // Set up recieve buffer // - Allocate 3 pages below 4GiB for the recieve buffer (Allows 8k+16+1500) card->ReceiveBuffer = (void*)MM_AllocDMA( 3, 32, &card->PhysReceiveBuffer ); - card->ReceiveBufferLength = 8*1024+16; + card->ReceiveBufferLength = 8*1024; outd(base + RBSTART, (Uint32)card->PhysReceiveBuffer); outd(base + CBA, 0); outd(base + CAPR, 0); @@ -176,10 +184,10 @@ int RTL8139_Install(char **Options) outd(base + TSAD3, card->PhysTransmitBuffers[3]); // Set recieve buffer size and recieve mask - // - Bit 7 being unset tells the card to overflow the recieve buffer if needed + // - Bit 7 being set tells the card to overflow the recieve buffer if needed // (i.e. when the packet starts at the end of the bufffer, it overflows up // to 1500 bytes) - outd(base + RCR, 0x0F); + outd(base + RCR, 0x8F); // Recive Enable and Transmit Enable outb(base + CMD, 0x0C); @@ -262,7 +270,9 @@ retry: Mutex_Acquire( &card->ReadMutex ); - read_ofs = (inw( card->IOBase + CAPR ) + 0x10) & 0xFFFF; + read_ofs = inw( card->IOBase + CAPR ); + LOG("raw read_ofs = %i", read_ofs); + read_ofs = (read_ofs + 0x10) & 0xFFFF; LOG("read_ofs = %i", read_ofs); pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2]; @@ -270,13 +280,17 @@ retry: // Calculate new read offset new_read_ofs = read_ofs + pkt_length + 4; new_read_ofs = (new_read_ofs + 3) & ~3; // Align - if(new_read_ofs > card->ReceiveBufferLength) new_read_ofs = 0; + if(new_read_ofs > card->ReceiveBufferLength) { + LOG("wrapping read_ofs"); + new_read_ofs -= card->ReceiveBufferLength; + } new_read_ofs -= 0x10; // I dunno + LOG("new_read_ofs = %i", new_read_ofs); // Check for errors if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E ) { // Update CAPR - outd(card->IOBase + CAPR, new_read_ofs); + outw(card->IOBase + CAPR, new_read_ofs); Mutex_Release( &card->ReadMutex ); goto retry; // I feel evil } @@ -306,19 +320,22 @@ Uint64 RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer ENTER("pNode XLength pBuffer", Node, Length, Buffer); // TODO: Implement a semaphore for avaliable transmit buffers - - td = card->CurTXDecscriptor; - + // Find an avaliable descriptor - while( card->TransmitInUse & (1 << td) ) - Threads_Yield(); + Mutex_Acquire(&card->CurTXProtector); + td = card->CurTXDescriptor; + card->CurTXDescriptor ++; + card->CurTXDescriptor %= 4; + Mutex_Release(&card->CurTXProtector); + // - Lock it + Mutex_Acquire( &card->TransmitInUse[td] ); LOG("td = %i", td); // Transmit using descriptor `td` - card->TransmitInUse |= (1 << td); + LOG("card->PhysTransmitBuffers[td] = %P", card->PhysTransmitBuffers[td]); outd(card->IOBase + TSAD0 + td*4, card->PhysTransmitBuffers[td]); - LOG("card->PhysTransmitBuffers[td] = 0x%llx", card->PhysTransmitBuffers[td]); + LOG("card->TransmitBuffers[td] = %p", card->TransmitBuffers[td]); // Copy to buffer memcpy(card->TransmitBuffers[td], Buffer, Length); // Start @@ -329,9 +346,6 @@ Uint64 RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer LOG("status = 0x%08x", status); outd(card->IOBase + TSD0 + td*4, status); - card->CurTXDecscriptor ++; - card->CurTXDecscriptor %= 4; - LEAVE('i', (int)Length); return Length; @@ -363,6 +377,8 @@ void RTL8139_IRQHandler(int Num) int i, j; tCard *card; Uint16 status; + + LOG("Num = %i", Num); for( i = 0; i < giRTL8139_CardCount; i ++ ) { @@ -378,7 +394,7 @@ void RTL8139_IRQHandler(int Num) for( j = 0; j < 4; j ++ ) { if( ind(card->IOBase + TSD0 + j*4) & 0x8000 ) { // TSD TOK - card->TransmitInUse &= ~(1 << j); + Mutex_Release( &card->TransmitInUse[j] ); // TODO: Update semaphore once implemented } } @@ -390,6 +406,7 @@ void RTL8139_IRQHandler(int Num) { int read_ofs, end_ofs; int packet_count = 0; + int len; // Scan recieve buffer for packets end_ofs = inw(card->IOBase + CBA); @@ -400,28 +417,36 @@ void RTL8139_IRQHandler(int Num) while( read_ofs < card->ReceiveBufferLength ) { packet_count ++; + len = *(Uint16*)&card->ReceiveBuffer[read_ofs+2]; LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x", packet_count, read_ofs, *(Uint16*)&card->ReceiveBuffer[read_ofs], - *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + len ); - read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4; + if(len > 2000) { + Log_Warning("RTL8139", "IRQ: Packet in buffer exceeds sanity (%i>2000)", len); + } + read_ofs += len + 4; read_ofs = (read_ofs + 3) & ~3; // Align - } - read_ofs = 0; + read_ofs -= card->ReceiveBufferLength; + LOG("wrapped read_ofs"); } while( read_ofs < end_ofs ) { + packet_count ++; LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x", packet_count, read_ofs, *(Uint16*)&card->ReceiveBuffer[read_ofs], *(Uint16*)&card->ReceiveBuffer[read_ofs+2] ); - packet_count ++; read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4; read_ofs = (read_ofs + 3) & ~3; // Align } + if( read_ofs != end_ofs ) { + Log_Warning("RTL8139", "IRQ: read_ofs (%i) != end_ofs(%i)", read_ofs, end_ofs); + read_ofs = end_ofs; + } card->SeenOfs = read_ofs; LOG("packet_count = %i, read_ofs = 0x%x", packet_count, read_ofs);