X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FNetwork%2FPRO100%2Fmain.c;h=d75571d339ce593462a983fb916eba835c1e96c2;hb=2cf950e5ea8ce43f45019db21b2b811cfa583e17;hp=db768445c6be390a0cab788591f0276759689394;hpb=fc261f5d8a0c8ede562802ea4aec857a257c6cb5;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Network/PRO100/main.c b/KernelLand/Modules/Network/PRO100/main.c index db768445..d75571d3 100644 --- a/KernelLand/Modules/Network/PRO100/main.c +++ b/KernelLand/Modules/Network/PRO100/main.c @@ -5,8 +5,7 @@ * main.c * - Driver core * - * Built with reference to the linux e100 driver (drivers/net/ethernet/intel/e100.c) - * 82559-fast-ethernet-multifunciton-pci-datasheet.pdf + * 8255x (Intel 8255x 10/100 Mbps Ethernet Controller Family) */ #define DEBUG 1 #include @@ -47,7 +46,7 @@ MODULE_DEFINE(0, 0x100, PRO100, PRO100_Install, PRO100_Cleanup, "IPStack", NULL) tIPStack_AdapterType gPRO100_AdapterType = { .Name = "PRO/100", .Type = ADAPTERTYPE_ETHERNET_100M, - .Flags = 0, + .Flags = ADAPTERFLAG_OFFLOAD_MAC, .SendPacket = PRO100_SendPacket, .WaitForPacket = PRO100_WaitForPacket }; @@ -122,16 +121,20 @@ int PRO100_InitCard(tCard *Card) tCommandUnit *cu = &Card->TXCommands[i].Desc.CU; cu->Status = 0; cu->Command = CMD_Nop|CMD_Suspend; - cu->Link = MM_GetPhysAddr(&Card->TXCommands[(i+1)%NUM_TX]) - txbase; + cu->Link = MM_GetPhysAddr(&Card->TXCommands[(i+1)%NUM_TX]); } - _Write32(Card, REG_GenPtr, txbase); + _Write32(Card, REG_GenPtr, 0); + _FlushWait(Card, 4); _Write16(Card, REG_Command, CU_CMD_BASE); + _FlushWait(Card, 4); // Ensure CU is in suspend before we attempt sending Card->LastTXIndex = 1; Card->CurTXIndex = 1; - _Write32(Card, REG_GenPtr, 0); + _Write32(Card, REG_GenPtr, txbase); + _FlushWait(Card, 4); _Write16(Card, REG_Command, CU_CMD_START); + _FlushWait(Card, 4); // Create RX Descriptors for( int i = 0; i < NUM_RX; i += 2 ) @@ -147,6 +150,7 @@ int PRO100_InitCard(tCard *Card) rx->CU.Command = 0; // Link is populated later rx->Size = RX_BUF_SIZE; + rx->Count = 0; // clears bit 14 rx->RXBufAddr = 0; // unused? } } @@ -156,17 +160,21 @@ int PRO100_InitCard(tCard *Card) for( int i = 0; i < NUM_RX-1; i ++ ) { tRXBuffer *rx = Card->RXBufs[i]; - rx->CU.Link = MM_GetPhysAddr(Card->RXBufs[i+1]) - rx_desc_phys; + rx->CU.Link = MM_GetPhysAddr(Card->RXBufs[i+1]); } Card->RXBufs[NUM_RX-1]->CU.Command = CMD_Suspend; Card->RXBufs[NUM_RX-1]->CU.Link = 0; // link = 0, loop back // Set RX Buffer base - _Write32(Card, REG_GenPtr, rx_desc_phys); + _Write32(Card, REG_GenPtr, 0); + _FlushWait(Card, 4); _Write16(Card, REG_Command, RX_CMD_ADDR_LOAD); + _FlushWait(Card, 4); - _Write32(Card, REG_GenPtr, 0); + _Write32(Card, REG_GenPtr, rx_desc_phys); + _FlushWait(Card, 4); _Write16(Card, REG_Command, RX_CMD_START); + _FlushWait(Card, 4); return 0; } @@ -189,29 +197,36 @@ void PRO100_ReleaseRXBuf(void *Arg, size_t HeadLen, size_t FootLen, const void * tRXBuffer *prev = Card->RXBufs[ (idx-1+NUM_RX)%NUM_RX ]; buf->CU.Status = 0; buf->CU.Command = 0; + buf->Count = 0; prev->CU.Command &= ~CMD_Suspend; // Resume _Write16(Card, REG_Command, RX_CMD_RESUME); + _FlushWait(Card, 4); } tIPStackBuffer *PRO100_WaitForPacket(void *Ptr) { tCard *Card = Ptr; + // Wait for a packet do { Semaphore_Wait(&Card->RXSemaphore, 1); } while( Card->RXBufs[Card->CurRXIndex]->CU.Status == 0 ); // Mark previous buffer as suspend (stops the RX unit running into old packets Card->RXBufs[ (Card->CurRXIndex-1+NUM_RX)%NUM_RX ]->CU.Command |= CMD_Suspend; - tRXBuffer *buf = Card->RXBufs[Card->CurRXIndex++]; + tRXBuffer *buf = Card->RXBufs[Card->CurRXIndex]; + Card->CurRXIndex = (Card->CurRXIndex+1) % NUM_RX; // Return packet (freed in PRO100_ReleaseRXBuf); tIPStackBuffer *ret = IPStack_Buffer_CreateBuffer(1); + size_t bytes = buf->Count & 0x3FFF; // - actual data is just after the descriptor - IPStack_Buffer_AppendSubBuffer(ret, buf->Count, 0, buf+1, PRO100_ReleaseRXBuf, Card); - + IPStack_Buffer_AppendSubBuffer(ret, bytes, 0, buf+1, PRO100_ReleaseRXBuf, Card); + + LOG("RX'd 0x%x bytes", bytes); + return ret; } @@ -277,23 +292,29 @@ int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer) Card->TXBuffers[txc_idx] = Buffer; // Mark as usable txc->Desc.TBDArrayAddr = 0xFFFFFFFF; - txc->Desc.TCBBytes = total_size; - txc->Desc.TXThreshold = 0; // TODO: What does this do on RHW? + txc->Desc.TCBBytes = total_size | (1 << 15); + txc->Desc.TXThreshold = 3; // Start transmitting after 3*8 bytes txc->Desc.TBDCount = 0; txc->Desc.CU.Command = CMD_Suspend|CMD_Tx; + txc->Desc.CU.Status = 0; + IPStack_Buffer_LockBuffer(Buffer); // - Mark previous as not suspended Card->TXCommands[ (txc_idx-1+NUM_TX) % NUM_TX ].Desc.CU.Command &= ~CMD_Suspend; - IPStack_Buffer_LockBuffer(Buffer); + LOG("Starting send on txc_idx=%i", txc_idx); + LOG("- REG_Status = %x", _Read8(Card, REG_Status)); // And dispatch // - If currently running or idle, this should not matter // NOTE: Qemu describes this behavior as 'broken' _Write16(Card, REG_Command, CU_CMD_RESUME); + _FlushWait(Card, 4); IPStack_Buffer_LockBuffer(Buffer); IPStack_Buffer_UnlockBuffer(Buffer); + LOG("- CU Status = 0x%x", txc->Desc.CU.Status); + return 0; } @@ -304,17 +325,28 @@ void PRO100_IRQHandler(int Num, void *Ptr) if( !status ) return ; - _Write8(Card, REG_Ack, status); LOG("status = %x", status); - if( status & ISR_FR ) { - LOG("FR"); - Semaphore_Signal(&Card->RXSemaphore, 1); + + if( status & ISR_FCP ) { + LOG("FCP - Flow Control Pause"); + } + if( status & ISR_ER ) { + LOG("ER - Early Receive"); + } + if( status & ISR_SWI ) { + LOG("SWI - Software interrupt"); + } + if( status & ISR_MDI ) { + LOG("MDI - Management Data Interface"); + } + + if( status & ISR_RNR ) { + LOG("RNR - Recieve not ready"); } - - // CU Idle if( status & ISR_CNA ) { + LOG("CNA - Command unit Not Active"); // Chase the next command buffer while( Card->LastTXIndex != Card->CurTXIndex ) { @@ -327,6 +359,14 @@ void PRO100_IRQHandler(int Num, void *Ptr) } LOG("CU Idle (%i / %i)", Card->LastTXIndex, Card->CurTXIndex); } + if( status & ISR_FR ) { + LOG("FR - Frame recieved"); + Semaphore_Signal(&Card->RXSemaphore, 1); + LOG("- RX signaled"); + } + if( status & ISR_CX ) { + LOG("CX - Command executed"); + } } Uint16 PRO100_int_ReadEEPROM(tCard *Card, Uint8 *addr_len, size_t Ofs)