Modules/VIARhineII - More implementation work
[tpg/acess2.git] / KernelLand / Modules / Network / VIARhineII / rhine2.c
1 /*
2  * Acess2 VIA Rhine II Driver (VT6102)
3  * - By John Hodge (thePowersGang)
4  */
5 #define DEBUG   1
6 #define VERSION ((0<<8)|10)
7 #include <acess.h>
8 #include <modules.h>
9 #include <drv_pci.h>
10 #include <semaphore.h>
11 #include "rhine2_hw.h"
12 #include <IPStack/include/adapters_api.h>
13
14 #define N_RX_DESCS      16
15 #define RX_BUF_SIZE     1024
16 #define N_RX_PAGES      ((N_RX_DESCS*RX_BUF_SIZE)/PAGE_SIZE)
17 #define N_TX_DESCS      ((PAGE_SIZE/16)-N_RX_DESCS)
18
19 // === CONSTANTS ===
20 #define VENDOR_ID       0x1106
21 #define DEVICE_ID       0x3065
22
23 // === TYPES ===
24 typedef struct sCard
25 {
26         Uint16  IOBase;
27         Uint8   IRQ;
28         
29         tSemaphore      ReadSemaphore;
30
31         struct {
32                 Uint32  Phys;
33                 void    *Virt;
34         } RXBuffers[N_RX_PAGES];
35
36         Uint32  DescTablePhys;
37         void    *DescTable;
38
39         struct sTXDesc  *TXDescs;
40         
41         struct sTXDesc  *FirstTX;
42         struct sTXDesc  *LastTX;        // Most recent unsent packet
43         
44         struct sRXDesc  *FirstRX;       // Most recent unread packet
45         struct sRXDesc  *LastRX;        // End of RX descriptor queue
46
47         void    *IPHandle;      
48         Uint8   MacAddr[6];
49 }       tCard;
50
51 // === PROTOTYPES ===
52  int    Rhine2_Install(char **Options);
53 void    Rhine2_int_InitialiseCard(tCard *Card);
54 tIPStackBuffer  *Rhine2_WaitPacket(void *Ptr);
55  int    Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
56 void    Rhine2_IRQHandler(int Num, void *Pt);
57 // --- Helpers ---
58 struct sRXDesc  *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr);
59 void    *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr);
60 void    Rhine2_int_FreeRXDesc(void *Desc, size_t, size_t, const void*);
61 struct sTXDesc  *Rhine2_int_AllocTXDesc(tCard *Card);
62
63 // === GLOBALS ===
64 MODULE_DEFINE(0, VERSION, VIARhineII, Rhine2_Install, NULL, NULL);
65 tIPStack_AdapterType    gRhine2_AdapterType = {
66         .Name = "VIA Rhine II",
67         .SendPacket = Rhine2_SendPacket,
68         .WaitForPacket = Rhine2_WaitPacket,
69 };
70  int    giRhine2_CardCount;
71 tCard   *gaRhine2_Cards;
72
73 // === CODE ===
74 /**
75  * \brief Initialises the driver
76  */
77 int Rhine2_Install(char **Options)
78 {
79          int    id = -1;
80          int    i = 0;
81 //      Uint16  base;
82         tCard   *card;
83         
84         giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID);
85         Log_Debug("Rhine2", "%i cards", giRhine2_CardCount);
86         
87         if( giRhine2_CardCount == 0 )   return MODULE_ERR_NOTNEEDED;
88         
89         gaRhine2_Cards = calloc( giRhine2_CardCount, sizeof(tCard) );
90         
91         while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, i)) != -1 )
92         {
93                 card = &gaRhine2_Cards[i];
94                 
95                 LOG("BAR0 = 0x%08x", PCI_GetBAR(id, 0));
96                 LOG("BAR1 = 0x%08x", PCI_GetBAR(id, 1));
97                 LOG("BAR2 = 0x%08x", PCI_GetBAR(id, 2));
98                 LOG("BAR3 = 0x%08x", PCI_GetBAR(id, 3));
99                 LOG("BAR4 = 0x%08x", PCI_GetBAR(id, 4));
100                 LOG("BAR5 = 0x%08x", PCI_GetBAR(id, 5));
101                 
102                 card->IOBase = PCI_GetBAR(id, 0);
103                 if( !(card->IOBase & 1) ) {
104                         // Oops?
105                         Log_Warning("Rhine2", "BAR0 is not in IO space");
106                         continue ;
107                 }
108                 card->IOBase &= ~1;
109                 card->IRQ = PCI_GetIRQ( id );
110                 
111                 // Install IRQ Handler
112                 IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler, card);
113                 
114                 Rhine2_int_InitialiseCard(card);
115         
116                 Log_Log("Rhine2", "Card %i 0x%04x, IRQ %i %02x:%02x:%02x:%02x:%02x:%02x",
117                         i, card->IOBase, card->IRQ,
118                         card->MacAddr[0], card->MacAddr[1], card->MacAddr[2],
119                         card->MacAddr[3], card->MacAddr[4], card->MacAddr[5]
120                         );
121                 
122                 i ++;
123         }
124         
125         return MODULE_ERR_OK;
126 }
127
128 void Rhine2_int_InitialiseCard(tCard *Card)
129 {
130         tPAddr  phys;
131         
132         Card->MacAddr[0] = inb(Card->IOBase + REG_PAR0);
133         Card->MacAddr[1] = inb(Card->IOBase + REG_PAR1);
134         Card->MacAddr[2] = inb(Card->IOBase + REG_PAR2);
135         Card->MacAddr[3] = inb(Card->IOBase + REG_PAR3);
136         Card->MacAddr[4] = inb(Card->IOBase + REG_PAR4);
137         Card->MacAddr[5] = inb(Card->IOBase + REG_PAR5);
138         
139         outb(Card->IOBase + REG_CR1, CR1_SFRST);
140         // TODO: Timeout
141         while( inb(Card->IOBase + REG_CR1) & CR1_SFRST ) ;
142         
143         // Allocate memory for things
144         for( int i = 0; i < N_RX_PAGES; i ++ )
145         {
146                 Card->RXBuffers[i].Virt = (void*)MM_AllocDMA(1, 32, &phys);
147                 Card->RXBuffers[i].Phys = phys;
148         }
149         
150         Card->DescTable = (void*)MM_AllocDMA(1, 32, &phys);
151         Card->DescTablePhys = phys;
152
153         // Initialise RX Descriptors
154         struct sRXDesc  *rxdescs = Card->DescTable;
155         for( int i = 0; i < N_RX_DESCS; i ++ )
156         {
157                 rxdescs[i].RSR = 0;
158                 rxdescs[i].BufferSize = RX_BUF_SIZE;
159                 rxdescs[i].RXBufferStart = Card->RXBuffers[i/(PAGE_SIZE/RX_BUF_SIZE)].Phys
160                         + (i % (PAGE_SIZE/RX_BUF_SIZE)) * RX_BUF_SIZE;
161                 rxdescs[i].RDBranchAddress = Card->DescTablePhys + (i+1) * sizeof(struct sRXDesc);
162                 rxdescs[i].Length = (1 << 15);  // set OWN
163         }
164         rxdescs[ N_RX_DESCS - 1 ].RDBranchAddress = 0;
165         Card->FirstRX = &rxdescs[0];
166         Card->LastRX = &rxdescs[N_RX_DESCS - 1];
167
168         Card->TXDescs = (void*)(rxdescs + N_RX_DESCS);
169         memset(Card->TXDescs, 0, sizeof(struct sTXDesc)*N_TX_DESCS);
170         
171         
172         // - Initialise card state
173         outb(Card->IOBase + REG_IMR0, 0xFF);
174         outb(Card->IOBase + REG_IMR1, 0xFF);
175         outd(Card->IOBase + REG_CUR_RX_DESC, Card->DescTablePhys);
176         
177         outb(Card->IOBase + REG_CR0, CR0_STRT|CR0_RXON);
178 }
179
180 // --- File Functions ---
181 tIPStackBuffer *Rhine2_WaitPacket(void *Ptr)
182 {
183         tCard   *card = Ptr;
184         tIPStackBuffer  *ret;
185         struct sRXDesc  *desc;
186          int    nDesc;
187         
188         ENTER("pPtr", Ptr);
189
190         if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
191         {
192                 LEAVE('n');
193                 return NULL;
194         }
195         
196         nDesc = 0;
197         desc = card->FirstRX;
198         while( desc->BufferSize & (1 << 15) )
199         {
200                 desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
201                 nDesc ++;
202         }
203
204         LOG("%i descriptors in packet", nDesc);
205
206         ret = IPStack_Buffer_CreateBuffer(nDesc);
207         desc = card->FirstRX;
208         while( desc->BufferSize & (1 << 15) )
209         {
210                 void    *data = Rhine2_int_GetBufferFromPhys(card, desc->RXBufferStart);
211                 IPStack_Buffer_AppendSubBuffer(ret,
212                         desc->Length, 0, data,
213                         Rhine2_int_FreeRXDesc, desc
214                         );
215                 desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
216         }       
217         card->FirstRX = desc;
218
219         LEAVE('p', ret);
220         return ret;
221 }
222
223 int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
224 {
225         tCard   *card = Ptr;
226         size_t  len;
227         const void      *data;
228         struct sTXDesc  *first_desc = NULL;
229         struct sTXDesc  *last_desc = NULL;
230
231         ENTER("pPtr pBuffer", Ptr, Buffer);     
232
233         // Iterate buffers
234         for( int id = -1; -1 != (id = IPStack_Buffer_GetBuffer(Buffer, id, &len, &data)); )
235         {
236                 tPAddr  pdata = MM_GetPhysAddr( (tVAddr)data );
237                 struct sTXDesc  *desc;
238                 #if PHYS_BITS > 32
239                 if( pdata >> 32 ) {
240                         // TODO: re-map
241                 } 
242                 #endif
243                 
244                 desc = Rhine2_int_AllocTXDesc(card);
245                 if(!last_desc)
246                         first_desc = desc;
247                 else
248                         last_desc->TDBranchAddress = MM_GetPhysAddr( (tVAddr)desc );
249
250                 desc->TXBufferStart = pdata;
251                 desc->BufferSize = len;
252                 // TODO: TCR
253                 desc->TCR = 0;
254                 desc->TSR = TD_TSR_OWN;
255                 desc->TDBranchAddress = 0;
256
257                 last_desc = desc;
258         }
259         
260         if( !first_desc ) {
261                 LEAVE('i', -1);
262                 return -1;
263         }
264
265         first_desc->TCR |= TD_TCR_STP;
266         last_desc->TCR |= TD_TCR_EDP;
267
268         if( card->LastTX )
269                 card->LastTX->TDBranchAddress = MM_GetPhysAddr( (tVAddr)first_desc );
270         else {
271                 card->FirstTX = first_desc;
272                 card->LastTX = first_desc;
273                 outd(card->IOBase + REG_CUR_TX_DESC, MM_GetPhysAddr( (tVAddr)first_desc ));
274         }
275
276         outb(card->IOBase + REG_CR1, CR1_TDMD);
277         
278         // TODO: Wait until the packet has sent, then clean up
279         while( inb(card->IOBase + REG_CR1) & CR1_TDMD )
280                 ;
281
282         return 0;
283 }
284
285 void Rhine2_IRQHandler(int Num, void *Ptr)
286 {
287         
288 }
289
290 // --- Helpers ---
291 struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr)
292 {
293         if( Card->DescTablePhys > Addr )        return NULL;
294         if( Card->DescTablePhys + PAGE_SIZE <= Addr )   return NULL;
295         if( Addr & 15 ) return NULL;
296         return (struct sRXDesc*)Card->DescTable + ((Addr & (PAGE_SIZE-1)) / 16);
297 }
298
299 void *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr)
300 {
301         for( int i = 0; i < N_RX_PAGES; i ++ )
302         {
303                 if( Card->RXBuffers[i].Phys > Addr )    continue;
304                 if( Card->RXBuffers[i].Phys + PAGE_SIZE <= Addr )       continue;
305                 return Card->RXBuffers[i].Virt + (Addr & (PAGE_SIZE-1));
306         }
307         return NULL;
308 }
309
310 void Rhine2_int_FreeRXDesc(void *Ptr, size_t u1, size_t u2, const void *u3)
311 {
312         struct sRXDesc  *desc = Ptr;
313         
314         desc->RSR = 0;
315         desc->Length = (1 << 15);       // Reset OWN
316 }
317
318 struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card)
319 {
320         for( int i = 0; i < N_TX_DESCS; i ++ )
321         {
322                 if( Card->TXDescs[i].TSR & TD_TSR_OWN ) continue ;
323                 Card->TXDescs[i].TSR = TD_TSR_OWN;
324                 return &Card->TXDescs[i];
325         }
326         return NULL;
327 }
328

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