Misc changes
[tpg/acess2.git] / Modules / Network / RTL8139 / rtl8139.c
1 /*
2  * Acess2 RTL8139 Driver
3  * - By John Hodge (thePowersGang)
4  */
5 #define DEBUG   0
6 #define VERSION ((0<<8)|50)
7 #include <acess.h>
8 #include <modules.h>
9 #include <fs_devfs.h>
10 #include <drv_pci.h>
11 #include <tpl_drv_network.h>
12
13 // === CONSTANTS ===
14 enum eRTL8139_Regs
15 {
16         MAC0, MAC1, MAC2,
17         MAC3, MAC4, MAC5,
18         MAR0    = 0x08,
19         MAR1, MAR2, MAR3,
20         MAR4, MAR5, MAR6, MAR7,
21         
22         RBSTART = 0x30, //!< Recieve Buffer Start (DWord)
23         // 0x31, 0x32, 0x33
24         
25         // ??, ??, ??, RST, RE, TE, ??, ??
26         CMD     = 0x37,
27         IMR     = 0x3C,
28         ISR     = 0x3E,
29         
30         RCR     = 0x44,
31         
32         CONFIG1 = 0x52
33 };
34
35 // === TYPES ===
36 typedef struct sCard
37 {
38         Uint16  IOBase;
39         Uint8   IRQ;
40         
41          int    NumWaitingPackets;
42         
43         void    *ReceiveBuffer;
44         tPAddr  PhysReceiveBuffer;
45         
46         char    Name[2];
47         tVFS_Node       Node;
48         Uint8   MacAddr[6];
49 }       tCard;
50
51 // === PROTOTYPES ===
52  int    RTL8139_Install(char **Options);
53 char    *RTL8139_ReadDir(tVFS_Node *Node, int Pos);
54 tVFS_Node       *RTL8139_FindDir(tVFS_Node *Node, const char *Filename);
55  int    RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Arg);
56 Uint64  RTL8139_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
57 Uint64  RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
58 void    RTL8139_IRQHandler(int Num);
59
60 // === GLOBALS ===
61 MODULE_DEFINE(0, VERSION, RTL8139, RTL8139_Install, NULL, NULL);
62 tDevFS_Driver   gRTL8139_DriverInfo = {
63         NULL, "RTL8139",
64         {
65         .NumACLs = 1,
66         .ACLs = &gVFS_ACL_EveryoneRX,
67         .Flags = VFS_FFLAG_DIRECTORY,
68         .ReadDir = RTL8139_ReadDir,
69         .FindDir = RTL8139_FindDir,
70         .IOCtl = RTL8139_RootIOCtl
71         }
72 };
73  int    giRTL8139_CardCount;
74 tCard   *gpRTL8139_Cards;
75
76 // === CODE ===
77 /**
78  * \brief Installs the RTL8139 Driver
79  */
80 int RTL8139_Install(char **Options)
81 {
82          int    id = -1;
83          int    i = 0;
84         Uint16  base;
85         
86         giRTL8139_CardCount = PCI_CountDevices( 0x10EC, 0x8139, 0 );
87         
88         gpRTL8139_Cards = calloc( giRTL8139_CardCount, sizeof(tCard) );
89         
90         
91         while( (id = PCI_GetDevice(0x10EC, 0x8139, 0, id)) != -1 )
92         {
93                 base = PCI_AssignPort( id, 0, 0x100 );
94                 gpRTL8139_Cards[i].IOBase = base;
95                 gpRTL8139_Cards[i].IRQ = PCI_GetIRQ( id );
96                 
97                 // Install IRQ Handler
98                 IRQ_AddHandler(gpRTL8139_Cards[ k ].IRQ, RTL8136_IRQHandler);
99                 
100                 // Power on
101                 outb( base + CONFIG1, 0x00 );
102
103                 // Reset (0x10 to CMD)
104                 outb( base + CMD, 0x10 );       
105                 while( inb(base + CMD) & 0x10 ) ;
106                 
107                 // Set up recieve buffer
108                 // - Allocate 3 pages below 4GiB for the recieve buffer (Allows 8k+16+1500)
109                 gpRTL8139_Cards[i].ReceiveBuffer = MM_AllocDMA( 3, 32, &gpRTL8139_Cards[i].PhysReceiveBuffer );
110                 outl(base + RBSTART, (Uint32)gpRTL8139_Cards[i].PhysReceiveBuffer);
111                 // Set IMR to Transmit OK and Receive OK
112                 outw(base + IMR, 0x5);
113                 
114                 // Set recieve buffer size and recieve mask
115                 // - Bit 7 being unset tells the card to overflow the recieve buffer if needed
116                 //   (i.e. when the packet starts at the end of the bufffer, it overflows up
117                 //    to 1500 bytes)
118                 outl(base + RCR, 0x0F);
119         
120                 // Recive Enable and Transmit Enable    
121                 outb(base + CMD, 0x0C);
122                 
123                 // Get the card's MAC address
124                 gpRTL8139_Cards[ i ].MacAddr[0] = inb(base+MAC0);
125                 gpRTL8139_Cards[ i ].MacAddr[1] = inb(base+MAC1);
126                 gpRTL8139_Cards[ i ].MacAddr[2] = inb(base+MAC2);
127                 gpRTL8139_Cards[ i ].MacAddr[3] = inb(base+MAC3);
128                 gpRTL8139_Cards[ i ].MacAddr[4] = inb(base+MAC4);
129                 gpRTL8139_Cards[ i ].MacAddr[5] = inb(base+MAC5);
130                 
131                 // Set VFS Node
132                 gpRTL8139_Cards[ i ].Name[0] = '0'+i;
133                 gpRTL8139_Cards[ i ].Name[1] = '\0';
134                 gpRTL8139_Cards[ i ].Node.ImplPtr = &gpRTL8139_Cards[ i ];
135                 gpRTL8139_Cards[ i ].Node.NumACLs = 0;
136                 gpRTL8139_Cards[ i ].Node.CTime = now();
137                 gpRTL8139_Cards[ i ].Node.Write = RTL8139_Write;
138                 gpRTL8139_Cards[ i ].Node.Read = RTL8139_Read;
139                 gpRTL8139_Cards[ i ].Node.IOCtl = RTL8139_IOCtl;
140                 
141                 Log_Log("RTL8139", "Card %i 0x%04x %02x:%02x:%02x:%02x:%02x:%02x",
142                         i, base,
143                         gpRTL8139_Cards[ i ].MacAddr[0], gpRTL8139_Cards[ i ].MacAddr[1],
144                         gpRTL8139_Cards[ i ].MacAddr[2], gpRTL8139_Cards[ i ].MacAddr[3],
145                         gpRTL8139_Cards[ i ].MacAddr[4], gpRTL8139_Cards[ i ].MacAddr[5]
146                         );
147                 
148                 i ++;
149         }
150         return MODULE_ERR_OK;
151 }
152
153 // --- Root Functions ---
154 char *RTL8139_ReadDir(tVFS_Node *Node, int Pos)
155 {
156         if( Pos < 0 || Pos > giRTL8139_CardCount )      return NULL;
157         
158         return strdup( gpRTL8139_Cards[Pos].Name );
159 }
160
161 tVFS_Node *RTL8139_FindDir(tVFS_Node *Node, const char *Filename)
162 {
163         //TODO: It might be an idea to supprt >10 cards
164         if(Filename[0] == '\0' || Filename[0] != '\0')  return NULL;
165         if(Filename[0] < '0' || Filename[0] > '9')      return NULL;
166         return &gpRTL8139_Cards[ Filename[0]-'0' ].Node;
167 }
168
169 const char *csaRTL8139_RootIOCtls[] = {DRV_IOCTLNAMES, NULL};
170 int RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Arg)
171 {
172         switch(ID)
173         {
174         BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_RootIOCtls);
175         }
176         return 0;
177 }
178
179 // --- File Functions ---
180 Uint64 RTL8139_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
181 {
182         return 0;
183 }
184
185 Uint64 RTL8139_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
186 {
187         return 0;
188 }
189
190 const char *csaRTL8139_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL};
191 int RTL8139_IOCtl(tVFS_Node *Node, int ID, void *Arg)
192 {
193         switch(ID)
194         {
195         BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_NodeIOCtls);
196         }
197         return 0;
198 }

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