Cleanup
[tpg/acess2.git] / Kernel / drv / ne2000.c
1 /* Acess2
2  * NE2000 Driver
3  * 
4  * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
5  */
6 #include <common.h>
7 #include <modules.h>
8 #include <fs_devfs.h>
9
10 // === CONSTANTS ===
11 static const struct {
12         Uint16  Vendor;
13         Uint16  Device;
14 } csaCOMPAT_DEVICES[] = {
15         {0x10EC, 0x8029},       // Realtek 8029
16         {0x10EC, 0x8129}        // Realtek 8129
17 };
18 #define NUM_COMPAT_DEVICES      (sizeof(csaCOMPAT_DEVICES)/sizeof(csaCOMPAT_DEVICES[0]))
19
20 enum eNe2k_Page0Read {
21         COMMAND = 0,    //!< the master command register
22         CLDA0,          //!< Current Local DMA Address 0
23         CLDA1,          //!< Current Local DMA Address 1
24         BNRY,           //!< Boundary Pointer (for ringbuffer)
25         TSR,            //!< Transmit Status Register
26         NCR,            //!< collisions counter
27         FIFO,           //!< (for what purpose ??)
28         ISR,            //!< Interrupt Status Register
29         CRDA0,          //!< Current Remote DMA Address 0
30         CRDA1,          //!< Current Remote DMA Address 1
31         RSR = 0xC       //!< Receive Status Register
32 };
33
34 enum eNe2k_Page0Write {
35         PTART = 1,      //!< page start (init only)
36         PSTOP,          //!< page stop  (init only)
37         TPSR = 4,       //!< transmit page start address
38         TBCR0,          //!< transmit byte count (low)
39         TBCR1,          //!< transmit byte count (high)
40         RSAR0 = 8,      //!< remote start address (lo)
41         RSAR1,  //!< remote start address (hi)
42         RBCR0,  //!< remote byte count (lo)
43         RBCR1,  //!< remote byte count (hi)
44         RCR,    //!< receive config register
45         TCR,    //!< transmit config register
46         DCR,    //!< data config register    (init)
47         IMR             //!< interrupt mask register (init)
48 };
49
50 // === TYPES ===
51 typedef struct sNe2k_Card {
52         Uint16  IOBase; //!< IO Port Address from PCI
53         Uint8   IRQ;    //!< IRQ Assigned from PCI
54         
55          int    NextMemPage;    //!< Next Card Memory page to use
56         
57         char    Name[2];        // "0"
58         tVFS_Node       *Node;
59         char    MacAddr[6];
60 } tCard;
61
62 // === PROTOTYPES ===
63  int    Ne2k_Install(char **Arguments);
64 Uint64  Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
65
66 // === GLOBALS ===
67 MODULE_DEFINE(0, 0x0032, Ne2k, Ne2k_Install, NULL, NULL);
68 tDevFS_Driver   gNe2k_DriverInfo = {
69         NULL, "ne2k",
70         {
71         .NumACLs = 1,
72         .ACLs = &gVFS_ACL_EveryoneRW,
73         .Flags = VFS_FFLAG_DIRECTORY
74         }
75 };
76 Uint16  gNe2k_BaseAddress;
77  int    giNe2k_CardCount = 0;
78
79 // === CODE ===
80 /**
81  * \fn int Ne2k_Install(char **Options)
82  * \brief Installs the NE2000 Driver
83  */
84 int Ne2k_Install(char **Options)
85 {
86          int    i, j, k;
87         
88         // --- Scan PCI Bus ---
89         // Count Cards
90         giNe2k_CardCount = 0;
91         for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
92         {
93                 giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
94         }
95         
96         // Enumerate Cards
97         k = 0;
98         gpNe2k_Cards = malloc( giNe2k_CardCount * sizeof(tCard) );
99         memsetd(gpNe2k_Cards, 0, giNe2k_CardCount * sizeof(tCard) / 4);
100         for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
101         {
102                 count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
103                 for( j = 0; j < count; j ++,k ++ )
104                 {
105                         id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0, j );
106                         // Create Structure
107                         base = PCI_AssignPort( id, 0, 0x20 );
108                         gpNe2k_Cards[ k ].IOBase = base;
109                         gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id );
110                         gpNe2k_Cards[ k ].NextMemPage = 1;
111                         
112                         //Install IRQ6 Handler
113                         IRQ_Set(gpNe2k_Cards[ k ].IRQ, Ne2k_IRQHandler);
114                         
115                         // Reset Card
116                         outb( base + 0x1F, inb(base + 0x1F) );
117                         while( (inb( base+ISR ) & 0x80) == 0 );
118                         outb( base + ISR, 0x80 );
119                         
120                         // Initialise Card
121                         outb( base + COMMAND, 0x21 );   // No DMA and Stop
122                         outb( base + DCR, 0x49 );       // Set WORD mode
123                         outb( base + IMR, 0x00 );
124                         outb( base + ISR, 0xFF );
125                         outb( base + RCR, 0x20 );       // Reciever to Monitor
126                         outb( base + TCR, 0x02 );       // Transmitter OFF
127                         outb( base + RBCR0, 6*4 );      // Remote Byte Count
128                         outb( base + RBCR1, 0 );
129                         outb( base + RSAR0, 0 );        // Clear Source Address
130                         outb( base + RSAR1, 0 );
131                         outb( base + COMMAND, 0x0A );   // Remote Read, Start
132                         
133                         // Read MAC Address
134                         gpNe2k_Cards[ k ].MacAddr[0] = inb(base+0x10);  inb(base+0x10);
135                         gpNe2k_Cards[ k ].MacAddr[1] = inb(base+0x10);  inb(base+0x10);
136                         gpNe2k_Cards[ k ].MacAddr[2] = inb(base+0x10);  inb(base+0x10);
137                         gpNe2k_Cards[ k ].MacAddr[3] = inb(base+0x10);  inb(base+0x10);
138                         gpNe2k_Cards[ k ].MacAddr[4] = inb(base+0x10);  inb(base+0x10);
139                         gpNe2k_Cards[ k ].MacAddr[5] = inb(base+0x10);  inb(base+0x10);
140                         
141                         outb( base+PSTART, 0x60);       // Set Receive Start
142                         outb( base+BNRY, 0x7F); // Set Boundary Page
143                         outb( base+PSTOP, 0x80);        // Set Stop Page
144                         outb( base+ISR, 0xFF ); // Clear all ints
145                         outb( base+CMD, 0x22 ); // No DMA, Start
146                         outb( base+IMR, 0x3F ); // Set Interupt Mask
147                         outb( base+RCR, 0x8F ); // Set WRAP and allow all packet matches
148                         outb( base+TCR, 0x00 ); // Set Normal Transmitter mode
149                         outb( base+TPSR, 0x40); // Set Transmit Start
150                         
151                         // Set MAC Address
152                         /*
153                         Ne2k_WriteReg(base, MAC0, gpNe2k_Cards[ k ].MacAddr[0]);
154                         Ne2k_WriteReg(base, MAC1, gpNe2k_Cards[ k ].MacAddr[1]);
155                         Ne2k_WriteReg(base, MAC2, gpNe2k_Cards[ k ].MacAddr[2]);
156                         Ne2k_WriteReg(base, MAC3, gpNe2k_Cards[ k ].MacAddr[3]);
157                         Ne2k_WriteReg(base, MAC4, gpNe2k_Cards[ k ].MacAddr[4]);
158                         Ne2k_WriteReg(base, MAC5, gpNe2k_Cards[ k ].MacAddr[5]);
159                         */
160                         
161                         Log("[NE2K]: Card #%i: IRQ=%i, Base=0x%x, ",
162                                 k, gpNe2k_Cards[ k ].IRQ, gpNe2k_Cards[ k ].PortBase,
163                                 gpNe2k_Cards[ k ].Buffer);
164                         Log("MAC Address %x:%x:%x:%x:%x:%x\n",
165                                 gpNe2k_Cards[ k ].MacAddr[0], gpNe2k_Cards[ k ].MacAddr[1],
166                                 gpNe2k_Cards[ k ].MacAddr[2], gpNe2k_Cards[ k ].MacAddr[3],
167                                 gpNe2k_Cards[ k ].MacAddr[4], gpNe2k_Cards[ k ].MacAddr[5]
168                                 );
169                         
170                         // Set VFS Node
171                         gpNe2k_Cards[ k ].Name[0] = '0'+k;
172                         gpNe2k_Cards[ k ].Name[1] = '\0';
173                         gpNe2k_Cards[ k ].Node.NumACLs = 1;
174                         gpNe2k_Cards[ k ].Node.ACLs = gVFS_ACL_EveryoneRW;
175                         gpNe2k_Cards[ k ].Node.CTime = now();
176                         gpNe2k_Cards[ k ].Node.Write = Ne2k_Write;
177                 }
178         }
179         
180         DevFS_AddDevice( &gNe2k_DriverInfo );
181         return 0;
182 }
183
184
185 /**
186  * \fn Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
187  */
188 Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
189 {
190         tCard   *Card = (tCard*)Node->ImplPtr;
191         
192         // Sanity Check Length
193         if(Length > 0xFFFF)     return 0;
194         
195         outb(Card->IOBase + COMMAND, 0|0x22);   // Page 0, Start, NoDMA
196         // Send Size
197         outb(Card->IOBase + RBCR0, Count & 0xFF);
198         outb(Card->IOBase + RBCR1, Count >> 8);
199         // Clear Remote DMA Flag
200         outb(Card->IOBase + ISR, 0x40); // Bit 6
201         // Set up transfer
202         outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
203         outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length));        // Page Offset
204         return 0;
205 }
206
207 /**
208  * \fn Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
209  */
210 Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
211 {
212         
213 }

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