Subversion Repositories shark

Rev

Rev 389 | Details | Compare with Previous | 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
 ------------
442 giacomo 23
 CVS :        $Id: eth.c,v 1.7 2004-02-05 11:42:57 giacomo Exp $
2 pj 24
 
25
 File:        $File$
442 giacomo 26
 Revision:    $Revision: 1.7 $
27
 Last update: $Date: 2004-02-05 11:42:57 $
2 pj 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
 
17 pj 77
//#define DEBUG_ETH
78
 
2 pj 79
#define ETH_PAGE        5
80
 
81
struct eth_service{
82
        WORD type;
83
        void (*rfun)(void *pkt);
84
} ETH_SERVICE;
85
 
86
int definedprotocols;
87
struct eth_service eth_table[ETH_MAX_PROTOCOLS];
88
 
89
#define ETH_RX_BUFFERS      4   
90
#define ETH_TX_BUFFERS      4
91
 
92
#ifndef ETH0_ADDR
93
# define ETH0_ADDR 0
94
#endif
95
#ifndef ETH0_IRQ
96
# define ETH0_IRQ 0
97
#endif
98
 
99
#define NONE 0
100
 
101
/*extern void net_handler(void);
102
//extern PID net_extern_driver(void);*/
103
 
104
PID nettask_pid = NIL;
105
static PORT NetRxPort;
106
 
107
/* void (*vortex_send)(DWORD BaseAddress, DWORD *txbuff, int len); */
108
 
109
int ethIsInstalled = FALSE;
110
 
111
/* device descriptor */
112
struct eth_device eth_dev;
113
struct pci_des pci_devs[5];
114
/* This is the Linux one!!! */
115
static struct device device0 = {
116
        "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, NULL, NULL};
117
struct device *dev_base = &device0;
118
 
119
/* received frames buffers */
120
extern struct netbuff rxbuff; /* from skbuff.c */
121
 
122
/* buffers for the frames to send */
123
/* struct netbuff txbuff; */
124
 
125
/* Called if an unknown frames arrives */
126
void eth_nullfun(void *pkt)
127
{
128
        kern_raise(ETH_NULLPROTOCOL_EXC,NIL);
129
}
130
 
131
 
132
 
133
 
134
void dev_tint(struct device *dev)
135
{
34 pj 136
        printk(KERN_WARNING "Warning!!!! dev_tint called!!! (Why?)\n");
2 pj 137
        sys_abort(201);
138
}
139
 
140
/*
141
   -----------------------------------------------------------------------
142
   The extern process calls this function when a frame arrives
143
   -----------------------------------------------------------------------
144
*/
145
 
146
void netif_rx(struct sk_buff *skb)
147
{
148
  //cprintf("DENTRO netif_rx, skbuf=%p\n",skb->data);
149
        if (nettask_pid == NIL) {
17 pj 150
                printk(KERN_CRIT "Net receives packets, but the driver doesn't exist!!!\n");
2 pj 151
                sys_abort(300);
152
        }
153
 
154
        port_send(NetRxPort,skb,NON_BLOCK);
155
/*  task_activate(nettask_pid);*/
156
}
157
 
158
TASK net_extern_driver(void)
159
{
160
        static PORT NetPort;
161
        struct sk_buff skb;
162
        void *pkt;
163
        int len;
164
        BYTE count;
165
        int i;
166
 
167
        NetPort = port_connect("NetPort", sizeof(struct sk_buff), STREAM, READ);
168
        while (1) {
169
/* debug... */
170
netlev = 1;
171
                port_receive(NetPort,&skb,BLOCK);  
172
                pkt = skb.data;
173
                len = skb.len;
174
 
175
                ((struct eth_header *)pkt)->type = ntohs(((struct eth_header *)pkt)->type);
176
                count = 0;
177
                /* Search for the frame protocol...*/
178
                for (i = 0; i < definedprotocols; i++) {
179
/* debug... */
180
netlev = 10 + i;
181
                        if (eth_table[i].type == (((struct eth_header *)pkt)->type)) {
182
                                count++;
183
                                /*...and call the protocol CallBack!!! */
184
                                eth_table[i].rfun(pkt);
185
                        }
186
                }
187
 
188
/* debug... */
189
                netlev = 20;
190
                //cprintf("ETH: releasing %p\n", pkt);
205 pj 191
 
192
                // NOTE changed by PJ because skb.data not always point to the
193
                // buffer start!!!... it is skb.head that always points there!
194
                netbuff_release(&rxbuff, skb.head);
2 pj 195
/* debug... */
196
netlev = 30;
197
        }
198
}
199
 
200
/*
201
   --------------------
202
   Interface functions
203
   --------------------
204
*/
205
/* formatted print of an ethernet header */
206
void eth_printHeader(struct eth_header *p)
207
{
17 pj 208
        cprintf("Dest   : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",p->dest.ad[0],
2 pj 209
                                                        p->dest.ad[1],
210
                                                        p->dest.ad[2],
211
                                                        p->dest.ad[3],
212
                                                        p->dest.ad[4],
213
                                                        p->dest.ad[5]);
214
        cprintf("Source : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",p->source.ad[0],
215
                                                        p->source.ad[1],
216
                                                        p->source.ad[2],
217
                                                        p->source.ad[3],
218
                                                        p->source.ad[4],
219
                                                        p->source.ad[5]);
220
        cprintf("Type : %x\n",p->type);
221
}
222
 
223
void eth_showinfo(struct eth_device *d)
224
{
225
        cprintf("IntLine                : %d\n",d->IntLine);
226
        cprintf("BaseAddress    : %lx\n",d->BaseAddress);
227
        cprintf("Address                : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
228
                                        d->addr.ad[0],d->addr.ad[1],d->addr.ad[2],
229
                                        d->addr.ad[3],d->addr.ad[4],d->addr.ad[5]);
230
}
231
 
232
/* formatted print of an ethernet frame*/
233
void eth_printPkt(char *pkt,int len)
234
{
235
        int i,j,offset;
236
 
237
        eth_printHeader((struct eth_header *)pkt);
238
        offset = sizeof(struct eth_header);
239
        len -= offset;
240
        for (i = 0; i < len; i += 10) {
241
        for (j = 0; j < 10; j++)
242
                cprintf("%2.2x  ",pkt[offset+i+j]);
243
        for (j = 0; j < 10; j++)
244
                cputc(pkt[offset+i+j]);
245
                cprintf("\n");
246
        }
247
        cprintf("\n");
248
}
249
 
442 giacomo 250
void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base)
251
{
252
        memcpy(dest->data,src,length);
253
}
254
 
2 pj 255
#if 0                                                                   
256
/*-------------------- User Interface -----------------------------*/
257
unsigned short htons(unsigned short host)
258
{
259
        return ((host & 0xff00) >> 8) + ((host & 0x00ff) << 8);
260
}
261
 
262
unsigned short ntohs(unsigned short host)
263
{
264
        return ((host & 0xff00) >> 8) + ((host & 0x00ff) << 8);
265
}
266
#endif
267
 
268
/*
269
   Translate an ethernet address from a text string to an eth_addr
270
   structure
271
*/
272
void eth_str2Addr(char *add, struct eth_addr *ds)
273
{
274
        int ad[6];
275
        int i,j;
276
        char c;
277
 
278
        i = 0;
279
        for(j = 0; j < 6; j++) {
280
        ad[j] = 0;
281
        while((add[i] != ':') && (add[i] != 0)) {
282
                c = add[i++];
283
                if (c <= '9') c = c - '0';
284
                else c = c - 'A' + 10;
285
                ad[j] = ad[j] * 16 + c;
286
        }
287
        i++;
288
        }
289
        for (i=0; i<6; i++) ds->ad[i] = ad[i];
290
}
291
 
292
/* Set a higher level protocol's CallBack */
293
int eth_setProtocol(WORD type, void (*recv)(void *pkt))
294
{
295
        int i;
296
 
297
        if (definedprotocols == ETH_MAX_PROTOCOLS) return FALSE;
298
        for(i = 0; i < definedprotocols; i++) {
299
        if (eth_table[i].type == type) return FALSE;
300
        }
301
        eth_table[definedprotocols].type = type;
302
        eth_table[definedprotocols++].rfun = recv;
303
        return TRUE;
304
}
305
 
306
/* Fill an ethernet frame's header and return a pointer to the frame's body */
307
void *eth_setHeader(void *b,struct eth_addr dest, WORD type)
308
{
309
        setEthAddr(((struct eth_header *)b)->dest,dest);
310
        setEthAddr(((struct eth_header *)b)->source,eth_dev.addr);
311
        /* the type field is in big-endian format */
312
        ((struct eth_header *) b)->type = htons(type);
313
        return((BYTE *)b + sizeof(struct eth_header));
314
}
315
 
316
/* getFirstDataByte : Return a pointer to the body of an ethernet frame */
317
void *eth_getFDB(void *p)
318
{
319
        return ((void *)((BYTE *)p + sizeof(struct eth_header)));
320
}
321
 
322
/* eth_getAddress : return the local ethernet address */
323
void eth_getAddress(struct eth_addr *eth)
324
{
325
        memcpy(eth->ad,&(device0.dev_addr),sizeof(struct eth_addr));
326
}
327
 
328
/* Send an ethernet frame */
329
int eth_sendPkt(void *p, int len)
330
{
331
        int i;
332
        int l;
333
        struct sk_buff buff;
334
 
335
        l = len + sizeof(struct eth_header);
336
        if (l < 60) {
337
                for (i = l; i <= 60; i++) *((BYTE *)p + i) = 0;
338
                l = 60;
339
        }
340
        buff.len = l;
341
        buff.data = p;
342
        device0.hard_start_xmit(&buff, &device0);
343
/*    lowlev_send(eth_dev.BaseAddress, p, l);*/
344
        return TRUE;
345
}
346
 
347
int eth_exc(int err)
348
{
349
        int p;
350
 
17 pj 351
         if (err != ETH_BUFFERS_FULL) printk(KERN_ERR "Ethernet : ");
2 pj 352
        switch (err) {
353
        case ETH_DRIVER_NOT_FOUND :
17 pj 354
                printk(KERN_ERR "NET PANIC --> Etherlink not found.\n");
2 pj 355
                return 0;
356
        case ETH_RXERROR :
17 pj 357
                printk(KERN_ERR "Receive error (vero dramma!!!).\n");
2 pj 358
                return 0;
359
        case ETH_TXERROR :
17 pj 360
                printk(KERN_ERR "Transimit error: N. Max Retry.\n");
2 pj 361
                return 0;
362
        case ETH_PROTOCOL_ERROR :
17 pj 363
                printk(KERN_ERR "Too much protocols.\n");
2 pj 364
                return 0;
365
        case ETH_BUFFERS_FULL:
17 pj 366
                printk(KERN_ERR "Buffers full: frame lost!\n");
2 pj 367
                return 1;
368
        case ETH_NULLPROTOCOL_EXC:
17 pj 369
                printk(KERN_ERR "Null protocol called!!!\n");
2 pj 370
                for (p = 0; p < ETH_MAX_PROTOCOLS; p++) {
17 pj 371
                printk(KERN_ERR "%d:   %d\n", p, eth_table[p].type);
2 pj 372
                }
373
                return 0;
374
        default :
375
                return 1;
376
        }
377
}
378
 
333 giacomo 379
void skb_init(void);
380
void linuxpci_init(void);
381
int rtl8139_probe(struct device *dev);
382
int tc59x_probe(struct device *dev);
383
int el3_probe(struct device *dev);
384
int ne_probe(struct device *dev);
442 giacomo 385
int eepro100_probe(struct device *dev);
333 giacomo 386
 
2 pj 387
int eth_init(int mode, TASK_MODEL *m)
388
{
389
        SOFT_TASK_MODEL m_soft;
333 giacomo 390
        int i;
391
#if 0
392
        ndev;
2 pj 393
        WORD Class;
394
        struct pci_regs *r;
395
        PID p;
333 giacomo 396
 
397
#endif
398
 
2 pj 399
        BYTE cardtype;
400
        int linux_found = 0;
401
 
402
        if (!ethIsInstalled) {
389 giacomo 403
                printk(KERN_INFO "Shark Net lib\n");
2 pj 404
                /* Scan the devices connected to the PCI bus */
405
                cardtype = NONE;
406
 
407
                skb_init();
408
                NetRxPort = port_create("NetPort",sizeof(struct sk_buff),50,STREAM,WRITE);
409
                if (!m) {
410
                  soft_task_default_model(m_soft);
411
                  soft_task_def_wcet(m_soft, 1000);
412
                  soft_task_def_period(m_soft,20000);
413
                  soft_task_def_met(m_soft, 1000);
414
                  soft_task_def_aperiodic(m_soft);
415
                  soft_task_def_system(m_soft);
416
                  soft_task_def_nokill(m_soft);
34 pj 417
                  m = (TASK_MODEL *)&m_soft;
2 pj 418
                }
419
 
420
                nettask_pid = task_create("rxProc", net_extern_driver, m, NULL);
421
                if (nettask_pid == NIL) {
17 pj 422
                  printk(KERN_ERR "Can't create extern driver!!!\n");
423
                  return 0;
2 pj 424
                }
425
                task_activate(nettask_pid);
426
                if (pci_init() == 1) {
427
                        linuxpci_init();
17 pj 428
#ifdef DEBUG_ETH
429
                        printk(KERN_DEBUG "LF %d\n", linux_found);
430
#endif
2 pj 431
                        linux_found += (rtl8139_probe(&device0) == 0);
17 pj 432
#ifdef DEBUG_ETH
433
                        printk(KERN_DEBUG "LF %d\n", linux_found);
434
#endif
2 pj 435
 
436
                        linux_found += (tc59x_probe(&device0) == 0);
17 pj 437
#ifdef DEBUG_ETH
438
                        printk(KERN_DEBUG "LF %d\n", linux_found);
439
#endif
205 pj 440
 
442 giacomo 441
                        linux_found += (eepro100_probe(&device0) == 0);
442
#ifdef DEBUG_ETH
443
                        printk(KERN_DEBUG "LF %d\n", linux_found);
444
#endif
445
 
446
 
2 pj 447
#if 0
448
                ndev = pci_scan_bus(pci_devs);
449
#ifdef __ETH_DBG__
450
pci_show(pci_devs, ndev);
451
#endif
452
                for (i = 0; i < ndev; i++) {
453
                r = (struct pci_regs *) pci_devs[i].mem;
454
                Class = r->ClassCode;
455
                /* Is there a network card? */
456
                if (Class == 0x0200) {
457
                        if (cardtype == NONE) {
458
                        cardtype = UNKNOWN;
459
                        }
460
                /* is it a 3COM card? */
461
                        if (r->VendorId == 0x10b7) {
462
                        /* YES!!!!!! */
463
                        lowlev_info = vortex_info;
464
                                lowlev_readregs = vortex_readregs;
465
                                lowlev_open = vortex_open;
466
                                lowlev_close = vortex_close;
467
                                if (mode == TXTASK) {
468
                                lowlev_send = vortex_send_msg;
469
                        } else {
470
                                lowlev_send = vortex_send_mem;
471
                        }
17 pj 472
                        printk(KERN_INFO "PCI Ethlink card found:\n");
2 pj 473
                        lowlev_info(r);
474
                        cardtype = VORTEX;
475
                        }
476
                }
477
                }
478
        }
479
        if ((cardtype == NONE) || (cardtype == UNKNOWN)) {
480
                exc_raise(ETH_DRIVER_NOT_FOUND);
481
        }
482
/*PUT HERE THE PFUN INIT!!!*/
483
        if (cardtype == VORTEX) {
484
        }
485
        /*
486
           Use it if you want to see the value of the internal
487
           registers of the card
488
        */
489
        /*vortex_readregs(eth_dev.BaseAddress);*/
490
 
491
        p = lowlev_open(eth_dev.BaseAddress, mode);
492
 
493
        /* Set the Fast Handler and the external process */
494
        handler_set(eth_dev.IntLine, net_handler, p);
495
#else
496
                }
497
                if (linux_found == 0) {
17 pj 498
                  linux_found += (el3_probe(&device0) == 0);
499
#ifdef DEBUG_ETH
500
                  printk(KERN_DEBUG "LF %d\n", linux_found);
501
#endif
502
                  linux_found += (ne_probe(&device0) == 0);
503
#ifdef DEBUG_ETH
504
                  printk(KERN_DEBUG "LF %d\n", linux_found);
505
#endif
2 pj 506
                }
507
 
508
/*
509
                if (mode & LOOPBACK) {
510
                        cprintf("Installing loopback device (forced)\n");
511
                        loopback_init(&device0);
512
                }
513
*/
514
                if (linux_found) {
515
                        device0.open(&device0);
17 pj 516
                        printk(KERN_INFO "Net card found!!!\n");
2 pj 517
                } else {
17 pj 518
                        printk(KERN_INFO "No card found... \n");
2 pj 519
/*          cprintf("No card found... Installing loopback device\n");
520
                        loopback_init(&device0);
521
                        device0.open(&device0);*/
522
                        return 0;
523
                }
524
#endif
525
 
526
//      netbuff_init(&rxbuff, ETH_RX_BUFFERS, ETH_MAX_LEN);
527
//      netbuff_init(&txbuff, ETH_TX_BUFFERS, ETH_MAX_LEN);
528
 
529
                definedprotocols = 0;
530
                for (i = 0; i < ETH_MAX_PROTOCOLS; i++) {
531
                        eth_table[i].type = 0;
532
                        eth_table[i].rfun = eth_nullfun;
533
                }
534
                ethIsInstalled = TRUE;
535
        /* Don't crash the system at the exit, please :) */
536
                sys_atrunlevel(eth_close,NULL,RUNLEVEL_BEFORE_EXIT);
537
 
538
        } else {
17 pj 539
                printk(KERN_INFO "Ethernet already installed!!!\n");
2 pj 540
                return 0;
541
        }
542
        return 1;
543
}
544
 
545
void eth_close(void *a)
546
{
17 pj 547
#ifdef DEBUG_ETH
548
  printk(KERN_DEBUG "CLOSE!!!!\n");
549
#endif
550
  if (ethIsInstalled == TRUE) {
551
    device0.stop(&device0);     /*This seems to break everithing...
552
                              //  lowlev_close(eth_dev.BaseAddress);*/
553
    ethIsInstalled = FALSE;
554
  }
2 pj 555
}