2 * Acess2 PRO/100 Driver
3 * - By John Hodge (thePowersGang)
8 * Built with reference to the linux e100 driver (drivers/net/ethernet/intel/e100.c)
9 * 82559-fast-ethernet-multifunciton-pci-datasheet.pdf
12 #include <IPStack/include/adapters_api.h>
19 #define NUM_STATIC_CARDS 2
20 const Uint16 caSupportedCards[][2] = {
23 const int ciNumSupportedCards = sizeof(caSupportedCards)/sizeof(caSupportedCards[0]);
26 int PRO100_Install(char **Arguments);
27 int PRO100_InitCard(tCard *Card);
28 int PRO100_Cleanup(void);
29 tIPStackBuffer *PRO100_WaitForPacket(void *Ptr);
30 int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
31 void PRO100_IRQHandler(int Num, void *Ptr);
33 Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs);
35 static void _Write16(tCard *Card, int Ofs, Uint16 Val);
36 static void _Write32(tCard *Card, int Ofs, Uint32 Val);
37 static Uint16 _Read16(tCard *Card, int Ofs);
38 static Uint32 _Read32(tCard *Card, int Ofs);
39 static void _FlushWait(tCard *Card, int Delay);
42 MODULE_DEFINE(0, 0x100, PRO100, PRO100_Install, PRO100_Cleanup, "IPStack", NULL);
43 tIPStack_AdapterType gPRO100_AdapterType = {
45 .Type = ADAPTERTYPE_ETHERNET_100M,
47 .SendPacket = PRO100_SendPacket,
48 .WaitForPacket = PRO100_WaitForPacket
50 tCard gaPRO100_StaticCards[NUM_STATIC_CARDS];
53 int PRO100_Install(char **Arguments)
56 for( int i = 0; i < ciNumSupportedCards; i ++ )
58 const Uint16 *ven_dev = caSupportedCards[i];
60 while( -1 != (pciid = PCI_GetDevice(ven_dev[0], ven_dev[1], pciid)) )
62 Uint32 base = PCI_GetValidBAR(pciid, 0, PCI_BARTYPE_MEM32);
64 if( cardidx < NUM_STATIC_CARDS ) {
65 card = &gaPRO100_StaticCards[cardidx++];
68 card = malloc(sizeof(tCard));
71 card->MMIO = MM_MapHWPages(base, 1);
74 PRO100_InitCard(card);
76 IPStack_Adapter_Add(&gPRO100_AdapterType, card, card->MAC.Bytes);
82 int PRO100_InitCard(tCard *Card)
85 _Write32(Card, REG_Port, PORT_SELECTIVERESET);
86 _FlushWait(Card, 20); // - Write Flush, wait 20us
87 _Write32(Card, REG_Port, PORT_SOFTWARERESET);
88 _FlushWait(Card, 20); // - Write Flush, wait 20us
91 Card->MAC.Words[0] = PRO100_int_ReadEEPROM(Card, 0);
92 Card->MAC.Words[1] = PRO100_int_ReadEEPROM(Card, 1);
93 Card->MAC.Words[2] = PRO100_int_ReadEEPROM(Card, 2);
95 // Create RX Descriptors
98 _Write32(Card, REG_GenPtr, rx_desc_phys);
99 _Write32(Card, REG_Command, RX_CMD_ADDR_LOAD);
101 _Write32(Card, REG_GenPtr, 0);
102 _Write32(Card, REG_Command, RX_CMD_START);
107 int PRO100_Cleanup(void)
112 tIPStackBuffer *PRO100_WaitForPacket(void *Ptr)
117 int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
122 void PRO100_IRQHandler(int Num, void *Ptr)
127 Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs)
130 Uint32 addr_data = ((EEPROM_OP_READ << addr_len) | Ofs) << 16;
132 _Write16( Card, REG_EEPROMCtrl, EEPROM_CTRL_CS | EEPROM_CTRL_SK );
133 _FlushWait(Card, 4); // Flush + 4us
137 for( int i = 32; i --; )
139 Uint16 ctrl = EEPROM_CTRL_CS | ((addr_data & (1 << i)) ? EEPROM_CTRL_DI : 0);
140 _Write16( Card, REG_EEPROMCtrl, ctrl );
141 _FlushWait(Card, 4); // Flush + 4us
142 _Write16( Card, REG_EEPROMCtrl, ctrl | EEPROM_CTRL_SK );
143 _FlushWait(Card, 4); // Flush + 4us
145 ctrl = _Read16( Card, REG_EEPROMCtrl );
146 // Once the address is fully recieved, the card emits a zero bit
147 if( !(ctrl & EEPROM_CTRL_DO) && i > 16 )
149 addr_len = addr_len - (i - 16);
153 data = (data << 1) | (ctrl & EEPROM_CTRL_DO ? 1 : 0);
157 _Write16( Card, REG_EEPROMCtrl, 0 );
158 _FlushWait(Card, 4); // Flush + 4us
160 return (data & 0xFFFF);
163 static void _Write16(tCard *Card, int Ofs, Uint16 Val) { outw(Card->IOBase + Ofs, Val); }
164 static void _Write32(tCard *Card, int Ofs, Uint32 Val) { outd(Card->IOBase + Ofs, Val); }
165 static Uint16 _Read16(tCard *Card, int Ofs) { return inw(Card->IOBase + Ofs); }
166 static Uint32 _Read32(tCard *Card, int Ofs) { return ind(Card->IOBase + Ofs); }
168 static void _FlushWait(tCard *Card, int Delay)
170 _Read16( Card, REG_Status );
173 Time_MicroSleep(Delay);