From eceedd44a40b713c2adf0ea8e3e864099e97477c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 7 Jun 2011 16:57:17 +0800 Subject: [PATCH] Networking - Bugfixing in IPStack/RTL8139 driver - PCI: Cleaned up (don't need to allocate ports, PCI bios does that for us) - Fixed Endian flipping issues - Added some debugging and catches to IPStack - Fixed IPv4 dropping all packets (due to firewall returning -1) > Need to create stub rules for INPUT/OUTPUT/FORWARD - Huge changes in RTL8136 driver > Now tested, but not fully --- Kernel/drv/pci.c | 15 +++- Kernel/include/acess.h | 2 +- Modules/IPStack/arp.c | 14 ++- Modules/IPStack/interface.c | 2 + Modules/IPStack/ipv4.c | 11 ++- Modules/IPStack/link.c | 6 +- Modules/Network/RTL8139/rtl8139.c | 136 ++++++++++++++++++++++-------- 7 files changed, 140 insertions(+), 46 deletions(-) diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index df5c1144..8dc947cc 100644 --- a/Kernel/drv/pci.c +++ b/Kernel/drv/pci.c @@ -296,7 +296,7 @@ int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn) */ int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx) { - int i, j=0; + int i, j=0; for(i=0;i= giPCI_DeviceCount) return 0; + if(bar < 0 || bar > 5) return 0; + dev = &gPCI_Devices[id]; + + rv = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 ); + if(rv & 1) return rv & ~1; + return 0; + #else Uint16 portVals; int gran=0; int i, j; @@ -466,6 +478,7 @@ Uint16 PCI_AssignPort(int id, int bar, int count) // Return //LogF("PCI_AssignPort: RETURN 0x%x\n", portVals); return portVals; + #endif } /** diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index f046a11f..d4feaf7b 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -307,7 +307,7 @@ extern int CheckMem(const void *Mem, int Num); * \name Endianness Swapping * \{ */ -#if __ENDIAN == BIG_ENDIAN +#ifdef __BIG_ENDIAN__ #define LittleEndian16(_val) SwapEndian16(_val) #define LittleEndian32(_val) SwapEndian32(_val) #define BigEndian16(_val) (_val) diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c index e5d8a2ba..e0912ad8 100644 --- a/Modules/IPStack/arp.c +++ b/Modules/IPStack/arp.c @@ -42,7 +42,7 @@ struct sARP_Cache6 { int giARP_Cache6Space; tMutex glARP_Cache6; #endif - int giARP_LastUpdateID = 0; +volatile int giARP_LastUpdateID = 0; // === CODE === /** @@ -135,11 +135,13 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) for(;;) { while(lastID == giARP_LastUpdateID && now() < timeout) { -// Log_Debug("ARP", "timeout = %lli", timeout); Threads_Yield(); } - if( now() >= timeout ) break; // Timeout + if( now() >= timeout ) { + Log_Log("ARP4", "Timeout"); + break; // Timeout + } lastID = giARP_LastUpdateID; @@ -149,6 +151,10 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) if(gaARP_Cache4[i].IP.L != Address.L) continue; Mutex_Release( &glARP_Cache4 ); + Log_Debug("ARP4", "Return %02x:%02x:%02x:%02x:%02x:%02x", + gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1], + gaARP_Cache4[i].MAC.B[2], gaARP_Cache4[i].MAC.B[3], + gaARP_Cache4[i].MAC.B[4], gaARP_Cache4[i].MAC.B[5]); return gaARP_Cache4[i].MAC; } Mutex_Release( &glARP_Cache4 ); @@ -184,7 +190,6 @@ void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr) i = free; else i = oldest; - gaARP_Cache4[i].IP = SWAddr; } Log_Log("ARP4", "Caching %i.%i.%i.%i (%02x:%02x:%02x:%02x:%02x:%02x) in %i", @@ -193,6 +198,7 @@ void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr) i ); + gaARP_Cache4[i].IP = SWAddr; gaARP_Cache4[i].MAC = HWAddr; gaARP_Cache4[i].LastUpdate = now(); giARP_LastUpdateID ++; diff --git a/Modules/IPStack/interface.c b/Modules/IPStack/interface.c index 14c3ed32..74f0cf83 100644 --- a/Modules/IPStack/interface.c +++ b/Modules/IPStack/interface.c @@ -181,6 +181,7 @@ int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data) { char name[4] = ""; tInterface *iface = IPStack_AddInterface(Data, name); + if(iface == NULL) LEAVE_RET('i', -1); tmp = iface->Node.ImplInt; } LEAVE_RET('i', tmp); @@ -203,6 +204,7 @@ tInterface *IPStack_AddInterface(const char *Device, const char *Name) card = IPStack_GetAdapter(Device); if( !card ) { + Log_Debug("IPStack", "Unable to open card '%s'", Device); LEAVE('n'); return NULL; // ERR_YOURBAD } diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index eb7e51df..a2e63efa 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -71,6 +71,8 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int if( MAC_EQU(to, cMAC_ZERO) ) { // No route to host + Log_Notice("IPv4", "No route to host %i.%i.%i.%i", + Address.B[0], Address.B[1], Address.B[2], Address.B[3]); return 0; } @@ -79,8 +81,9 @@ int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int 4, (tIPv4*)Iface->Address, &Address, Protocol, 0, Length, Data); - if(ret != 0) { + if(ret > 0) { // Just drop it (with an error) + Log_Notice("IPv4", "Firewall dropped packet"); return 0; } @@ -121,7 +124,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff Uint8 *data; int dataLength; int ret; - + if(Length < sizeof(tIPv4Header)) return; #if 0 @@ -200,8 +203,12 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff case 1: Log_Debug("IPv4", "Silently dropping packet"); return ; + case -1: + // Bad rule + break ; // Unknown, silent drop default: + Log_Warning("IPv4", "Unknown firewall response %i", ret); return ; } diff --git a/Modules/IPStack/link.c b/Modules/IPStack/link.c index 8de87292..fe08b8d5 100644 --- a/Modules/IPStack/link.c +++ b/Modules/IPStack/link.c @@ -101,7 +101,7 @@ void Link_WatchDevice(tAdapter *Adapter) int tid = Proc_SpawnWorker(); // Create a new worker thread if(tid < 0) { - Log_Warning("NET", "Unable to create watcher thread for '%s'", Adapter->Device); + Log_Warning("Net Link", "Unable to create watcher thread for '%s'", Adapter->Device); return ; } @@ -130,7 +130,7 @@ void Link_WatchDevice(tAdapter *Adapter) if(ret == -1) break; if(ret <= (int)sizeof(tEthernetHeader)) { - Log_Log("NET", "Recieved an undersized packet"); + Log_Log("Net Link", "Recieved an undersized packet"); continue; } @@ -167,7 +167,7 @@ void Link_WatchDevice(tAdapter *Adapter) ); } - Log_Log("NET", "Watcher terminated (file closed)"); + Log_Log("Net Link", "Watcher terminated (file closed)"); Threads_Exit(0, 0); } diff --git a/Modules/Network/RTL8139/rtl8139.c b/Modules/Network/RTL8139/rtl8139.c index 32aa7d45..c63dfeed 100644 --- a/Modules/Network/RTL8139/rtl8139.c +++ b/Modules/Network/RTL8139/rtl8139.c @@ -3,7 +3,7 @@ * - By John Hodge (thePowersGang) */ #define DEBUG 0 -#define VERSION ((0<<8)|50) +#define VERSION ((0<<8)|20) #include #include #include @@ -12,6 +12,9 @@ #include // === CONSTANTS === +#define VENDOR_ID 0x10EC +#define DEVICE_ID 0x8139 + enum eRTL8139_Regs { // MAC Address @@ -78,6 +81,7 @@ typedef struct sCard char *TransmitBuffers[4]; tPAddr PhysTransmitBuffers[4]; BOOL TransmitInUse; // Flags for each transmit descriptor + int CurTXDecscriptor; char Name[2]; tVFS_Node Node; @@ -121,15 +125,18 @@ int RTL8139_Install(char **Options) Uint16 base; tCard *card; - giRTL8139_CardCount = PCI_CountDevices( 0x10EC, 0x8139, 0 ); + giRTL8139_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID, 0); + Log_Debug("RTL8139", "%i cards", giRTL8139_CardCount); - gaRTL8139_Cards = calloc( giRTL8139_CardCount, sizeof(tCard) ); + if( giRTL8139_CardCount == 0 ) return MODULE_ERR_NOTNEEDED; + gaRTL8139_Cards = calloc( giRTL8139_CardCount, sizeof(tCard) ); - while( (id = PCI_GetDevice(0x10EC, 0x8139, 0, id)) != -1 ) + //while( (id = PCI_GetDevice(0x10EC, 0x8139, 0, id)) != -1 ) + while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, 0, i)) != -1 ) { - base = PCI_AssignPort( id, 0, 0x100 ); card = &gaRTL8139_Cards[i]; + base = PCI_AssignPort( id, 0, 0x100 ); card->IOBase = base; card->IRQ = PCI_GetIRQ( id ); @@ -146,7 +153,10 @@ 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; outd(base + RBSTART, (Uint32)card->PhysReceiveBuffer); + outd(base + CBA, 0); + outd(base + CAPR, 0); // Set IMR to Transmit OK and Receive OK outw(base + IMR, 0x5); @@ -156,7 +166,7 @@ int RTL8139_Install(char **Options) card->TransmitBuffers[1] = card->TransmitBuffers[0] + 0x800; card->PhysTransmitBuffers[1] = card->PhysTransmitBuffers[0] + 0x800; - card->TransmitBuffers[2] = (void*)MM_AllocDMA( 1, 32, &card->PhysTransmitBuffers[1] ); + card->TransmitBuffers[2] = (void*)MM_AllocDMA( 1, 32, &card->PhysTransmitBuffers[2] ); card->TransmitBuffers[3] = card->TransmitBuffers[2] + 0x800; card->PhysTransmitBuffers[3] = card->PhysTransmitBuffers[2] + 0x800; @@ -192,14 +202,18 @@ int RTL8139_Install(char **Options) card->Node.Read = RTL8139_Read; card->Node.IOCtl = RTL8139_IOCtl; - Log_Log("RTL8139", "Card %i 0x%04x %02x:%02x:%02x:%02x:%02x:%02x", - i, base, + Log_Log("RTL8139", "Card %i 0x%04x, IRQ %i %02x:%02x:%02x:%02x:%02x:%02x", + i, card->IOBase, card->IRQ, card->MacAddr[0], card->MacAddr[1], card->MacAddr[2], card->MacAddr[3], card->MacAddr[4], card->MacAddr[5] ); i ++; } + + gRTL8139_DriverInfo.RootNode.Size = giRTL8139_CardCount; + DevFS_AddDevice( &gRTL8139_DriverInfo ); + return MODULE_ERR_OK; } @@ -214,7 +228,7 @@ char *RTL8139_ReadDir(tVFS_Node *Node, int Pos) tVFS_Node *RTL8139_FindDir(tVFS_Node *Node, const char *Filename) { //TODO: It might be an idea to supprt >10 cards - if(Filename[0] == '\0' || Filename[0] != '\0') return NULL; + if(Filename[0] == '\0' || Filename[1] != '\0') return NULL; if(Filename[0] < '0' || Filename[0] > '9') return NULL; return &gaRTL8139_Cards[ Filename[0]-'0' ].Node; } @@ -222,10 +236,12 @@ tVFS_Node *RTL8139_FindDir(tVFS_Node *Node, const char *Filename) const char *csaRTL8139_RootIOCtls[] = {DRV_IOCTLNAMES, NULL}; int RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Data) { + ENTER("pNode iID pData", Node, ID, Data); switch(ID) { BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_RootIOCtls); } + LEAVE('i', 0); return 0; } @@ -233,35 +249,46 @@ int RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Data) Uint64 RTL8139_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { tCard *card = Node->ImplPtr; - int read_ofs, pkt_length; + Uint16 read_ofs, pkt_length; + int new_read_ofs; + + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); retry: Semaphore_Wait( &card->ReadSemaphore, 1 ); Mutex_Acquire( &card->ReadMutex ); - read_ofs = ind( card->IOBase + CAPR ) - card->PhysReceiveBuffer; + read_ofs = (inw( card->IOBase + CAPR ) + 0x10) & 0xFFFF; + LOG("read_ofs = %i", read_ofs); + + pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2]; + + // 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; + new_read_ofs -= 0x10; // I dunno // Check for errors if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E ) { + // Update CAPR + outd(card->IOBase + CAPR, new_read_ofs); Mutex_Release( &card->ReadMutex ); goto retry; // I feel evil } - pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2]; - // Get packet if( Length > pkt_length ) Length = pkt_length; memcpy(Buffer, &card->ReceiveBuffer[read_ofs+4], Length); - // Update read offset - read_ofs += pkt_length + 4; - read_ofs = (read_ofs + 3) & ~3; // Align - if(read_ofs > card->ReceiveBufferLength) read_ofs = 0; - outd(card->IOBase + CAPR, read_ofs + card->PhysReceiveBuffer); + // Update CAPR + outw(card->IOBase + CAPR, new_read_ofs); Mutex_Release( &card->ReadMutex ); + LEAVE('i', Length); + return Length; } @@ -273,18 +300,22 @@ Uint64 RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer if( Length > 1500 ) return 0; // MTU exceeded - // TODO: Implement a semaphore for avaliable tranmit buffers + ENTER("pNode XLength pBuffer", Node, Length, Buffer); + + // TODO: Implement a semaphore for avaliable transmit buffers + + td = card->CurTXDecscriptor; // Find an avaliable descriptor - do { - for( td = 0; td < 4; td ++ ) { - if( !(card->TransmitInUse & (1 << td)) ) - break; - } - } while(td == 4 && (Threads_Yield(),1)); + while( card->TransmitInUse & (1 << td) ) + Threads_Yield(); + + LOG("td = %i", td); // Transmit using descriptor `td` card->TransmitInUse |= (1 << td); + outd(card->IOBase + TSAD0 + td*4, card->PhysTransmitBuffers[td]); + LOG("card->PhysTransmitBuffers[td] = 0x%llx", card->PhysTransmitBuffers[td]); // Copy to buffer memcpy(card->TransmitBuffers[td], Buffer, Length); // Start @@ -292,18 +323,35 @@ Uint64 RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer status |= Length & 0x1FFF; // 0-12: Length status |= 0 << 13; // 13: OWN bit status |= (0 & 0x3F) << 16; // 16-21: Early TX threshold (zero atm, TODO: check) - outd(card->IOBase + TSD0 + td, status); + LOG("status = 0x%08x", status); + outd(card->IOBase + TSD0 + td*4, status); - return 0; + card->CurTXDecscriptor ++; + card->CurTXDecscriptor %= 4; + + LEAVE('i', (int)Length); + + return Length; } const char *csaRTL8139_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL}; int RTL8139_IOCtl(tVFS_Node *Node, int ID, void *Data) { + tCard *card = Node->ImplPtr; + ENTER("pNode iID pData", Node, ID, Data); switch(ID) { BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_NodeIOCtls); + case NET_IOCTL_GETMAC: + if( !CheckMem(Data, 6) ) { + LEAVE('i', -1); + return -1; + } + memcpy( Data, card->MacAddr, 6 ); + LEAVE('i', 1); + return 1; } + LEAVE('i', 0); return 0; } @@ -311,25 +359,27 @@ void RTL8139_IRQHandler(int Num) { int i, j; tCard *card; - Uint8 status; + Uint16 status; + for( i = 0; i < giRTL8139_CardCount; i ++ ) { card = &gaRTL8139_Cards[i]; if( Num != card->IRQ ) break; - status = inb(card->IOBase + ISR); + status = inw(card->IOBase + ISR); + LOG("status = 0x%02x", status); // Transmit OK, a transmit descriptor is now free if( status & FLAG_ISR_TOK ) { - outb(card->IOBase + ISR, FLAG_ISR_TOK); for( j = 0; j < 4; j ++ ) { - if( ind(card->IOBase + TSD0 + j) & 0x8000 ) { // TSD TOK + if( ind(card->IOBase + TSD0 + j*4) & 0x8000 ) { // TSD TOK card->TransmitInUse &= ~(1 << j); // TODO: Update semaphore once implemented } } + outw(card->IOBase + ISR, FLAG_ISR_TOK); } // Recieve OK, inform read @@ -339,29 +389,45 @@ void RTL8139_IRQHandler(int Num) int packet_count = 0; // Scan recieve buffer for packets - end_ofs = ind(card->IOBase + CBA) - card->PhysReceiveBuffer; + end_ofs = inw(card->IOBase + CBA); read_ofs = card->SeenOfs; + LOG("read_ofs = %i, end_ofs = %i", read_ofs, end_ofs); if( read_ofs > end_ofs ) { while( read_ofs < card->ReceiveBufferLength ) { packet_count ++; - read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+1] + 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] + ); + read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4; + read_ofs = (read_ofs + 3) & ~3; // Align + } read_ofs = 0; } while( read_ofs < end_ofs ) { + 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+1] + 2; + read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4; + read_ofs = (read_ofs + 3) & ~3; // Align } card->SeenOfs = read_ofs; + LOG("packet_count = %i, read_ofs = 0x%x", packet_count, read_ofs); + Semaphore_Signal( &card->ReadSemaphore, packet_count ); if( packet_count ) VFS_MarkAvaliable( &card->Node, 1 ); - outb(card->IOBase + ISR, FLAG_ISR_ROK); + outw(card->IOBase + ISR, FLAG_ISR_ROK); } } } -- 2.20.1