From c8f8642db99f495f7baa098ba0169848bc411124 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Fri, 9 Aug 2013 17:21:22 +0800 Subject: [PATCH] Modules/PRO100 - Implimenting, still untested --- BuildConf/x86/default.mk | 3 +- KernelLand/Kernel/include/acess.h | 2 + KernelLand/Modules/Network/PRO100/Makefile | 9 ++ KernelLand/Modules/Network/PRO100/main.c | 110 ++++++++++++---- KernelLand/Modules/Network/PRO100/pro100.h | 68 +++------- KernelLand/Modules/Network/PRO100/pro100_hw.h | 119 ++++++++++++++++++ 6 files changed, 235 insertions(+), 76 deletions(-) create mode 100644 KernelLand/Modules/Network/PRO100/Makefile create mode 100644 KernelLand/Modules/Network/PRO100/pro100_hw.h diff --git a/BuildConf/x86/default.mk b/BuildConf/x86/default.mk index f0f8dc7d..6a720854 100644 --- a/BuildConf/x86/default.mk +++ b/BuildConf/x86/default.mk @@ -1,4 +1,5 @@ +MODULES += Input/PS2KbMouse MODULES += Storage/ATA MODULES += Storage/AHCI MODULES += Storage/FDDv2 @@ -6,10 +7,10 @@ MODULES += Network/NE2000 Network/RTL8139 MODULES += Network/VIARhineII MODULES += Network/PCnetFAST3 MODULES += Network/E1000 +MODULES += Network/PRO100 MODULES += Display/VESA MODULES += Display/BochsGA #MODULES += Display/VIAVideo -MODULES += Input/PS2KbMouse MODULES += x86/ISADMA x86/VGAText MODULES += USB/Core diff --git a/KernelLand/Kernel/include/acess.h b/KernelLand/Kernel/include/acess.h index d5b96b24..8c5e454a 100644 --- a/KernelLand/Kernel/include/acess.h +++ b/KernelLand/Kernel/include/acess.h @@ -22,6 +22,8 @@ #define DEPRECATED __attribute__((deprecated)) //! Mark a parameter as unused #define UNUSED(x) UNUSED_##x __attribute__((unused)) +//! +#define ALIGN(x) __attribute__((aligned(x))) /** * \name Boolean constants diff --git a/KernelLand/Modules/Network/PRO100/Makefile b/KernelLand/Modules/Network/PRO100/Makefile new file mode 100644 index 00000000..826b5055 --- /dev/null +++ b/KernelLand/Modules/Network/PRO100/Makefile @@ -0,0 +1,9 @@ +# +# + +OBJ = main.o +NAME = PRO100 + +-include ../Makefile.tpl + + diff --git a/KernelLand/Modules/Network/PRO100/main.c b/KernelLand/Modules/Network/PRO100/main.c index d5dc161d..13ef2167 100644 --- a/KernelLand/Modules/Network/PRO100/main.c +++ b/KernelLand/Modules/Network/PRO100/main.c @@ -9,10 +9,14 @@ * 82559-fast-ethernet-multifunciton-pci-datasheet.pdf */ #include -#include +#include #include +#include +#include +#include "pro100.h" // === CONSTANTS === +#define NUM_STATIC_CARDS 2 const Uint16 caSupportedCards[][2] = { {0x8086, 0x103D}, }; @@ -21,57 +25,98 @@ const int ciNumSupportedCards = sizeof(caSupportedCards)/sizeof(caSupportedCards // === PROTOTYPES === int PRO100_Install(char **Arguments); int PRO100_InitCard(tCard *Card); -void PRO100_Cleanup(void); + int PRO100_Cleanup(void); tIPStackBuffer *PRO100_WaitForPacket(void *Ptr); int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer); void PRO100_IRQHandler(int Num, void *Ptr); -size_t PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs, size_t Len, void *Buffer); +Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs); + +static void _Write16(tCard *Card, int Ofs, Uint16 Val); +static void _Write32(tCard *Card, int Ofs, Uint32 Val); +static Uint16 _Read16(tCard *Card, int Ofs); +static Uint32 _Read32(tCard *Card, int Ofs); +static void _FlushWait(tCard *Card, int Delay); + // === GLOBALS === -MODULE_DEFINE(0, PRO100, PRO100_Install, PRO100_Cleanup, "IPStack", NULL); +MODULE_DEFINE(0, 0x100, PRO100, PRO100_Install, PRO100_Cleanup, "IPStack", NULL); tIPStack_AdapterType gPRO100_AdapterType = { .Name = "PRO/100", .Type = ADAPTERTYPE_ETHERNET_100M, .Flags = 0, .SendPacket = PRO100_SendPacket, .WaitForPacket = PRO100_WaitForPacket - }; +tCard gaPRO100_StaticCards[NUM_STATIC_CARDS]; // === CODE === int PRO100_Install(char **Arguments) { + int cardidx = 0; + for( int i = 0; i < ciNumSupportedCards; i ++ ) + { + const Uint16 *ven_dev = caSupportedCards[i]; + int pciid = -1; + while( -1 != (pciid = PCI_GetDevice(ven_dev[0], ven_dev[1], pciid)) ) + { + Uint32 base = PCI_GetValidBAR(pciid, 0, PCI_BARTYPE_MEM32); + tCard *card; + if( cardidx < NUM_STATIC_CARDS ) { + card = &gaPRO100_StaticCards[cardidx++]; + } + else { + card = malloc(sizeof(tCard)); + } + + card->MMIO = MM_MapHWPages(base, 1); + + // TODO: Error check + PRO100_InitCard(card); + + IPStack_Adapter_Add(&gPRO100_AdapterType, card, card->MAC.Bytes); + } + } return MODULE_ERR_OK; } int PRO100_InitCard(tCard *Card) { // Card reset - Card->MMIO->Port = PORT_SELECTIVERESET; - // - Write Flush, wait 20us - Card->MMIO->Port = PORT_SOFTWARERESET; - // - Write Flush, wait 20us + _Write32(Card, REG_Port, PORT_SELECTIVERESET); + _FlushWait(Card, 20); // - Write Flush, wait 20us + _Write32(Card, REG_Port, PORT_SOFTWARERESET); + _FlushWait(Card, 20); // - Write Flush, wait 20us // Read MAC address Card->MAC.Words[0] = PRO100_int_ReadEEPROM(Card, 0); Card->MAC.Words[1] = PRO100_int_ReadEEPROM(Card, 1); Card->MAC.Words[2] = PRO100_int_ReadEEPROM(Card, 2); + + // Create RX Descriptors + + // Set RX Buffer base + _Write32(Card, REG_GenPtr, rx_desc_phys); + _Write32(Card, REG_Command, RX_CMD_ADDR_LOAD); + + _Write32(Card, REG_GenPtr, 0); + _Write32(Card, REG_Command, RX_CMD_START); return 0; } -void PRO100_Cleanup(void) +int PRO100_Cleanup(void) { return 0; } -tIPStackBuffer *PRO100_WaitForPacket(void *Ptr) +tIPStackBuffer *PRO100_WaitForPacket(void *Ptr) { + return NULL; } int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer) { - + return -1; } void PRO100_IRQHandler(int Num, void *Ptr) @@ -84,18 +129,20 @@ Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs) Uint8 addr_len = 8; Uint32 addr_data = ((EEPROM_OP_READ << addr_len) | Ofs) << 16; - Card->MMIO->EEPROMCtrl = EEPROM_CTRL_CS | EEPROM_CTRL_SK; - // Flush + 4us - + _Write16( Card, REG_EEPROMCtrl, EEPROM_CTRL_CS | EEPROM_CTRL_SK ); + _FlushWait(Card, 4); // Flush + 4us + + Uint32 data = 0; + for( int i = 32; i --; ) { - Uint8 ctrl = EEPROM_CTRL_CS | ((addr_data & (1 << i)) ? EEPROM_CTRL_DI : 0); - Card->MMIO->EEPROMCtrl = ctrl; - // Flush + 4us - Card->MMIO->EEPROMCtrl = ctrl | EEPROM_CTRL_SK; - // Flush + 4us + Uint16 ctrl = EEPROM_CTRL_CS | ((addr_data & (1 << i)) ? EEPROM_CTRL_DI : 0); + _Write16( Card, REG_EEPROMCtrl, ctrl ); + _FlushWait(Card, 4); // Flush + 4us + _Write16( Card, REG_EEPROMCtrl, ctrl | EEPROM_CTRL_SK ); + _FlushWait(Card, 4); // Flush + 4us - ctrl = Card->MMIO->EEPROMCtrl; + ctrl = _Read16( Card, REG_EEPROMCtrl ); // Once the address is fully recieved, the card emits a zero bit if( !(ctrl & EEPROM_CTRL_DO) && i > 16 ) { @@ -103,12 +150,27 @@ Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs) i = 17; } - data = (data << 1) | (ctrl & EEPROM_CTRL_DO ? 1 : 0) + data = (data << 1) | (ctrl & EEPROM_CTRL_DO ? 1 : 0); } // Deslect chip - Card->MMIO->EEPROMCtrl = 0; - // Flush + 4us + _Write16( Card, REG_EEPROMCtrl, 0 ); + _FlushWait(Card, 4); // Flush + 4us return (data & 0xFFFF); } + +static void _Write16(tCard *Card, int Ofs, Uint16 Val) { outw(Card->IOBase + Ofs, Val); } +static void _Write32(tCard *Card, int Ofs, Uint32 Val) { outd(Card->IOBase + Ofs, Val); } +static Uint16 _Read16(tCard *Card, int Ofs) { return inw(Card->IOBase + Ofs); } +static Uint32 _Read32(tCard *Card, int Ofs) { return ind(Card->IOBase + Ofs); } + +static void _FlushWait(tCard *Card, int Delay) +{ + _Read16( Card, REG_Status ); + if(Delay > 0) + { + Time_MicroSleep(Delay); + } +} + diff --git a/KernelLand/Modules/Network/PRO100/pro100.h b/KernelLand/Modules/Network/PRO100/pro100.h index 9a14f7c7..2bcc7825 100644 --- a/KernelLand/Modules/Network/PRO100/pro100.h +++ b/KernelLand/Modules/Network/PRO100/pro100.h @@ -1,63 +1,29 @@ /* - + * Acess2 PRO/100 Driver + * - By John Hodge (thePowersGang) + * + * pro100.h + * - Hardware header */ #ifndef _PRO100_H_ #define _PRO100_H_ -struct sCSR -{ - Uint16 Status; - Uint16 Command; - - Uint32 GenPtr; - Uint32 Port; - - Uint16 FlashCtrl; - Uint16 EEPROMCtrl; - - Uint32 MDICtrl; - Uint32 RXDMACount; -}; - -#define STATUS_RUS_MASK 0x003C // Receive Unit Status -#define STATUS_CUS_MASK 0x00C0 // Comamnd Unit Status -#define STATUS_FCP 0x0100 // Flow Control Pause -#define STATUS_ER 0x0200 // Early Recieve -#define STATUS_SWI 0x0400 // Software Interrupt -#define STATUS_MDI 0x0800 // Management Data Interrupt -#define STATUS_RNR 0x1000 // Receive Not Ready -#define STATUS_CNA 0x2000 // Command Unit not active -#define STATUS_FR 0x4000 // Frame Recieved -#define STATUS_CX 0x8000 // Command Unit executed +#include "pro100_hw.h" -#define CMD_RUC 0x0007 -#define CMD_CUC 0x00F0 -#define CMD_M 0x0100 // Interrupt Mask -#define CMD_SI 0x0200 // Software Interrupt +typedef struct sCard tCard; -#define MDI_IE (1 << 29) -#define MDI_RDY (1 << 28) - -#define EEPROM_CTRL_SK 0x01 // -#define EEPROM_CTRL_CS 0x02 -#define EEPROM_CTRL_DI 0x04 -#define EEPROM_CTRL_DO 0x08 - -enum ePortCommands { - PORT_SOFTWARERESET = 0, - PORT_SELFTEST = 1, - PORT_SELECTIVERESET = 2, -}; - -struct sCommandBuffer +struct sCard { - Uint16 Status; - Uint16 Command; - Uint32 Link; + Uint16 IOBase; + struct sCSR *MMIO; - tIPStackBuffer *Buffer; - tCommandBuffer *Next; -} __align__(4); + union { + Uint8 Bytes[6]; + Uint16 Words[3]; // Used to read the MAC from EEPROM + } MAC; + + //tIPStackBuffer *TXBuffers[NUM_TX]; +}; #endif diff --git a/KernelLand/Modules/Network/PRO100/pro100_hw.h b/KernelLand/Modules/Network/PRO100/pro100_hw.h new file mode 100644 index 00000000..cc665c37 --- /dev/null +++ b/KernelLand/Modules/Network/PRO100/pro100_hw.h @@ -0,0 +1,119 @@ +/* + * Acess2 PRO/100 Driver + * - By John Hodge (thePowersGang) + * + * pro100_hw.h + * - Hardware header + */ +#ifndef _PRO100_HW_H_ +#define _PRO100_HW_H_ + +enum ePro100_Regs { + REG_Status, + REG_Ack, + REG_Command, + REG_IntMask, + + REG_GenPtr = 4, + REG_Port = 8, + + REG_FlashCtrl = 12, + REG_EEPROMCtrl = 14, + + REG_MDICtrl = 16, + REG_RXDMACnt = 20, +}; +struct sCSR +{ + Uint16 Status; + Uint16 Command; + + Uint32 GenPtr; + Uint32 Port; + + Uint16 FlashCtrl; + Uint16 EEPROMCtrl; + + Uint32 MDICtrl; + Uint32 RXDMACount; +}; + +#define STATUS_RUS_MASK 0x003C // Receive Unit Status +#define STATUS_CUS_MASK 0x00C0 // Comamnd Unit Status +#define STATUS_FCP 0x0100 // Flow Control Pause +#define STATUS_ER 0x0200 // Early Recieve +#define STATUS_SWI 0x0400 // Software Interrupt +#define STATUS_MDI 0x0800 // Management Data Interrupt +#define STATUS_RNR 0x1000 // Receive Not Ready +#define STATUS_CNA 0x2000 // Command Unit not active +#define STATUS_FR 0x4000 // Frame Recieved +#define STATUS_CX 0x8000 // Command Unit executed + +#define CMD_RUC 0x0007 +#define CMD_CUC 0x00F0 +#define CMD_M 0x0100 // Interrupt Mask +#define CMD_SI 0x0200 // Software Interrupt + +#define MDI_IE (1 << 29) +#define MDI_RDY (1 << 28) + +#define EEPROM_CTRL_SK 0x01 // +#define EEPROM_CTRL_CS 0x02 +#define EEPROM_CTRL_DI 0x04 +#define EEPROM_CTRL_DO 0x08 + +#define EEPROM_OP_READ 0x06 + +enum ePortCommands { + PORT_SOFTWARERESET = 0, + PORT_SELFTEST = 1, + PORT_SELECTIVERESET = 2, +}; + +enum eRXCommands { + RX_CMD_NOP, + RX_CMD_START, + RX_CMD_RESUME, + _RX_CMD_3, + RX_CMD_ABORT, + _RX_CMD_5, + RX_CMD_ADDR_LOAD, + RX_CMD_RESUMENR, +}; +enum eCUCommands { + CU_CMD_NOP = 0<<4, + CU_CMD_START = 1<<4, + CU_CMD_RESUME = 2<<4, + CU_CMD_BASE = 6<<4, +}; + +enum eCommands { + CMD_Nop, + CMD_IAddrSetup, + CMD_Configure, + CMD_MulticastList, + CMD_Tx, +}; + +typedef struct sCommandUnit +{ + Uint16 Status; + Uint16 Command; + Uint32 Link; +}; + +typedef struct sRXBuffer tRXBuffer; + +struct sRXBuffer +{ + Uint16 Status; + Uint16 Command; + Uint32 Link; // Base from RX base + + Uint32 RXBufAddr; // Unused according to qemu source + Uint16 Count; + Uint16 Size; +} ALIGN(4); + +#endif + -- 2.20.1