X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FNetwork%2FE1000%2Fe1000.c;h=404540aa17ccad191ec44f8bd2194c25d3fa2987;hb=13f6e43bd202691b72e1d17806d575d1935c6f13;hp=644d6940dd1546c6d07ee644f9d013b8730c6a39;hpb=123f510dc86e5179222e4b6844555aa69937b5da;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Network/E1000/e1000.c b/KernelLand/Modules/Network/E1000/e1000.c index 644d6940..404540aa 100644 --- a/KernelLand/Modules/Network/E1000/e1000.c +++ b/KernelLand/Modules/Network/E1000/e1000.c @@ -5,7 +5,7 @@ * e1000.c * - Intel 8254x Network Card Driver (core) */ -#define DEBUG 1 +#define DEBUG 0 #define VERSION VER2(0,1) #include #include "e1000.h" @@ -75,28 +75,16 @@ int E1000_Install(char **Arguments) for( int id = -1, i = 0; (id = PCI_GetDevice(cardtype->Vendor, cardtype->Device, i)) != -1; i ++ ) { tCard *card = &gaE1000_Cards[card_idx++]; - Uint32 mmiobase = PCI_GetBAR(id, 0); - if( mmiobase & (1|8) ) { + card->MMIOBasePhys = PCI_GetValidBAR(id, 0, PCI_BARTYPE_MEMNP); + if( !card->MMIOBasePhys ) { Log_Warning("E1000", "Dev %i: BAR0 should be non-prefetchable memory", id); continue; } - const int addrsize = (mmiobase>>1) & 3; - if( addrsize == 0 ) { - // Standard 32-bit - card->MMIOBasePhys = mmiobase & ~0xF; - } - else if( addrsize == 2 ) { - // 64-bit - card->MMIOBasePhys = (mmiobase & ~0xF) | ((Uint64)PCI_GetBAR(id, 1)<<32); - } - else { - Log_Warning("E1000", "Dev %i: Unknown memory address size %i", id, (mmiobase>>1)&3); - continue; - } card->IRQ = PCI_GetIRQ(id); IRQ_AddHandler(card->IRQ, E1000_IRQHandler, card); - + PCI_SetCommand(id, PCI_CMD_MEMENABLE|PCI_CMD_BUSMASTER, 0); + Log_Debug("E1000", "Card %i: %P IRQ %i", card_idx, card->MMIOBasePhys, card->IRQ); if( E1000_int_InitialiseCard(card) ) { @@ -118,8 +106,11 @@ void E1000_int_ReleaseRXD(void *Arg, size_t HeadLen, size_t FootLen, const void { tCard **cardptr = Arg; tCard *Card = *cardptr; - int rxd = (Arg - (void*)Card->RXDescs) / sizeof(tRXDesc); - + int rxd = (Arg - (void*)Card->RXBackHandles) / sizeof(void*); + + LOG("RXD %p %i being released", Card, rxd); + ASSERT(rxd >= 0 && rxd < NUM_RX_DESC); + Card->RXDescs[rxd].Status = 0; Mutex_Acquire(&Card->lRXDescs); if( rxd == REG32(Card, REG_RDT) ) { @@ -231,20 +222,34 @@ int E1000_SendPacket(void *Ptr, tIPStackBuffer *Buffer) else { // Single - Card->TXDescs[txd].Buffer = MM_GetPhysAddr(ptr); - Card->TXDescs[txd].Length = len; - Card->TXDescs[txd].CMD = TXD_CMD_RS; + volatile tTXDesc *txdp = &Card->TXDescs[txd]; + txdp->Buffer = MM_GetPhysAddr(ptr); + txdp->Length = len; + txdp->CMD = TXD_CMD_RS; + LOG("%P: %llx %x %x", MM_GetPhysAddr((void*)txdp), txdp->Buffer, txdp->Length, txdp->CMD); } txd = (txd + 1) % NUM_TX_DESC; } Card->TXDescs[last_txd].CMD |= TXD_CMD_EOP|TXD_CMD_IDE|TXD_CMD_IFCS; Card->TXSrcBuffers[last_txd] = Buffer; + __sync_synchronize(); + #if DEBUG + { + volatile tTXDesc *txdp = Card->TXDescs + last_txd; + LOG("%p %P: %llx %x %x", txdp, MM_GetPhysAddr((void*)txdp), txdp->Buffer, txdp->Length, txdp->CMD); + volatile tTXDesc *txdp_base = MM_MapTemp(MM_GetPhysAddr((void*)Card->TXDescs)); + txdp = txdp_base + last_txd; + LOG("%p %P: %llx %x %x", txdp, MM_GetPhysAddr((void*)txdp), txdp->Buffer, txdp->Length, txdp->CMD); + MM_FreeTemp( (void*)txdp_base); + } + #endif // Trigger TX IPStack_Buffer_LockBuffer(Buffer); + LOG("Triggering TX - Buffers[%i]=%p", last_txd, Buffer); REG32(Card, REG_TDT) = Card->FirstFreeTXD; Mutex_Release(&Card->lTXDescs); - LOG("Waiting for TX"); + LOG("Waiting for TX to complete"); // Wait for completion (lock will block, then release straight away) IPStack_Buffer_LockBuffer(Buffer); @@ -269,21 +274,47 @@ void E1000_IRQHandler(int Num, void *Ptr) if( (icr & ICR_TXDW) || (icr & ICR_TXQE) ) { int nReleased = 0; + int txd = Card->LastFreeTXD; + int nReleasedAtLastDD = 0; + int idxOfLastDD = txd; // Walk descriptors looking for the first non-complete descriptor LOG("TX %i:%i", Card->LastFreeTXD, Card->FirstFreeTXD); - while( Card->LastFreeTXD != Card->FirstFreeTXD && (Card->TXDescs[Card->LastFreeTXD].Status & TXD_STS_DD) ) + while( txd != Card->FirstFreeTXD ) { nReleased ++; - if( Card->TXSrcBuffers[Card->LastFreeTXD] ) { - IPStack_Buffer_UnlockBuffer( Card->TXSrcBuffers[Card->LastFreeTXD] ); - Card->TXSrcBuffers[Card->LastFreeTXD] = NULL; + if(Card->TXDescs[txd].Status & TXD_STS_DD) { + nReleasedAtLastDD = nReleased; + idxOfLastDD = txd; } - Card->LastFreeTXD ++; - if(Card->LastFreeTXD == NUM_TX_DESC) - Card->LastFreeTXD = 0; + txd ++; + if(txd == NUM_TX_DESC) + txd = 0; + } + if( nReleasedAtLastDD ) + { + // Unlock buffers + txd = Card->LastFreeTXD; + LOG("TX unlocking range %i-%i", txd, idxOfLastDD); + while( txd != (idxOfLastDD+1)%NUM_TX_DESC ) + { + if( Card->TXSrcBuffers[txd] ) { + LOG("- Unlocking %i:%p", txd, Card->TXSrcBuffers[txd]); + IPStack_Buffer_UnlockBuffer( Card->TXSrcBuffers[txd] ); + Card->TXSrcBuffers[txd] = NULL; + } + txd ++; + if(txd == NUM_TX_DESC) + txd = 0; + } + // Update last free + Card->LastFreeTXD = txd; + Semaphore_Signal(&Card->FreeTxDescs, nReleasedAtLastDD); + LOG("nReleased = %i", nReleasedAtLastDD); + } + else + { + LOG("No completed TXDs"); } - Semaphore_Signal(&Card->FreeTxDescs, nReleased); - LOG("nReleased = %i", nReleased); } if( icr & ICR_LSC ) @@ -292,6 +323,11 @@ void E1000_IRQHandler(int Num, void *Ptr) LOG("LSC"); // TODO: Detect link drop/raise and poke IPStack } + + if( icr & ICR_RXO ) + { + LOG("RX Overrun"); + } // Pending packet (s) if( icr & ICR_RXT0 ) @@ -341,7 +377,7 @@ int DrvUtil_AllocBuffers(void **Buffers, int NumBufs, int PhysBits, size_t BufSi size_t ofs = 0; const int bufs_per_page = PAGE_SIZE / BufSize; ASSERT(bufs_per_page * BufSize == PAGE_SIZE); - void *page; + void *page = NULL; for( int i = 0; i < NumBufs; i ++ ) { if( ofs == 0 ) { @@ -422,6 +458,7 @@ int E1000_int_InitialiseCard(tCard *Card) LEAVE('i', 4); return 4; } + LOG("Card->RXDescs = %p [%P]", Card->TXDescs, MM_GetPhysAddr((void*)Card->TXDescs)); for( int i = 0; i < NUM_TX_DESC; i ++ ) { Card->TXDescs[i].Buffer = 0;