Kernel - Changed MM_GetPhysAddr to take a pointer
[tpg/acess2.git] / KernelLand / Modules / Network / VIARhineII / rhine2.c
index d351a4d..f9f4d25 100644 (file)
@@ -2,76 +2,79 @@
  * Acess2 VIA Rhine II Driver (VT6102)
  * - By John Hodge (thePowersGang)
  */
-#define        DEBUG   0
+#define        DEBUG   1
 #define VERSION        ((0<<8)|10)
 #include <acess.h>
 #include <modules.h>
-#include <fs_devfs.h>
 #include <drv_pci.h>
-#include <api_drv_network.h>
 #include <semaphore.h>
+#include "rhine2_hw.h"
+#include <IPStack/include/adapters_api.h>
+
+#define DESC_SIZE      16
+#define N_RX_DESCS     16
+#define RX_BUF_SIZE    1024
+#define N_RX_BUF_PER_PAGE      (PAGE_SIZE/RX_BUF_SIZE)
+#define N_RX_BUF_PAGES ((N_RX_DESCS*RX_BUF_SIZE)/PAGE_SIZE)
+#define N_TX_DESCS     ((PAGE_SIZE/DESC_SIZE)-N_RX_DESCS)
+
+#define CR0_BASEVAL    (CR0_STRT|CR0_TXON|CR0_RXON)
 
 // === CONSTANTS ===
 #define VENDOR_ID      0x1106
 #define DEVICE_ID      0x3065
 
-enum eRegs
-{
-       REG_PAR0, REG_PAR1,
-       REG_PAR2, REG_PAR3,
-       REG_PAR4, REG_PAR5,
-       REG_RCR,  REG_TCR,
-       REG_CR0,  REG_CR1,
-       REG_rsv0, REG_rsv1,
-       REG_ISR0, REG_ISR1,
-       REG_IMR0, REG_IMR1,
-};
-
 // === TYPES ===
 typedef struct sCard
 {
        Uint16  IOBase;
        Uint8   IRQ;
        
-        int    NumWaitingPackets;
+       tSemaphore      ReadSemaphore;
+       tSemaphore      SendSemaphore;
+
+       struct {
+               Uint32  Phys;
+               void    *Virt;
+       } RXBuffers[N_RX_BUF_PAGES];
+
+       Uint32  DescTablePhys;
+       void    *DescTable;
+
+       struct sTXDesc  *TXDescs;
+        int    NextTX;
+        int    nFreeTX;
        
-       char    Name[2];
-       tVFS_Node       Node;
+       struct sRXDesc  *NextRX;        // Most recent unread packet
+
+       void    *IPHandle;      
        Uint8   MacAddr[6];
 }      tCard;
 
 // === PROTOTYPES ===
  int   Rhine2_Install(char **Options);
-char   *Rhine2_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Rhine2_FindDir(tVFS_Node *Node, const char *Filename);
- int   Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Arg);
-Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
- int   Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Arg);
-void   Rhine2_IRQHandler(int Num);
+void   Rhine2_int_InitialiseCard(tCard *Card);
+tIPStackBuffer *Rhine2_WaitPacket(void *Ptr);
+ int   Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
+void   Rhine2_IRQHandler(int Num, void *Pt);
+// --- Helpers ---
+struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr);
+void   *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr);
+void   Rhine2_int_FreeRXDesc(void *Desc, size_t, size_t, const void*);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, VIARhineII, Rhine2_Install, NULL, NULL);
-tVFS_NodeType  gRhine2_DirType = {
-       .ReadDir = Rhine2_ReadDir,
-       .FindDir = Rhine2_FindDir,
-       .IOCtl = Rhine2_RootIOCtl
-       };
-tDevFS_Driver  gRhine2_DriverInfo = {
-       NULL, "Rhine2",
-       {
-       .NumACLs = 1,
-       .ACLs = &gVFS_ACL_EveryoneRX,
-       .Flags = VFS_FFLAG_DIRECTORY,
-       .Type = &gRhine2_DirType
-       }
+tIPStack_AdapterType   gRhine2_AdapterType = {
+       .Name = "VIA Rhine II",
+       .SendPacket = Rhine2_SendPacket,
+       .WaitForPacket = Rhine2_WaitPacket,
 };
  int   giRhine2_CardCount;
 tCard  *gaRhine2_Cards;
 
 // === CODE ===
 /**
- * \brief Installs the PCnet3 Driver
+ * \brief Initialises the driver
  */
 int Rhine2_Install(char **Options)
 {
@@ -81,8 +84,7 @@ int Rhine2_Install(char **Options)
        tCard   *card;
        
        giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID);
-       Log_Debug("PCnet3", "%i cards", giRhine2_CardCount);
-       
+       Log_Debug("Rhine2", "giRhine2_CardCount = %i", giRhine2_CardCount);
        if( giRhine2_CardCount == 0 )   return MODULE_ERR_NOTNEEDED;
        
        gaRhine2_Cards = calloc( giRhine2_CardCount, sizeof(tCard) );
@@ -98,270 +100,331 @@ int Rhine2_Install(char **Options)
                LOG("BAR4 = 0x%08x", PCI_GetBAR(id, 4));
                LOG("BAR5 = 0x%08x", PCI_GetBAR(id, 5));
                
-//             card->IOBase = base;
-//             card->IRQ = PCI_GetIRQ( id );
+               card->IOBase = PCI_GetBAR(id, 0);
+               if( !(card->IOBase & 1) ) {
+                       // Oops?
+                       Log_Warning("Rhine2", "BAR0 is not in IO space");
+                       continue ;
+               }
+               card->IOBase &= ~1;
+               card->IRQ = PCI_GetIRQ( id );
                
                // Install IRQ Handler
-//             IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler);
-               
-               
+               IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler, card);
                
-//             Log_Log("PCnet3", "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]
-//                     );
+               Rhine2_int_InitialiseCard(card);
+       
+               card->IPHandle = IPStack_Adapter_Add(&gRhine2_AdapterType, card, card->MacAddr);
+       
+               Log_Log("Rhine2", "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 ++;
        }
        
-       gRhine2_DriverInfo.RootNode.Size = giRhine2_CardCount;
-       DevFS_AddDevice( &gRhine2_DriverInfo );
-       
        return MODULE_ERR_OK;
 }
 
-// --- Root Functions ---
-char *Rhine2_ReadDir(tVFS_Node *Node, int Pos)
+void Rhine2_int_InitialiseCard(tCard *Card)
 {
-       if( Pos < 0 || Pos >= giRhine2_CardCount )      return NULL;
+       tPAddr  phys;
        
-       return strdup( gaRhine2_Cards[Pos].Name );
-}
+       Card->MacAddr[0] = inb(Card->IOBase + REG_PAR0);
+       Card->MacAddr[1] = inb(Card->IOBase + REG_PAR1);
+       Card->MacAddr[2] = inb(Card->IOBase + REG_PAR2);
+       Card->MacAddr[3] = inb(Card->IOBase + REG_PAR3);
+       Card->MacAddr[4] = inb(Card->IOBase + REG_PAR4);
+       Card->MacAddr[5] = inb(Card->IOBase + REG_PAR5);
 
-tVFS_Node *Rhine2_FindDir(tVFS_Node *Node, const char *Filename)
-{
-       //TODO: It might be an idea to supprt >10 cards
-       if(Filename[0] == '\0' || Filename[1] != '\0')  return NULL;
-       if(Filename[0] < '0' || Filename[0] > '9')      return NULL;
-       return &gaRhine2_Cards[ Filename[0]-'0' ].Node;
-}
+       LOG("Resetting card");  
+       outb(Card->IOBase + REG_CR1, CR1_SFRST);
+       // TODO: Timeout
+       while( inb(Card->IOBase + REG_CR1) & CR1_SFRST ) ;
+       
+       LOG("Allocaating RX buffers");
+       // Allocate memory for things
+       for( int i = 0; i < N_RX_BUF_PAGES; i ++ )
+       {
+               Card->RXBuffers[i].Virt = (void*)MM_AllocDMA(1, 32, &phys);
+               Card->RXBuffers[i].Phys = phys;
+       }
+       
+       LOG("Allocating and filling RX/TX Descriptors");
+       Card->DescTable = (void*)MM_AllocDMA(1, 32, &phys);
+       Card->DescTablePhys = phys;
 
-const char *csaRhine2_RootIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Data)
-{
-       ENTER("pNode iID pData", Node, ID, Data);
-       switch(ID)
+       // Initialise RX Descriptors
+       struct sRXDesc  *rxdescs = Card->DescTable;
+       for( int i = 0; i < N_RX_DESCS; i ++ )
        {
-       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_RootIOCtls);
+               rxdescs[i].RSR = 0;
+               rxdescs[i].BufferSize = RX_BUF_SIZE;
+               rxdescs[i].RXBufferStart = Card->RXBuffers[i/N_RX_BUF_PER_PAGE].Phys
+                       + (i % N_RX_BUF_PER_PAGE) * RX_BUF_SIZE;
+               rxdescs[i].RDBranchAddress = Card->DescTablePhys + (i+1) * DESC_SIZE;
+               rxdescs[i].Length = (1 << 15);  // set OWN
+               LOG("RX Desc %p = {Buf:0x%8x, Next:0x%x}", rxdescs,
+                       rxdescs[i].RXBufferStart, rxdescs[i].RDBranchAddress
+                       );
        }
-       LEAVE('i', 0);
-       return 0;
+       rxdescs[ N_RX_DESCS - 1 ].RDBranchAddress = Card->DescTablePhys;
+       Card->NextRX = &rxdescs[0];
+
+       Card->TXDescs = (void*)(rxdescs + N_RX_DESCS);
+       memset(Card->TXDescs, 0, sizeof(struct sTXDesc)*N_TX_DESCS);
+       for( int i = 0; i < N_TX_DESCS; i ++ )
+       {
+               Card->TXDescs[i].TDBranchAddress = Card->DescTablePhys + (N_RX_DESCS + i + 1) * DESC_SIZE;
+       }
+       Card->TXDescs[N_TX_DESCS-1].TDBranchAddress = Card->DescTablePhys + N_RX_DESCS * DESC_SIZE;
+       Card->nFreeTX = N_TX_DESCS;
+       Card->NextTX = 0;
+       
+       // - Initialise card state
+       LOG("Initialising card state");
+       outb(Card->IOBase + REG_IMR0, 0xFF);
+       outb(Card->IOBase + REG_IMR1, 0xFF);
+       outd(Card->IOBase + REG_CUR_RX_DESC, Card->DescTablePhys);
+       outd(Card->IOBase + REG_CUR_TX_DESC, Card->DescTablePhys + N_RX_DESCS * DESC_SIZE);
+
+       outb(Card->IOBase + REG_TCR, TCR_TRSF(4));
+       
+       LOG("RX started");
+       outb(Card->IOBase + REG_CR0, CR0_BASEVAL);
+       outb(Card->IOBase + REG_CR1, 0);        // Disabled TX polling only?
+       
+       LOG("ISR state: %02x %02x", inb(Card->IOBase + REG_ISR0), inb(Card->IOBase + REG_ISR1));
 }
 
 // --- File Functions ---
-Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+tIPStackBuffer *Rhine2_WaitPacket(void *Ptr)
 {
-       #if 0
-       tCard   *card = Node->ImplPtr;
-       Uint16  read_ofs, pkt_length;
-        int    new_read_ofs;
-
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       tCard   *card = Ptr;
+       tIPStackBuffer  *ret;
+       struct sRXDesc  *desc;
+        int    nDesc;
+       
+       ENTER("pPtr", Ptr);
 
-retry:
+       LOG("CR0 state: %02x", inb(card->IOBase + REG_CR0));
        if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
        {
-               LEAVE_RET('i', 0);
+               LEAVE('n');
+               return NULL;
        }
        
-       Mutex_Acquire( &card->ReadMutex );
+       nDesc = 0;
+       desc = card->NextRX;
+       while( !(desc->Length & (1 << 15)) )
+       {
+//             LOG("desc(%p) = {RSR:%04x,Length:%04x,BufferSize:%04x,RXBufferStart:%08x,RDBranchAddress:%08x}",
+//                     desc, desc->RSR, desc->Length, desc->BufferSize, desc->RXBufferStart, desc->RDBranchAddress);
+               // TODO: This kinda expensive call can be changed for an increment, but cbf
+               desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
+               nDesc ++;
+       }
+
+       LOG("%i descriptors in packet", nDesc);
+
+       ret = IPStack_Buffer_CreateBuffer(nDesc);
+       desc = card->NextRX;
+       while( !(desc->Length & (1 << 15)) )
+       {
+               void    *data = Rhine2_int_GetBufferFromPhys(card, desc->RXBufferStart);
+               IPStack_Buffer_AppendSubBuffer(ret,
+                       desc->Length, 0, data,
+                       Rhine2_int_FreeRXDesc, desc
+                       );
+               desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
+       }       
+       card->NextRX = desc;
+
+       LEAVE('p', ret);
+       return ret;
+}
+
+int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
+{
+       tCard   *card = Ptr;
+       size_t  len;
+       const void      *data;
+        int    nDescs, first_desc_id;
+       struct sTXDesc  *desc = NULL;
+       struct sTXDesc  *first_desc = NULL;
+       struct sTXDesc  *last_desc = NULL;
+
+       ENTER("pPtr pBuffer", Ptr, Buffer);     
+
+       #if 0
+       // Iterate buffers
+       nDescs = 0;
+       for( int id = -1; -1 != (id = IPStack_Buffer_GetBuffer(Buffer, id, &len, &data)); )
+       {
+               if( ((tVAddr)data & (PAGE_SIZE-1)) + len > PAGE_SIZE )
+                       nDescs ++;
+               nDescs ++;
+       }
+       if( nDescs == 0 ) {
+               LEAVE('i', -1);
+               return -1;
+       }
+
+       LOG("%i descriptors needed", nDescs);
        
-       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);
+       if( card->nFreeTX < nDescs ) {
+               // Oops... wait?
+               // TODO: Semaphore instead?
+               LEAVE('i', 1);
+               return 1;
+       }
+
+       first_desc_id = card->NextTX;
+       card->NextTX = (card->NextTX + nDescs) % N_TX_DESCS;
+
+       desc = card->TXDescs + first_desc_id;
        
-       pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
+       nDescs = 0;
+       for( int id = -1; -1 != (id = IPStack_Buffer_GetBuffer(Buffer, id, &len, &data)); )
+       {
+               tPAddr  pdata = MM_GetPhysAddr( (tVAddr)data );
+               #if PHYS_BITS > 32
+               if( pdata >> 32 ) {
+                       // TODO: re-map
+                       Log_Warning("Rhine2", "TODO: Bounce-buffer >32 pbit buffers");
+               } 
+               #endif
        
-       // 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) {
-               LOG("wrapping read_ofs");
-               new_read_ofs -= card->ReceiveBufferLength;
-       }
-       new_read_ofs -= 0x10;   // I dunno
-       LOG("new_read_ofs = %i", new_read_ofs);
+               if( (pdata & (PAGE_SIZE-1)) + len > PAGE_SIZE )
+               {
+                       // Need to split into to descriptors
+                       Log_Warning("Rhine2", "TODO: Split cross-page buffers");
+               }
+               
+               LOG("Buffer %i (%p+0x%x) placed in %p", id-1, data, len, desc);
+
+               // TODO: Rhine I requires 4-byte alignment (fsck that, I don't have one)
        
-       // Check for errors
-       if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E ) {
-               // Update CAPR
-               outw(card->IOBase + CAPR, new_read_ofs);
-               Mutex_Release( &card->ReadMutex );
-               goto retry;     // I feel evil
+               desc->TXBufferStart = pdata;
+               desc->BufferSize = len | (1 << 15);
+               // TODO: TCR
+               desc->TCR = 0;
+               if( nDescs == 0 )
+                       desc->TSR = 0;  // OWN will be set below
+               else
+                       desc->TSR = TD_TSR_OWN;
+
+               nDescs ++;
+               if(first_desc_id + nDescs == N_TX_DESCS)
+                       desc = card->TXDescs;
+               else
+                       desc ++;
        }
+       #else
+       data = IPStack_Buffer_CompactBuffer(Buffer, &len);
        
-       // Get packet
-       if( Length > pkt_length )       Length = pkt_length;
-       memcpy(Buffer, &card->ReceiveBuffer[read_ofs+4], Length);
+       nDescs = 1;
+       first_desc_id = card->NextTX;
+       card->NextTX = (card->NextTX + nDescs) % N_TX_DESCS;
+       desc = card->TXDescs + first_desc_id;
        
-       // Update CAPR
-       outw(card->IOBase + CAPR, new_read_ofs);
+       desc->TXBufferStart = MM_GetPhysAddr( data );
+       desc->BufferSize = len | (1 << 15);
+       desc->TSR = 0;
+       desc->TCR = 0;
+       #endif
        
-       Mutex_Release( &card->ReadMutex );
+       first_desc = card->TXDescs + first_desc_id;
+       last_desc = desc;
        
-       LEAVE('i', Length);
+       first_desc->TCR |= TD_TCR_STP;
+       last_desc->TCR |= TD_TCR_EDP|TD_TCR_IC;
+//     last_desc->BufferSize &= ~(1 << 15);
+
+       first_desc->TSR |= TD_TSR_OWN;
+
+       LOG("%i descriptors allocated, first = %p, last = %p", nDescs, first_desc, last_desc);
+
+
+       LOG("Waiting for TX to complete");
+       outb(card->IOBase + REG_CR0, CR0_TDMD|CR0_BASEVAL);
+       Semaphore_Wait(&card->SendSemaphore, 1);
+
+       #if 1
+       free((void*)data);
        #endif
-       
-       return Length;
+
+       LEAVE('i', 0);
+       return 0;
 }
 
-Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+void Rhine2_IRQHandler(int Num, void *Ptr)
 {
-       #if 0
-        int    td;
-       Uint32  status;
-       tCard   *card = Node->ImplPtr;
-       
-       if( Length > 1500 )     return 0;       // MTU exceeded
-       
-       ENTER("pNode XLength pBuffer", Node, Length, Buffer);
-       
-       // TODO: Implement a semaphore for avaliable transmit buffers
-
-       // Find an avaliable descriptor
-       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);
+       tCard   *card = Ptr;
+       Uint8   isr0 = inb(card->IOBase + REG_ISR0);
+       Uint8   isr1 = inb(card->IOBase + REG_ISR1);
+
+       if( isr0 == 0 ) return ;        
+
+       LOG("ISR0 = 0x%02x, ISR1 = 0x%02x", isr0, isr1);
+
+       if( isr0 & ISR0_PRX )
+       {
+               LOG("PRX");
+               Semaphore_Signal(&card->ReadSemaphore, 1);
+       }
        
-       // Transmit using descriptor `td`
-       LOG("card->PhysTransmitBuffers[td] = %P", card->PhysTransmitBuffers[td]);
-       outd(card->IOBase + TSAD0 + td*4, card->PhysTransmitBuffers[td]);
-       LOG("card->TransmitBuffers[td] = %p", card->TransmitBuffers[td]);
-       // Copy to buffer
-       memcpy(card->TransmitBuffers[td], Buffer, Length);
-       // Start
-       status = 0;
-       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)
-       LOG("status = 0x%08x", status);
-       outd(card->IOBase + TSD0 + td*4, status);
+       if( isr0 & ISR0_PTX )
+       {
+               LOG("PTX");
+               Semaphore_Signal(&card->SendSemaphore, 1);
+       }
        
-       LEAVE('i', (int)Length);
-       #endif
+       if( isr0 & ISR0_TXE )
+       {
+               LOG("TX Error... oops");
+               Semaphore_Signal(&card->SendSemaphore, 1);
+       }
        
-       return Length;
+       if( isr0 & ISR0_TU )
+       {
+               LOG("Transmit buffer underflow");
+       }
+
+       LOG("Acking interrupts");
+       outb(card->IOBase + REG_ISR0, isr0);
+       outb(card->IOBase + REG_ISR1, isr1);
 }
 
-const char *csaRhine2_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Data)
+// --- Helpers ---
+struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr)
 {
-       tCard   *card = Node->ImplPtr;
-       ENTER("pNode iID pData", Node, ID, Data);
-       switch(ID)
+       if( Card->DescTablePhys > Addr )        return NULL;
+       if( Card->DescTablePhys + PAGE_SIZE <= Addr )   return NULL;
+       if( Addr & 15 ) return NULL;
+       return (struct sRXDesc*)Card->DescTable + ((Addr & (PAGE_SIZE-1)) / 16);
+}
+
+void *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr)
+{
+       for( int i = 0; i < N_RX_BUF_PAGES; i ++ )
        {
-       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_NodeIOCtls);
-       case NET_IOCTL_GETMAC:
-               if( !CheckMem(Data, 6) ) {
-                       LEAVE('i', -1);
-                       return -1;
-               }
-               memcpy( Data, card->MacAddr, 6 );
-               LEAVE('i', 1);
-               return 1;
+               if( Card->RXBuffers[i].Phys > Addr )    continue;
+               if( Card->RXBuffers[i].Phys + PAGE_SIZE <= Addr )       continue;
+               return Card->RXBuffers[i].Virt + (Addr & (PAGE_SIZE-1));
        }
-       LEAVE('i', 0);
-       return 0;
+       return NULL;
 }
 
-void Rhine2_IRQHandler(int Num)
+void Rhine2_int_FreeRXDesc(void *Ptr, size_t u1, size_t u2, const void *u3)
 {
-       #if 0
-        int    i, j;
-       tCard   *card;
-       Uint16  status;
+       struct sRXDesc  *desc = Ptr;
 
-       LOG("Num = %i", Num);
+       LOG("Descriptor %p returned to card", desc);
        
-       for( i = 0; i < giRhine2_CardCount; i ++ )
-       {
-               card = &gaRhine2_Cards[i];
-               if( Num != card->IRQ )  break;
-               
-               status = inw(card->IOBase + ISR);
-               LOG("status = 0x%02x", status);
-               
-               // Transmit OK, a transmit descriptor is now free
-               if( status & FLAG_ISR_TOK )
-               {
-                       for( j = 0; j < 4; j ++ )
-                       {
-                               if( ind(card->IOBase + TSD0 + j*4) & 0x8000 ) { // TSD TOK
-                                       Mutex_Release( &card->TransmitInUse[j] );
-                                       // TODO: Update semaphore once implemented
-                               }
-                       }
-                       outw(card->IOBase + ISR, FLAG_ISR_TOK);
-               }
-               
-               // Recieve OK, inform read
-               if( status & FLAG_ISR_ROK )
-               {
-                        int    read_ofs, end_ofs;
-                        int    packet_count = 0;
-                        int    len;
-                       
-                       // Scan recieve buffer for packets
-                       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 ++;
-                                       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],
-                                               len
-                                               );
-                                       if(len > 2000) {
-                                               Log_Warning("PCnet3", "IRQ: Packet in buffer exceeds sanity (%i>2000)", len);
-                                       }
-                                       read_ofs += len + 4;
-                                       read_ofs = (read_ofs + 3) & ~3; // Align
-                               }
-                               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]
-                                       );
-                               read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4;
-                               read_ofs = (read_ofs + 3) & ~3; // Align
-                       }
-                       if( read_ofs != end_ofs ) {
-                               Log_Warning("PCnet3", "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);
-                       
-                       if( packet_count )
-                       {
-                               if( Semaphore_Signal( &card->ReadSemaphore, packet_count ) != packet_count ) {
-                                       // Oops?
-                               }
-                               VFS_MarkAvaliable( &card->Node, 1 );
-                       }
-                       
-                       outw(card->IOBase + ISR, FLAG_ISR_ROK);
-               }
-       }
-       #endif
+       desc->RSR = 0;
+       desc->Length = (1 << 15);       // Reset OWN
 }
+

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