Merge branch 'master' of git://cadel.mutabah.net/acess2
[tpg/acess2.git] / KernelLand / Modules / Network / E1000 / e1000.c
index 644d694..21cc9ed 100644 (file)
@@ -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,32 @@ 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();
+       {
+               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);
+       }
        // 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 +272,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 +321,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 +375,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 +456,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;

UCC git Repository :: git.ucc.asn.au