From 0fea0b04ca1c979de681b237d7952126db3e2471 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 13 May 2012 21:42:14 +0800 Subject: [PATCH] Modules/VIARhineII - Implementing, won't work yet --- .../Modules/Network/VIARhineII/rhine2.c | 371 ++++++------------ .../Modules/Network/VIARhineII/rhine2_hw.h | 5 + 2 files changed, 133 insertions(+), 243 deletions(-) diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2.c b/KernelLand/Modules/Network/VIARhineII/rhine2.c index d27c5eb9..d8bbf887 100644 --- a/KernelLand/Modules/Network/VIARhineII/rhine2.c +++ b/KernelLand/Modules/Network/VIARhineII/rhine2.c @@ -6,11 +6,10 @@ #define VERSION ((0<<8)|10) #include #include -#include #include -#include #include #include "rhine2_hw.h" +#include // === CONSTANTS === #define VENDOR_ID 0x1106 @@ -22,41 +21,43 @@ typedef struct sCard Uint16 IOBase; Uint8 IRQ; - int NumWaitingPackets; + tSemaphore ReadSemaphore; - Uint32 DescTablePAddr; + Uint32 RXBuffersPhys; + void *RXBuffers; + + Uint32 DescTablePhys; void *DescTable; - char Name[2]; - tVFS_Node Node; + struct sTXDesc *FirstTX; + struct sTXDesc *LastTX; // Most recent unsent packet + + struct sRXDesc *FirstRX; // Most recent unread packet + struct sRXDesc *LastRX; // End of RX descriptor queue + + 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); +tIPStackBuffer *Rhine2_WaitPacket(void *Ptr); + int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer); void Rhine2_IRQHandler(int Num); +// --- 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); -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; @@ -91,7 +92,7 @@ int Rhine2_Install(char **Options) LOG("BAR5 = 0x%08x", PCI_GetBAR(id, 5)); // card->IOBase = base; -// card->IRQ = PCI_GetIRQ( id ); + card->IRQ = PCI_GetIRQ( id ); // Install IRQ Handler // IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler); @@ -107,253 +108,137 @@ int Rhine2_Install(char **Options) 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) +// --- File Functions --- +tIPStackBuffer *Rhine2_WaitPacket(void *Ptr) { - if( Pos < 0 || Pos >= giRhine2_CardCount ) return NULL; + tCard *card = Ptr; + tIPStackBuffer *ret; + struct sRXDesc *desc; + int nDesc; - return strdup( gaRhine2_Cards[Pos].Name ); -} + ENTER("pPtr", Ptr); -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; -} - -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) + if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 ) { - BASE_IOCTLS(DRV_TYPE_NETWORK, "Rhine2", VERSION, csaRhine2_RootIOCtls); + LEAVE('n'); + return NULL; } - LEAVE('i', 0); - return 0; + + nDesc = 0; + desc = card->FirstRX; + while( desc->BufferSize & (1 << 15) ) + { + desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress); + nDesc ++; + } + + LOG("%i descriptors in packet", nDesc); + + ret = IPStack_Buffer_CreateBuffer(nDesc); + desc = card->FirstRX; + while( desc->BufferSize & (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->FirstRX = desc; + + LEAVE('p', ret); + return ret; } -// --- File Functions --- -Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer) { - #if 0 - tCard *card = Node->ImplPtr; - Uint16 read_ofs, pkt_length; - int new_read_ofs; + tCard *card = Ptr; + size_t len; + const void *data; + struct sTXDesc *first_desc = NULL; + struct sTXDesc *last_desc = NULL; - ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + ENTER("pPtr pBuffer", Ptr, Buffer); -retry: - if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 ) + // Iterate buffers + for( int id = -1; -1 != (id = IPStack_Buffer_GetBuffer(Buffer, id, &len, &data)); ) { - LEAVE_RET('i', 0); + tPAddr pdata = MM_GetPhysAddr( (tVAddr)data ); + struct sTXDesc *desc; + #if PHYS_BITS > 32 + if( pdata >> 32 ) { + // TODO: re-map + } + #endif + + desc = Rhine2_int_AllocTXDesc(card); + if(!last_desc) + first_desc = desc; + else + last_desc->TDBranchAddress = MM_GetPhysAddr( (tVAddr)desc ); + + desc->TXBufferStart = pdata; + desc->BufferSize = len; + // TODO: TCR + desc->TCR = 0; + desc->TDBranchAddress = 0; + + last_desc = desc; } - Mutex_Acquire( &card->ReadMutex ); - - 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); - - pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2]; - - // 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; + if( !first_desc ) { + LEAVE('i', -1); + return -1; } - new_read_ofs -= 0x10; // I dunno - LOG("new_read_ofs = %i", new_read_ofs); - - // 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 + + first_desc->TCR |= TD_TCR_STP; + last_desc->TCR |= TD_TCR_EDP; + + if( card->LastTX ) + card->LastTX->TDBranchAddress = MM_GetPhysAddr( (tVAddr)first_desc ); + else { + card->FirstTX = first_desc; + card->LastTX = first_desc; + _WriteDWord(card, REG_CUR_TX_DESC, MM_GetPhysAddr( (tVAddr)first_desc )); } - // Get packet - if( Length > pkt_length ) Length = pkt_length; - memcpy(Buffer, &card->ReceiveBuffer[read_ofs+4], Length); - - // Update CAPR - outw(card->IOBase + CAPR, new_read_ofs); - - Mutex_Release( &card->ReadMutex ); - - LEAVE('i', Length); - #endif - - return Length; + // TODO: Wait until the packet has sent, then clean up + + return 0; } -Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +void Rhine2_IRQHandler(int Num) { - #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); - - // 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); - - LEAVE('i', (int)Length); - #endif - - return Length; +// --- Helpers --- +struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr) +{ + return NULL; } -const char *csaRhine2_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL}; -int Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Data) +void *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr) { - tCard *card = Node->ImplPtr; - ENTER("pNode iID pData", Node, ID, Data); - switch(ID) - { - BASE_IOCTLS(DRV_TYPE_NETWORK, "Rhine2", 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; - } - LEAVE('i', 0); - return 0; + return NULL; } -void Rhine2_IRQHandler(int Num) +void Rhine2_int_FreeRXDesc(void *Desc, size_t u1, size_t u2, const void *u3) { - #if 0 - int i, j; - tCard *card; - Uint16 status; + +} + +struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card) +{ + return NULL; +} - LOG("Num = %i", Num); +// --- IO --- +void _WriteDWord(tCard *Card, int Offset, Uint32 Value) +{ - 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 } diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h b/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h index ef0d8c9a..afe9cc9e 100644 --- a/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h +++ b/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h @@ -84,5 +84,10 @@ struct sTXDesc Uint32 TDBranchAddress; // Bit 0: Disable interrupt }; +#define TD_TCR_CRC (1 << 0) // Disable CRC generation +#define TD_TCR_STP (1 << 5) // First descriptor in packet +#define TD_TCR_EDP (1 << 6) // Last descriptor in packet +#define TD_TCR_IC (1 << 7) // Interrupt when transmitted + #endif -- 2.20.1