Subversion Repositories shark

Rev

Rev 3 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
23
 CVS :        $Id: eth.c,v 1.1.1.1 2002-03-29 14:12:50 pj Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.1.1.1 $
27
 Last update: $Date: 2002-03-29 14:12:50 $
28
 ------------
29
**/
30
 
31
/*
32
 * Copyright (C) 2000 Luca Abeni
33
 *
34
 * This program is free software; you can redistribute it and/or modify
35
 * it under the terms of the GNU General Public License as published by
36
 * the Free Software Foundation; either version 2 of the License, or
37
 * (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
47
 *
48
 */
49
 
50
 
51
/* Author:      Luca Abeni                  */
52
/* Date:        2/12/1997                                       */
53
 
54
/* File:    eth.C                       */
55
/* Revision:    2.0                     */
56
 
57
/*
58
   Ethernet layer: it is an inetrface between the low level driver (
59
   3Com 3c59xx, ...) and the high level protocols (IP, ARP,...).
60
*/
61
 
62
/* only 4 debug... */
63
int netlev;
64
 
65
#include <kernel/kern.h>
66
#include <modules/hartport.h>
67
 
68
#include <drivers/pci.h>
69
 
70
#include "eth_priv.h"
71
#include "netbuff.h"
72
 
73
#include <linux/netdevice.h>
74
/*#include "lowlev.h"
75
//#include "3com.h" */
76
 
77
#define ETH_PAGE        5
78
 
79
struct eth_service{
80
        WORD type;
81
        void (*rfun)(void *pkt);
82
} ETH_SERVICE;
83
 
84
int definedprotocols;
85
struct eth_service eth_table[ETH_MAX_PROTOCOLS];
86
 
87
#define ETH_RX_BUFFERS      4   
88
#define ETH_TX_BUFFERS      4
89
 
90
#ifndef ETH0_ADDR
91
# define ETH0_ADDR 0
92
#endif
93
#ifndef ETH0_IRQ
94
# define ETH0_IRQ 0
95
#endif
96
 
97
#define NONE 0
98
 
99
/*extern void net_handler(void);
100
//extern PID net_extern_driver(void);*/
101
 
102
PID nettask_pid = NIL;
103
static PORT NetRxPort;
104
 
105
/* void (*vortex_send)(DWORD BaseAddress, DWORD *txbuff, int len); */
106
 
107
int ethIsInstalled = FALSE;
108
 
109
/* device descriptor */
110
struct eth_device eth_dev;
111
struct pci_des pci_devs[5];
112
/* This is the Linux one!!! */
113
static struct device device0 = {
114
        "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, NULL, NULL};
115
struct device *dev_base = &device0;
116
 
117
/* received frames buffers */
118
extern struct netbuff rxbuff; /* from skbuff.c */
119
 
120
/* buffers for the frames to send */
121
/* struct netbuff txbuff; */
122
 
123
/* Called if an unknown frames arrives */
124
void eth_nullfun(void *pkt)
125
{
126
        kern_raise(ETH_NULLPROTOCOL_EXC,NIL);
127
}
128
 
129
 
130
 
131
 
132
void dev_tint(struct device *dev)
133
{
134
        cprintf("Warning!!!! dev_tint called!!! (Why???)\n");
135
        sys_abort(201);
136
}
137
 
138
/*
139
   -----------------------------------------------------------------------
140
   The extern process calls this function when a frame arrives
141
   -----------------------------------------------------------------------
142
*/
143
 
144
void netif_rx(struct sk_buff *skb)
145
{
146
  //cprintf("DENTRO netif_rx, skbuf=%p\n",skb->data);
147
        if (nettask_pid == NIL) {
148
                cprintf("Net receives packets, but the driver doesn't exist!!!\n");
149
                sys_abort(300);
150
        }
151
 
152
        port_send(NetRxPort,skb,NON_BLOCK);
153
/*  task_activate(nettask_pid);*/
154
}
155
 
156
TASK net_extern_driver(void)
157
{
158
        static PORT NetPort;
159
        struct sk_buff skb;
160
        void *pkt;
161
        int len;
162
        BYTE count;
163
        int i;
164
 
165
        NetPort = port_connect("NetPort", sizeof(struct sk_buff), STREAM, READ);
166
        while (1) {
167
/* debug... */
168
netlev = 1;
169
                port_receive(NetPort,&skb,BLOCK);  
170
                pkt = skb.data;
171
                len = skb.len;
172
 
173
                ((struct eth_header *)pkt)->type = ntohs(((struct eth_header *)pkt)->type);
174
                count = 0;
175
                /* Search for the frame protocol...*/
176
                for (i = 0; i < definedprotocols; i++) {
177
/* debug... */
178
netlev = 10 + i;
179
                        if (eth_table[i].type == (((struct eth_header *)pkt)->type)) {
180
                                count++;
181
                                /*...and call the protocol CallBack!!! */
182
                                eth_table[i].rfun(pkt);
183
                        }
184
                }
185
 
186
/* debug... */
187
                netlev = 20;
188
                //cprintf("ETH: releasing %p\n", pkt);
189
                netbuff_release(&rxbuff, pkt);
190
/* debug... */
191
netlev = 30;
192
        }
193
}
194
 
195
/*
196
   --------------------
197
   Interface functions
198
   --------------------
199
*/
200
/* formatted print of an ethernet header */
201
void eth_printHeader(struct eth_header *p)
202
{
203
        cprintf("Dest   : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",p->dest.ad[0],
204
                                                        p->dest.ad[1],
205
                                                        p->dest.ad[2],
206
                                                        p->dest.ad[3],
207
                                                        p->dest.ad[4],
208
                                                        p->dest.ad[5]);
209
        cprintf("Source : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",p->source.ad[0],
210
                                                        p->source.ad[1],
211
                                                        p->source.ad[2],
212
                                                        p->source.ad[3],
213
                                                        p->source.ad[4],
214
                                                        p->source.ad[5]);
215
        cprintf("Type : %x\n",p->type);
216
}
217
 
218
void eth_showinfo(struct eth_device *d)
219
{
220
        cprintf("IntLine                : %d\n",d->IntLine);
221
        cprintf("BaseAddress    : %lx\n",d->BaseAddress);
222
        cprintf("Address                : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
223
                                        d->addr.ad[0],d->addr.ad[1],d->addr.ad[2],
224
                                        d->addr.ad[3],d->addr.ad[4],d->addr.ad[5]);
225
}
226
 
227
/* formatted print of an ethernet frame*/
228
void eth_printPkt(char *pkt,int len)
229
{
230
        int i,j,offset;
231
 
232
        eth_printHeader((struct eth_header *)pkt);
233
        offset = sizeof(struct eth_header);
234
        len -= offset;
235
        for (i = 0; i < len; i += 10) {
236
        for (j = 0; j < 10; j++)
237
                cprintf("%2.2x  ",pkt[offset+i+j]);
238
        for (j = 0; j < 10; j++)
239
                cputc(pkt[offset+i+j]);
240
                cprintf("\n");
241
        }
242
        cprintf("\n");
243
}
244
 
245
#if 0                                                                   
246
/*-------------------- User Interface -----------------------------*/
247
unsigned short htons(unsigned short host)
248
{
249
        return ((host & 0xff00) >> 8) + ((host & 0x00ff) << 8);
250
}
251
 
252
unsigned short ntohs(unsigned short host)
253
{
254
        return ((host & 0xff00) >> 8) + ((host & 0x00ff) << 8);
255
}
256
#endif
257
 
258
/*
259
   Translate an ethernet address from a text string to an eth_addr
260
   structure
261
*/
262
void eth_str2Addr(char *add, struct eth_addr *ds)
263
{
264
        int ad[6];
265
        int i,j;
266
        char c;
267
 
268
        i = 0;
269
        for(j = 0; j < 6; j++) {
270
        ad[j] = 0;
271
        while((add[i] != ':') && (add[i] != 0)) {
272
                c = add[i++];
273
                if (c <= '9') c = c - '0';
274
                else c = c - 'A' + 10;
275
                ad[j] = ad[j] * 16 + c;
276
        }
277
        i++;
278
        }
279
        for (i=0; i<6; i++) ds->ad[i] = ad[i];
280
}
281
 
282
/* Set a higher level protocol's CallBack */
283
int eth_setProtocol(WORD type, void (*recv)(void *pkt))
284
{
285
        int i;
286
 
287
        if (definedprotocols == ETH_MAX_PROTOCOLS) return FALSE;
288
        for(i = 0; i < definedprotocols; i++) {
289
        if (eth_table[i].type == type) return FALSE;
290
        }
291
        eth_table[definedprotocols].type = type;
292
        eth_table[definedprotocols++].rfun = recv;
293
        return TRUE;
294
}
295
 
296
/* Fill an ethernet frame's header and return a pointer to the frame's body */
297
void *eth_setHeader(void *b,struct eth_addr dest, WORD type)
298
{
299
        setEthAddr(((struct eth_header *)b)->dest,dest);
300
        setEthAddr(((struct eth_header *)b)->source,eth_dev.addr);
301
        /* the type field is in big-endian format */
302
        ((struct eth_header *) b)->type = htons(type);
303
        return((BYTE *)b + sizeof(struct eth_header));
304
}
305
 
306
/* getFirstDataByte : Return a pointer to the body of an ethernet frame */
307
void *eth_getFDB(void *p)
308
{
309
        return ((void *)((BYTE *)p + sizeof(struct eth_header)));
310
}
311
 
312
/* eth_getAddress : return the local ethernet address */
313
void eth_getAddress(struct eth_addr *eth)
314
{
315
        memcpy(eth->ad,&(device0.dev_addr),sizeof(struct eth_addr));
316
}
317
 
318
/* Send an ethernet frame */
319
int eth_sendPkt(void *p, int len)
320
{
321
        int i;
322
        int l;
323
        struct sk_buff buff;
324
 
325
        l = len + sizeof(struct eth_header);
326
        if (l < 60) {
327
                for (i = l; i <= 60; i++) *((BYTE *)p + i) = 0;
328
                l = 60;
329
        }
330
        buff.len = l;
331
        buff.data = p;
332
        device0.hard_start_xmit(&buff, &device0);
333
/*    lowlev_send(eth_dev.BaseAddress, p, l);*/
334
        return TRUE;
335
}
336
 
337
int eth_exc(int err)
338
{
339
        int p;
340
 
341
         if (err != ETH_BUFFERS_FULL) cprintf("Ethernet : ");
342
        switch (err) {
343
        case ETH_DRIVER_NOT_FOUND :
344
                cprintf("NET PANIC --> Etherlink not found.\n");
345
                return 0;
346
        case ETH_RXERROR :
347
                cprintf("Receive error (vero dramma!!!).\n");
348
                return 0;
349
        case ETH_TXERROR :
350
                cprintf("Transimit error: N. Max Retry.\n");
351
                return 0;
352
        case ETH_PROTOCOL_ERROR :
353
                cprintf("Too much protocols.\n");
354
                return 0;
355
        case ETH_BUFFERS_FULL:
356
                cprintf("Buffers full: frame lost!\n");
357
                return 1;
358
        case ETH_NULLPROTOCOL_EXC:
359
                cprintf("Null protocol called!!!\n");
360
                for (p = 0; p < ETH_MAX_PROTOCOLS; p++) {
361
                cprintf("%d:   %d\n", p, eth_table[p].type);
362
                }
363
                return 0;
364
        default :
365
                return 1;
366
        }
367
}
368
 
369
int eth_init(int mode, TASK_MODEL *m)
370
{
371
        SOFT_TASK_MODEL m_soft;
372
        int i, ndev;
373
        WORD Class;
374
        struct pci_regs *r;
375
        PID p;
376
        BYTE cardtype;
377
        int linux_found = 0;
378
 
379
        if (!ethIsInstalled) {
380
                cprintf("                Hartik Net lib\n\n");
381
                /* Scan the devices connected to the PCI bus */
382
                cardtype = NONE;
383
 
384
                skb_init();
385
                NetRxPort = port_create("NetPort",sizeof(struct sk_buff),50,STREAM,WRITE);
386
                if (!m) {
387
                  soft_task_default_model(m_soft);
388
                  soft_task_def_wcet(m_soft, 1000);
389
                  soft_task_def_period(m_soft,20000);
390
                  soft_task_def_met(m_soft, 1000);
391
                  soft_task_def_aperiodic(m_soft);
392
                  soft_task_def_system(m_soft);
393
                  soft_task_def_nokill(m_soft);
394
                  m = &m_soft;
395
                }
396
 
397
                nettask_pid = task_create("rxProc", net_extern_driver, m, NULL);
398
                if (nettask_pid == NIL) {
399
                  cprintf("Can't create extern driver!!!\n");
400
                        return 0;
401
                }
402
                task_activate(nettask_pid);
403
                if (pci_init() == 1) {
404
                        linuxpci_init();
405
//                              pci_show();
406
                        cprintf("LF %d\n", linux_found);
407
                        linux_found += (rtl8139_probe(&device0) == 0);
408
                        cprintf("LF %d\n", linux_found);
409
 
410
                        linux_found += (tc59x_probe(&device0) == 0);
411
                        cprintf("LF %d\n", linux_found);
412
#if 0
413
                ndev = pci_scan_bus(pci_devs);
414
#ifdef __ETH_DBG__
415
pci_show(pci_devs, ndev);
416
#endif
417
                for (i = 0; i < ndev; i++) {
418
                r = (struct pci_regs *) pci_devs[i].mem;
419
                Class = r->ClassCode;
420
                /* Is there a network card? */
421
                if (Class == 0x0200) {
422
                        if (cardtype == NONE) {
423
                        cardtype = UNKNOWN;
424
                        }
425
                /* is it a 3COM card? */
426
                        if (r->VendorId == 0x10b7) {
427
                        /* YES!!!!!! */
428
                        lowlev_info = vortex_info;
429
                                lowlev_readregs = vortex_readregs;
430
                                lowlev_open = vortex_open;
431
                                lowlev_close = vortex_close;
432
                                if (mode == TXTASK) {
433
                                lowlev_send = vortex_send_msg;
434
                        } else {
435
                                lowlev_send = vortex_send_mem;
436
                        }
437
                        cprintf("PCI Ethlink card found:\n");
438
                        lowlev_info(r);
439
                        cardtype = VORTEX;
440
                        }
441
                }
442
                }
443
        }
444
        if ((cardtype == NONE) || (cardtype == UNKNOWN)) {
445
                exc_raise(ETH_DRIVER_NOT_FOUND);
446
        }
447
/*PUT HERE THE PFUN INIT!!!*/
448
        if (cardtype == VORTEX) {
449
        }
450
        /*
451
           Use it if you want to see the value of the internal
452
           registers of the card
453
        */
454
        /*vortex_readregs(eth_dev.BaseAddress);*/
455
 
456
        p = lowlev_open(eth_dev.BaseAddress, mode);
457
 
458
        /* Set the Fast Handler and the external process */
459
        handler_set(eth_dev.IntLine, net_handler, p);
460
#else
461
                }
462
                if (linux_found == 0) {
463
                                linux_found += (el3_probe(&device0) == 0);
464
                        cprintf("LF %d\n", linux_found);
465
                                linux_found += (ne_probe(&device0) == 0);
466
                        cprintf("LF %d\n", linux_found);
467
                }
468
 
469
/*
470
                if (mode & LOOPBACK) {
471
                        cprintf("Installing loopback device (forced)\n");
472
                        loopback_init(&device0);
473
                }
474
*/
475
                if (linux_found) {
476
                        device0.open(&device0);
477
                        cprintf("Net card found!!!\n");
478
                } else {
479
                        cprintf("No card found... \n");
480
/*          cprintf("No card found... Installing loopback device\n");
481
                        loopback_init(&device0);
482
                        device0.open(&device0);*/
483
                        return 0;
484
                }
485
#endif
486
 
487
//      netbuff_init(&rxbuff, ETH_RX_BUFFERS, ETH_MAX_LEN);
488
//      netbuff_init(&txbuff, ETH_TX_BUFFERS, ETH_MAX_LEN);
489
 
490
                definedprotocols = 0;
491
                for (i = 0; i < ETH_MAX_PROTOCOLS; i++) {
492
                        eth_table[i].type = 0;
493
                        eth_table[i].rfun = eth_nullfun;
494
                }
495
                ethIsInstalled = TRUE;
496
        /* Don't crash the system at the exit, please :) */
497
                sys_atrunlevel(eth_close,NULL,RUNLEVEL_BEFORE_EXIT);
498
 
499
        } else {
500
                cprintf("Ethernet already installed!!!\n");
501
                return 0;
502
        }
503
        return 1;
504
}
505
 
506
void eth_close(void *a)
507
{
508
        kern_printf("CLOSE!!!!\n");
509
        if (ethIsInstalled == TRUE) {
510
        device0.stop(&device0);     /*This seems to break everithing...
511
//  lowlev_close(eth_dev.BaseAddress);*/
512
                ethIsInstalled = FALSE;
513
        }
514
}