Merge branch 'master' of git://localhost/acess2
[tpg/acess2.git] / KernelLand / Modules / Network / PRO100 / main.c
1 /*
2  * Acess2 PRO/100 Driver
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - Driver core
7  *
8  * Built with reference to the linux e100 driver (drivers/net/ethernet/intel/e100.c)
9  * 82559-fast-ethernet-multifunciton-pci-datasheet.pdf
10  */
11 #include <acess.h>
12 #include <IPStack/include/adapters_api.h>
13 #include <modules.h>
14 #include <drv_pci.h>
15 #include <timers.h>
16 #include "pro100.h"
17
18 // === CONSTANTS ===
19 #define NUM_STATIC_CARDS        2
20 const Uint16    caSupportedCards[][2] = {
21         {0x8086, 0x103D},
22         };
23 const int       ciNumSupportedCards = sizeof(caSupportedCards)/sizeof(caSupportedCards[0]);
24
25 // === PROTOTYPES ===
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);
32
33 Uint16  PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs);
34
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);
40
41 // === GLOBALS ===
42 MODULE_DEFINE(0, 0x100, PRO100, PRO100_Install, PRO100_Cleanup, "IPStack", NULL);
43 tIPStack_AdapterType    gPRO100_AdapterType = {
44         .Name = "PRO/100",
45         .Type = ADAPTERTYPE_ETHERNET_100M,
46         .Flags = 0,     
47         .SendPacket = PRO100_SendPacket,
48         .WaitForPacket = PRO100_WaitForPacket
49 };
50 tCard   gaPRO100_StaticCards[NUM_STATIC_CARDS];
51
52 // === CODE ===
53 int PRO100_Install(char **Arguments)
54 {
55          int    cardidx = 0;
56         for( int i = 0; i < ciNumSupportedCards; i ++ )
57         {
58                 const Uint16    *ven_dev = caSupportedCards[i];
59                 int pciid = -1;
60                 while( -1 != (pciid = PCI_GetDevice(ven_dev[0], ven_dev[1], pciid)) )
61                 {
62                         Uint32  base = PCI_GetValidBAR(pciid, 0, PCI_BARTYPE_MEM32);
63                         tCard   *card;
64                         if( cardidx < NUM_STATIC_CARDS ) {
65                                 card = &gaPRO100_StaticCards[cardidx++];
66                         }
67                         else {
68                                 card = malloc(sizeof(tCard));
69                         }
70                         
71                         card->MMIO = MM_MapHWPages(base, 1);
72                         
73                         // TODO: Error check
74                         PRO100_InitCard(card);
75                         
76                         IPStack_Adapter_Add(&gPRO100_AdapterType, card, card->MAC.Bytes);
77                 }
78         }
79         return MODULE_ERR_OK;
80 }
81
82 int PRO100_InitCard(tCard *Card)
83 {
84         // Card reset
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
89
90         // Read MAC address
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);
94
95         // Create RX Descriptors
96         
97         // Set RX Buffer base
98         _Write32(Card, REG_GenPtr, rx_desc_phys);
99         _Write32(Card, REG_Command, RX_CMD_ADDR_LOAD);
100         
101         _Write32(Card, REG_GenPtr, 0);
102         _Write32(Card, REG_Command, RX_CMD_START);
103         
104         return 0;
105 }
106
107 int PRO100_Cleanup(void)
108 {
109         return 0;
110 }
111
112 tIPStackBuffer *PRO100_WaitForPacket(void *Ptr)
113 {
114         return NULL;
115 }
116
117 int PRO100_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
118 {
119         return -1;
120 }
121
122 void PRO100_IRQHandler(int Num, void *Ptr)
123 {
124         
125 }
126
127 Uint16 PRO100_int_ReadEEPROM(tCard *Card, size_t Ofs)
128 {
129         Uint8   addr_len = 8;
130         Uint32  addr_data = ((EEPROM_OP_READ << addr_len) | Ofs) << 16;
131         
132         _Write16( Card, REG_EEPROMCtrl, EEPROM_CTRL_CS | EEPROM_CTRL_SK );
133         _FlushWait(Card, 4);    // Flush + 4us
134
135         Uint32  data = 0;       
136
137         for( int i = 32; i --; )
138         {
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
144                 
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 )
148                 {
149                         addr_len = addr_len - (i - 16);
150                         i = 17;
151                 }
152                 
153                 data = (data << 1) | (ctrl & EEPROM_CTRL_DO ? 1 : 0);
154         }
155
156         // Deslect chip
157         _Write16( Card, REG_EEPROMCtrl, 0 );
158         _FlushWait(Card, 4);    // Flush + 4us
159
160         return (data & 0xFFFF);
161 }
162
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); }
167
168 static void _FlushWait(tCard *Card, int Delay)
169 {
170         _Read16( Card, REG_Status );
171         if(Delay > 0)
172         {
173                 Time_MicroSleep(Delay);
174         }
175 }
176

UCC git Repository :: git.ucc.asn.au