Modules/VIARhineII - More implementation work
authorJohn Hodge <[email protected]>
Tue, 15 May 2012 06:27:24 +0000 (14:27 +0800)
committerJohn Hodge <[email protected]>
Tue, 15 May 2012 06:27:24 +0000 (14:27 +0800)
KernelLand/Modules/Network/VIARhineII/rhine2.c
KernelLand/Modules/Network/VIARhineII/rhine2_hw.h

index d8bbf88..4a152fe 100644 (file)
@@ -2,7 +2,7 @@
  * 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 "rhine2_hw.h"
 #include <IPStack/include/adapters_api.h>
 
+#define N_RX_DESCS     16
+#define RX_BUF_SIZE    1024
+#define N_RX_PAGES     ((N_RX_DESCS*RX_BUF_SIZE)/PAGE_SIZE)
+#define N_TX_DESCS     ((PAGE_SIZE/16)-N_RX_DESCS)
+
 // === CONSTANTS ===
 #define VENDOR_ID      0x1106
 #define DEVICE_ID      0x3065
@@ -23,11 +28,15 @@ typedef struct sCard
        
        tSemaphore      ReadSemaphore;
 
-       Uint32  RXBuffersPhys;
-       void    *RXBuffers;
+       struct {
+               Uint32  Phys;
+               void    *Virt;
+       } RXBuffers[N_RX_PAGES];
 
        Uint32  DescTablePhys;
        void    *DescTable;
+
+       struct sTXDesc  *TXDescs;
        
        struct sTXDesc  *FirstTX;
        struct sTXDesc  *LastTX;        // Most recent unsent packet
@@ -41,16 +50,15 @@ typedef struct sCard
 
 // === PROTOTYPES ===
  int   Rhine2_Install(char **Options);
+void   Rhine2_int_InitialiseCard(tCard *Card);
 tIPStackBuffer *Rhine2_WaitPacket(void *Ptr);
  int   Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
-void   Rhine2_IRQHandler(int Num);
+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*);
 struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card);
-// --- IO ---
-void   _WriteDWord(tCard *Card, int Offset, Uint32 Value);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, VIARhineII, Rhine2_Install, NULL, NULL);
@@ -91,19 +99,25 @@ 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->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);
+       
+               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 ++;
        }
@@ -111,6 +125,58 @@ int Rhine2_Install(char **Options)
        return MODULE_ERR_OK;
 }
 
+void Rhine2_int_InitialiseCard(tCard *Card)
+{
+       tPAddr  phys;
+       
+       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);
+       
+       outb(Card->IOBase + REG_CR1, CR1_SFRST);
+       // TODO: Timeout
+       while( inb(Card->IOBase + REG_CR1) & CR1_SFRST ) ;
+       
+       // Allocate memory for things
+       for( int i = 0; i < N_RX_PAGES; i ++ )
+       {
+               Card->RXBuffers[i].Virt = (void*)MM_AllocDMA(1, 32, &phys);
+               Card->RXBuffers[i].Phys = phys;
+       }
+       
+       Card->DescTable = (void*)MM_AllocDMA(1, 32, &phys);
+       Card->DescTablePhys = phys;
+
+       // Initialise RX Descriptors
+       struct sRXDesc  *rxdescs = Card->DescTable;
+       for( int i = 0; i < N_RX_DESCS; i ++ )
+       {
+               rxdescs[i].RSR = 0;
+               rxdescs[i].BufferSize = RX_BUF_SIZE;
+               rxdescs[i].RXBufferStart = Card->RXBuffers[i/(PAGE_SIZE/RX_BUF_SIZE)].Phys
+                       + (i % (PAGE_SIZE/RX_BUF_SIZE)) * RX_BUF_SIZE;
+               rxdescs[i].RDBranchAddress = Card->DescTablePhys + (i+1) * sizeof(struct sRXDesc);
+               rxdescs[i].Length = (1 << 15);  // set OWN
+       }
+       rxdescs[ N_RX_DESCS - 1 ].RDBranchAddress = 0;
+       Card->FirstRX = &rxdescs[0];
+       Card->LastRX = &rxdescs[N_RX_DESCS - 1];
+
+       Card->TXDescs = (void*)(rxdescs + N_RX_DESCS);
+       memset(Card->TXDescs, 0, sizeof(struct sTXDesc)*N_TX_DESCS);
+       
+       
+       // - Initialise card state
+       outb(Card->IOBase + REG_IMR0, 0xFF);
+       outb(Card->IOBase + REG_IMR1, 0xFF);
+       outd(Card->IOBase + REG_CUR_RX_DESC, Card->DescTablePhys);
+       
+       outb(Card->IOBase + REG_CR0, CR0_STRT|CR0_RXON);
+}
+
 // --- File Functions ---
 tIPStackBuffer *Rhine2_WaitPacket(void *Ptr)
 {
@@ -185,6 +251,7 @@ int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
                desc->BufferSize = len;
                // TODO: TCR
                desc->TCR = 0;
+               desc->TSR = TD_TSR_OWN;
                desc->TDBranchAddress = 0;
 
                last_desc = desc;
@@ -203,15 +270,19 @@ int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
        else {
                card->FirstTX = first_desc;
                card->LastTX = first_desc;
-               _WriteDWord(card, REG_CUR_TX_DESC, MM_GetPhysAddr( (tVAddr)first_desc ));
+               outd(card->IOBase + REG_CUR_TX_DESC, MM_GetPhysAddr( (tVAddr)first_desc ));
        }
+
+       outb(card->IOBase + REG_CR1, CR1_TDMD);
        
        // TODO: Wait until the packet has sent, then clean up
+       while( inb(card->IOBase + REG_CR1) & CR1_TDMD )
+               ;
 
        return 0;
 }
 
-void Rhine2_IRQHandler(int Num)
+void Rhine2_IRQHandler(int Num, void *Ptr)
 {
        
 }
@@ -219,26 +290,39 @@ void Rhine2_IRQHandler(int Num)
 // --- Helpers ---
 struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr)
 {
-       return NULL;
+       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_PAGES; i ++ )
+       {
+               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));
+       }
        return NULL;
 }
 
-void Rhine2_int_FreeRXDesc(void *Desc, size_t u1, size_t u2, const void *u3)
+void Rhine2_int_FreeRXDesc(void *Ptr, size_t u1, size_t u2, const void *u3)
 {
+       struct sRXDesc  *desc = Ptr;
        
+       desc->RSR = 0;
+       desc->Length = (1 << 15);       // Reset OWN
 }
 
 struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card)
 {
+       for( int i = 0; i < N_TX_DESCS; i ++ )
+       {
+               if( Card->TXDescs[i].TSR & TD_TSR_OWN ) continue ;
+               Card->TXDescs[i].TSR = TD_TSR_OWN;
+               return &Card->TXDescs[i];
+       }
        return NULL;
 }
 
-// --- IO ---
-void _WriteDWord(tCard *Card, int Offset, Uint32 Value)
-{
-       
-}
index afe9cc9..dd3f9ac 100644 (file)
@@ -45,6 +45,24 @@ enum eRegs
 #define TCR_RSVD1      (1 << 4)        // reserved
 #define TCR_TRSF(v)    (((v)&7)<<5)    // Transmit FIFO threshold
 
+#define CR0_INIT       (1 << 0)
+#define CR0_STRT       (1 << 1)
+#define CR0_STOP       (1 << 2)
+#define CR0_RXON       (1 << 3)
+#define CR0_TXON       (1 << 4)
+#define CR0_TDMD       (1 << 5)
+#define CR0_RDMD       (1 << 6)
+#define CR0_RESV       (1 << 7)        // reserved
+
+#define CR1_EREN       (1 << 0)        // Early recieve enable
+#define CR1_RESV0      (1 << 1)
+#define CR1_FDX        (1 << 2)        // Full/Half-duplex selector
+#define CR1_DPOLL      (1 << 3)        // Disable automatic polling
+#define CR1_RESV1      (1 << 4)
+#define CR1_TDMD       (1 << 5)
+#define CR1_RDMD       (1 << 6)
+#define CR1_SFRST      (1 << 7)        // Software reset
+
 // TODO: Other Regs?
 
 struct sRXDesc
@@ -89,5 +107,7 @@ struct sTXDesc
 #define TD_TCR_EDP     (1 << 6)        // Last descriptor in packet
 #define TD_TCR_IC      (1 << 7)        // Interrupt when transmitted
 
+#define TD_TSR_OWN     (1 << 31)
+
 #endif
 

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