From 761956dfbdf60c0289a3133cab7bb939f98e70b5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 15 May 2012 14:27:24 +0800 Subject: [PATCH] Modules/VIARhineII - More implementation work --- .../Modules/Network/VIARhineII/rhine2.c | 132 ++++++++++++++---- .../Modules/Network/VIARhineII/rhine2_hw.h | 20 +++ 2 files changed, 128 insertions(+), 24 deletions(-) diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2.c b/KernelLand/Modules/Network/VIARhineII/rhine2.c index d8bbf887..4a152fef 100644 --- a/KernelLand/Modules/Network/VIARhineII/rhine2.c +++ b/KernelLand/Modules/Network/VIARhineII/rhine2.c @@ -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 #include @@ -11,6 +11,11 @@ #include "rhine2_hw.h" #include +#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) -{ - -} diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h b/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h index afe9cc9e..dd3f9ac1 100644 --- a/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h +++ b/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h @@ -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 -- 2.20.1