xref: /minix/minix/drivers/net/lance/lance.c (revision e3b78ef1)
1 /*
2  * lance.c
3  *
4  * This file contains a ethernet device driver for AMD LANCE based ethernet
5  * cards.
6  *
7  * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
8  * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
9  */
10 
11 #define VERBOSE 0 /* Verbose debugging output */
12 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */
13 
14 #include <minix/drivers.h>
15 #include <minix/netdriver.h>
16 
17 #include <net/hton.h>
18 #include <net/gen/ether.h>
19 #include <net/gen/eth_io.h>
20 #include <assert.h>
21 
22 #include <minix/syslib.h>
23 #include <minix/endpoint.h>
24 #include <machine/pci.h>
25 #include <minix/ds.h>
26 
27 #include "lance.h"
28 
29 static int do_init(unsigned int instance, ether_addr_t *addr);
30 static void ec_confaddr(ether_addr_t *addr);
31 static void ec_reinit(ether_card_t *ec);
32 static void ec_reset(ether_card_t *ec);
33 static void do_intr(unsigned int mask);
34 static void do_mode(unsigned int mode);
35 static int do_send(struct netdriver_data *data, size_t size);
36 static ssize_t do_recv(struct netdriver_data *data, size_t max);
37 static void do_stat(eth_stat_t *stat);
38 static void do_stop(void);
39 static void lance_dump(void);
40 static void do_other(const message *m_ptr, int ipc_status);
41 static void get_addressing(int devind, ether_card_t *ec);
42 static int lance_probe(ether_card_t *ec, unsigned int skip);
43 static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr);
44 
45 /* Accesses Lance Control and Status Registers */
46 static u8_t in_byte(port_t port);
47 static u16_t in_word(port_t port);
48 static void out_word(port_t port, u16_t value);
49 static u16_t read_csr(port_t ioaddr, u16_t csrno);
50 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value);
51 
52 static ether_card_t ec_state;
53 static int ec_instance;
54 
55 /* --- LANCE --- */
56 /* General */
57 typedef uint32_t Address;
58 
59 #define ETH_FRAME_LEN           1518
60 
61 #define LANCE_MUST_PAD          0x00000001
62 #define LANCE_ENABLE_AUTOSELECT 0x00000002
63 #define LANCE_SELECT_PHONELINE  0x00000004
64 #define LANCE_MUST_UNRESET      0x00000008
65 
66 static const struct lance_chip_type
67 {
68    int        id_number;
69    const char *name;
70    int        flags;
71 } chip_table[] = {
72    {0x0000, "LANCE 7990",           /* Ancient lance chip.  */
73     LANCE_MUST_PAD + LANCE_MUST_UNRESET},
74    {0x0003, "PCnet/ISA 79C960",     /* 79C960 PCnet/ISA.  */
75     LANCE_ENABLE_AUTOSELECT},
76    {0x2260, "PCnet/ISA+ 79C961",    /* 79C961 PCnet/ISA+, Plug-n-Play.  */
77     LANCE_ENABLE_AUTOSELECT},
78    {0x2420, "PCnet/PCI 79C970",     /* 79C970 or 79C974 PCnet-SCSI, PCI. */
79     LANCE_ENABLE_AUTOSELECT},
80    {0x2430, "PCnet32",              /* 79C965 PCnet for VL bus. */
81     LANCE_ENABLE_AUTOSELECT},
82    {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
83     LANCE_ENABLE_AUTOSELECT},
84    {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
85     LANCE_ENABLE_AUTOSELECT},
86    {0x2626, "PCnet/HomePNA 79C978",
87     LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
88    {0x0, "PCnet (unknown)",
89     LANCE_ENABLE_AUTOSELECT},
90 };
91 
92 /* ############## for LANCE device ############## */
93 #define LANCE_ETH_ADDR          0x0
94 #define LANCE_DATA              0x10
95 #define LANCE_ADDR              0x12
96 #define LANCE_RESET             0x14
97 #define LANCE_BUS_IF            0x16
98 #define LANCE_TOTAL_SIZE        0x18
99 
100 /* Use 2^4=16 {Rx,Tx} buffers */
101 #define LANCE_LOG_RX_BUFFERS    4
102 #define RX_RING_SIZE            (1 << (LANCE_LOG_RX_BUFFERS))
103 #define RX_RING_MOD_MASK        (RX_RING_SIZE - 1)
104 #define RX_RING_LEN_BITS        ((LANCE_LOG_RX_BUFFERS) << 29)
105 
106 #define LANCE_LOG_TX_BUFFERS    4
107 #define TX_RING_SIZE            (1 << (LANCE_LOG_TX_BUFFERS))
108 #define TX_RING_MOD_MASK        (TX_RING_SIZE - 1)
109 #define TX_RING_LEN_BITS        ((LANCE_LOG_TX_BUFFERS) << 29)
110 
111 /* for lance_interface */
112 struct lance_init_block
113 {
114    unsigned short  mode;
115    unsigned char   phys_addr[6];
116    unsigned long   filter[2];
117    Address         rx_ring;
118    Address         tx_ring;
119 };
120 
121 struct lance_rx_head
122 {
123    union {
124       Address         base;
125       unsigned char   addr[4];
126    } u;
127    short           buf_length;     /* 2s complement */
128    short           msg_length;
129 };
130 
131 struct lance_tx_head
132 {
133    union {
134       Address         base;
135       unsigned char   addr[4];
136    } u;
137    short           buf_length;     /* 2s complement */
138    short           misc;
139 };
140 
141 struct lance_interface
142 {
143    struct lance_init_block init_block;
144    struct lance_rx_head    rx_ring[RX_RING_SIZE];
145    struct lance_tx_head    tx_ring[TX_RING_SIZE];
146    unsigned char           rbuf[RX_RING_SIZE][ETH_FRAME_LEN];
147    unsigned char           tbuf[TX_RING_SIZE][ETH_FRAME_LEN];
148 };
149 
150 /* =============== global variables =============== */
151 /* AKA the stuff that really should have been in ether_card_t */
152 static struct lance_interface  *lp;
153 #define LANCE_BUF_SIZE (sizeof(struct lance_interface))
154 static char *lance_buf = NULL;
155 static int rx_slot_nr = 0;          /* Rx-slot number */
156 static int tx_slot_nr = 0;          /* Tx-slot number */
157 static int cur_tx_slot_nr = 0;      /* Tx-slot number */
158 static phys_bytes tx_ring_base[TX_RING_SIZE]; /* Tx-slot physical address */
159 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
160 
161 static const struct netdriver lance_table = {
162    .ndr_init = do_init,
163    .ndr_stop = do_stop,
164    .ndr_mode = do_mode,
165    .ndr_recv = do_recv,
166    .ndr_send = do_send,
167    .ndr_stat = do_stat,
168    .ndr_intr = do_intr,
169    .ndr_other = do_other,
170 };
171 
172 /*===========================================================================*
173  *                              main                                         *
174  *===========================================================================*/
175 int main(int argc, char **argv)
176 {
177 
178    env_setargs(argc, argv);
179 
180    netdriver_task(&lance_table);
181 
182    return 0;
183 }
184 
185 /*===========================================================================*
186  *                              lance_dump                                   *
187  *===========================================================================*/
188 static void lance_dump()
189 {
190    ether_card_t *ec;
191    int isr, csr;
192    unsigned short ioaddr;
193 
194    printf("\n");
195    ec = &ec_state;
196 
197    printf("lance statistics of instance %d:\n", ec_instance);
198 
199    printf("recvErr    :%8ld\t", ec->eth_stat.ets_recvErr);
200    printf("sendErr    :%8ld\t", ec->eth_stat.ets_sendErr);
201    printf("OVW        :%8ld\n", ec->eth_stat.ets_OVW);
202 
203    printf("CRCerr     :%8ld\t", ec->eth_stat.ets_CRCerr);
204    printf("frameAll   :%8ld\t", ec->eth_stat.ets_frameAll);
205    printf("missedP    :%8ld\n", ec->eth_stat.ets_missedP);
206 
207    printf("packetR    :%8ld\t", ec->eth_stat.ets_packetR);
208    printf("packetT    :%8ld\t", ec->eth_stat.ets_packetT);
209    printf("transDef   :%8ld\n", ec->eth_stat.ets_transDef);
210 
211    printf("collision  :%8ld\t", ec->eth_stat.ets_collision);
212    printf("transAb    :%8ld\t", ec->eth_stat.ets_transAb);
213    printf("carrSense  :%8ld\n", ec->eth_stat.ets_carrSense);
214 
215    printf("fifoUnder  :%8ld\t", ec->eth_stat.ets_fifoUnder);
216    printf("fifoOver   :%8ld\t", ec->eth_stat.ets_fifoOver);
217    printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
218 
219    printf("OWC        :%8ld\t", ec->eth_stat.ets_OWC);
220 
221    ioaddr = ec->ec_port;
222    isr = read_csr(ioaddr, LANCE_CSR0);
223    printf("isr = 0x%x, flags = 0x%x\n", isr,
224              ec->flags);
225 
226    printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
227 
228    csr = read_csr(ioaddr, LANCE_CSR0);
229    printf("CSR0: 0x%x\n", csr);
230    csr = read_csr(ioaddr, LANCE_CSR3);
231    printf("CSR3: 0x%x\n", csr);
232    csr = read_csr(ioaddr, LANCE_CSR4);
233    printf("CSR4: 0x%x\n", csr);
234    csr = read_csr(ioaddr, LANCE_CSR5);
235    printf("CSR5: 0x%x\n", csr);
236    csr = read_csr(ioaddr, LANCE_CSR15);
237    printf("CSR15: 0x%x\n", csr);
238 }
239 
240 /*===========================================================================*
241  *                              do_other                                     *
242  *===========================================================================*/
243 static void do_other(const message *m_ptr, int ipc_status)
244 {
245 
246    if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR)
247       lance_dump();
248 }
249 
250 /*===========================================================================*
251  *                              ec_confaddr                                  *
252  *===========================================================================*/
253 static void ec_confaddr(ether_addr_t *addr)
254 {
255    int i;
256    char eakey[16];
257    static char eafmt[]= "x:x:x:x:x:x";
258    long v;
259 
260    /* User defined ethernet address? */
261    strlcpy(eakey, "LANCE0_EA", sizeof(eakey));
262    eakey[5] += ec_instance;
263 
264    for (i = 0; i < 6; i++)
265    {
266       v= addr->ea_addr[i];
267       if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
268          break;
269       addr->ea_addr[i]= v;
270    }
271 
272    if (i != 0 && i != 6)
273    {
274       /* It's all or nothing; force a panic. */
275       panic("invalid ethernet address supplied");
276    }
277 }
278 
279 /*===========================================================================*
280  *		                do_init                                      *
281  *===========================================================================*/
282 static int do_init(unsigned int instance, ether_addr_t *addr)
283 {
284 /* Initialize the lance driver. */
285    ether_card_t *ec;
286 #if VERBOSE
287    int i, r;
288 #endif
289 #if LANCE_FKEY
290    int fkeys, sfkeys;
291 #endif
292 
293 #if LANCE_FKEY
294    fkeys = sfkeys = 0;
295    bit_set( sfkeys, 7 );
296    if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
297       printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
298 #endif
299 
300    ec_instance = instance;
301 
302    /* Initialize the driver state. */
303    ec= &ec_state;
304    memset(ec, 0, sizeof(*ec));
305    strlcpy(ec->port_name, "lance#0", sizeof(ec->port_name));
306    ec->port_name[6] += instance;
307 
308    /* See if there is a matching card. */
309    if (!lance_probe(ec, instance))
310       return ENXIO;
311 
312    /* Initialize the hardware. */
313    lance_init_hw(ec, addr);
314 
315 #if VERBOSE
316    printf("%s: Ethernet address ", ec->port_name);
317    for (i= 0; i < 6; i++)
318       printf("%x%c", addr->ea_addr[i], i < 5 ? ':' : '\n');
319 #endif
320 
321    return OK;
322 }
323 
324 /*===========================================================================*
325  *                              ec_reinit                                    *
326  *===========================================================================*/
327 static void ec_reinit(ether_card_t *ec)
328 {
329    int i;
330    unsigned short ioaddr = ec->ec_port;
331 
332    /* stop */
333    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
334 
335    /* purge Tx-ring */
336    tx_slot_nr = cur_tx_slot_nr = 0;
337    for (i=0; i<TX_RING_SIZE; i++)
338    {
339       lp->tx_ring[i].u.base = 0;
340       isstored[i]=0;
341    }
342 
343    /* re-init Rx-ring */
344    rx_slot_nr = 0;
345    for (i=0; i<RX_RING_SIZE; i++)
346    {
347       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
348       lp->rx_ring[i].u.addr[3] |= 0x80;
349    }
350 
351    /* Set 'Receive Mode' */
352    if (ec->flags & ECF_PROMISC)
353    {
354       write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
355    }
356    else
357    {
358       if (ec->flags & (ECF_BROAD | ECF_MULTI))
359       {
360          write_csr(ioaddr, LANCE_CSR15, 0x0000);
361       }
362       else
363       {
364          write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
365       }
366    }
367 
368    /* start && enable interrupt */
369    write_csr(ioaddr, LANCE_CSR0,
370              LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
371 
372    return;
373 }
374 
375 /*===========================================================================*
376  *                              do_mode                                      *
377  *===========================================================================*/
378 static void do_mode(unsigned int mode)
379 {
380    ether_card_t *ec;
381 
382    ec = &ec_state;
383 
384    ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD);
385 
386    if (mode & NDEV_PROMISC)
387       ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD;
388    if (mode & NDEV_MULTI)
389       ec->flags |= ECF_MULTI;
390    if (mode & NDEV_BROAD)
391       ec->flags |= ECF_BROAD;
392 
393    ec_reinit(ec);
394 }
395 
396 /*===========================================================================*
397  *                              do_intr                                      *
398  *===========================================================================*/
399 static void do_intr(unsigned int __unused mask)
400 {
401    ether_card_t *ec;
402    int must_restart = 0;
403    int r, check, status;
404    int isr = 0x0000;
405    unsigned short ioaddr;
406 
407    ec = &ec_state;
408    ioaddr = ec->ec_port;
409 
410    for (;;)
411    {
412 #if VERBOSE
413       printf("ETH: Reading ISR...");
414 #endif
415       isr = read_csr(ioaddr, LANCE_CSR0);
416       if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) {
417          write_csr(ioaddr, LANCE_CSR0,
418                    isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP
419                            |LANCE_CSR0_STRT|LANCE_CSR0_INIT) );
420       }
421       write_csr(ioaddr, LANCE_CSR0,
422                 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR
423                 |LANCE_CSR0_IDON|LANCE_CSR0_IENA);
424 
425       if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS
426                   |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000)
427       {
428 #if VERBOSE
429          printf("OK\n");
430 #endif
431          break;
432       }
433 
434       if (isr & LANCE_CSR0_MISS)
435       {
436 #if VERBOSE
437          printf("RX Missed Frame\n");
438 #endif
439          ec->eth_stat.ets_recvErr++;
440       }
441       if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT))
442       {
443          if (isr & LANCE_CSR0_BABL)
444          {
445 #if VERBOSE
446             printf("TX Timeout\n");
447 #endif
448             ec->eth_stat.ets_sendErr++;
449          }
450          if (isr & LANCE_CSR0_TINT)
451          {
452 #if VERBOSE
453             printf("TX INT\n");
454 #endif
455             /* status check: restart if needed. */
456             status = lp->tx_ring[cur_tx_slot_nr].u.base;
457 
458             /* did an error (UFLO, LCOL, LCAR, RTRY) occur? */
459             if (status & 0x40000000)
460             {
461                status = lp->tx_ring[cur_tx_slot_nr].misc;
462                ec->eth_stat.ets_sendErr++;
463                if (status & 0x0400) /* RTRY */
464                   ec->eth_stat.ets_transAb++;
465                if (status & 0x0800) /* LCAR */
466                   ec->eth_stat.ets_carrSense++;
467                if (status & 0x1000) /* LCOL */
468                   ec->eth_stat.ets_OWC++;
469                if (status & 0x4000) /* UFLO */
470                {
471                   ec->eth_stat.ets_fifoUnder++;
472                   must_restart=1;
473                }
474             }
475             else
476             {
477                if (status & 0x18000000)
478                   ec->eth_stat.ets_collision++;
479                ec->eth_stat.ets_packetT++;
480             }
481          }
482          /* transmit a packet on the next slot if it exists. */
483          check = 0;
484          if (isstored[cur_tx_slot_nr]==1)
485          {
486             /* free the tx-slot just transmitted */
487             isstored[cur_tx_slot_nr]=0;
488             cur_tx_slot_nr = (cur_tx_slot_nr + 1) & TX_RING_MOD_MASK;
489 
490             /* next tx-slot is ready? */
491             if (isstored[cur_tx_slot_nr]==1)
492                check=1;
493             else
494                check=0;
495          }
496          else
497          {
498             panic("got premature TX INT..");
499          }
500          if (check==1)
501          {
502             lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
503             write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
504          }
505          /* we set a buffered message in the slot if it exists. */
506          /* and transmit it, if needed. */
507          if (!must_restart)
508             netdriver_send();
509       }
510       if (isr & LANCE_CSR0_RINT)
511       {
512 #if VERBOSE
513          printf("RX INT\n");
514 #endif
515          netdriver_recv();
516       }
517 
518       if (must_restart == 1)
519       {
520 #if VERBOSE
521          printf("ETH: restarting...\n");
522 #endif
523 
524          ec_reset(ec);
525       }
526    }
527 
528    /* reenable interrupts */
529    if ((r = sys_irqenable(&ec->ec_hook)) != OK)
530       panic("couldn't enable interrupt: %d", r);
531 }
532 
533 /*===========================================================================*
534  *                              ec_reset                                     *
535  *===========================================================================*/
536 static void ec_reset(ether_card_t *ec)
537 {
538    /* Stop/start the chip, and clear all RX,TX-slots.  The spec says this type
539     * of reset should be done on MERR, UFLO, and TX BUFF errors.  For now it is
540     * called only for UFLO and TX BUFF (which causes UFLO).  MERR is not (yet?)
541     * handled.  Also note that the PCnet spec says that the LANCE chip does not
542     * require resetting Rx/Tx, but PCnet does.  We intend to support both here.
543     */
544    unsigned short ioaddr = ec->ec_port;
545    int i;
546 
547    /* stop */
548    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
549    /* start */
550    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
551 
552    /* purge Tx-ring */
553    tx_slot_nr = cur_tx_slot_nr = 0;
554    for (i=0; i<TX_RING_SIZE; i++)
555    {
556       lp->tx_ring[i].u.base = 0;
557       isstored[i]=0;
558    }
559 
560    /* re-init Rx-ring */
561    rx_slot_nr = 0;
562    for (i=0; i<RX_RING_SIZE; i++)
563    {
564       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
565       lp->rx_ring[i].u.addr[3] |= 0x80;
566    }
567 
568    /* store a buffered message on the slot if it exists */
569    netdriver_send();
570 }
571 
572 /*===========================================================================*
573  *                              do_recv                                      *
574  *===========================================================================*/
575 static ssize_t do_recv(struct netdriver_data *data, size_t max)
576 {
577    ether_card_t *ec;
578    vir_bytes length;
579    int packet_processed;
580    int status;
581    unsigned short ioaddr;
582 
583    ec = &ec_state;
584    ioaddr = ec->ec_port;
585 
586    /* we check all the received slots until find a properly received packet */
587    packet_processed = FALSE;
588    while (!packet_processed)
589    {
590       status = lp->rx_ring[rx_slot_nr].u.base >> 24;
591 
592       /* is the slot marked as ready? */
593       if ( (status & 0x80) != 0x00 )
594          return SUSPEND; /* no */
595 
596       /* did an error occur? */
597       if (status != 0x03)
598       {
599          if (status & 0x01)
600             ec->eth_stat.ets_recvErr++;
601          if (status & 0x04)
602             ec->eth_stat.ets_fifoOver++;
603          if (status & 0x08)
604             ec->eth_stat.ets_CRCerr++;
605          if (status & 0x10)
606              ec->eth_stat.ets_OVW++;
607          if (status & 0x20)
608              ec->eth_stat.ets_frameAll++;
609          length = 0;
610       }
611       else
612       {
613          ec->eth_stat.ets_packetR++;
614          length = lp->rx_ring[rx_slot_nr].msg_length;
615       }
616 
617       /* do we now have a valid packet? */
618       if (length > 0)
619       {
620 	 if (length > max)
621 	    length = max;
622          netdriver_copyout(data, 0, lp->rbuf[rx_slot_nr], length);
623          packet_processed = TRUE;
624       }
625 
626       /* set up this slot again, and we move to the next slot */
627       lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN;
628       lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80;
629 
630       write_csr(ioaddr, LANCE_CSR0,
631                 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS
632                 |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA);
633 
634       rx_slot_nr = (rx_slot_nr + 1) & RX_RING_MOD_MASK;
635    }
636 
637    /* return the length of the packet we have received */
638    return length;
639 }
640 
641 /*===========================================================================*
642  *                              do_send                                      *
643  *===========================================================================*/
644 static int do_send(struct netdriver_data *data, size_t size)
645 {
646    int check;
647    ether_card_t *ec;
648    unsigned short ioaddr;
649 
650    ec = &ec_state;
651 
652    /* if all slots are used, this request must be deferred */
653    if (isstored[tx_slot_nr]==1)
654       return SUSPEND;
655 
656    /* copy the packet to the slot on DMA address */
657    netdriver_copyin(data, 0, lp->tbuf[tx_slot_nr], size);
658 
659    /* set-up for transmitting, and transmit it if needed. */
660    lp->tx_ring[tx_slot_nr].buf_length = -size;
661    lp->tx_ring[tx_slot_nr].misc = 0x0;
662    lp->tx_ring[tx_slot_nr].u.base = tx_ring_base[tx_slot_nr];
663    isstored[tx_slot_nr]=1;
664    if (cur_tx_slot_nr == tx_slot_nr)
665       check=1;
666    else
667       check=0;
668    tx_slot_nr = (tx_slot_nr + 1) & TX_RING_MOD_MASK;
669 
670    if (check == 1)
671    {
672       ioaddr = ec->ec_port;
673       lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
674       write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
675    }
676 
677    return OK;
678 }
679 
680 /*===========================================================================*
681  *                              do_stat                                      *
682  *===========================================================================*/
683 static void do_stat(eth_stat_t *stat)
684 {
685 
686    memcpy(stat, &ec_state.eth_stat, sizeof(*stat));
687 }
688 
689 /*===========================================================================*
690  *                              do_stop                                      *
691  *===========================================================================*/
692 static void do_stop(void)
693 {
694    ether_card_t *ec;
695    unsigned short ioaddr;
696 
697    ec = &ec_state;
698 
699    ioaddr = ec->ec_port;
700 
701    /* stop */
702    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
703 
704    /* Reset */
705    in_word(ioaddr+LANCE_RESET);
706 }
707 
708 /*===========================================================================*
709  *                              get_addressing                               *
710  *===========================================================================*/
711 static void get_addressing(int devind, ether_card_t *ec)
712 {
713    unsigned int ioaddr;
714    int reg, irq;
715 
716    for (reg = PCI_BAR; reg <= PCI_BAR_6; reg += 4)
717    {
718       ioaddr = pci_attr_r32(devind, reg);
719 
720       if ((ioaddr & PCI_BAR_IO_MASK) == 0 || (ioaddr & PCI_BAR_IO) == 0)
721          continue;
722       /* Strip the I/O address out of the returned value */
723       ioaddr &= PCI_BAR_IO_MASK;
724       ec->ec_port = ioaddr;
725    }
726 
727    /* KK: Get the IRQ number */
728    irq = pci_attr_r8(devind, PCI_IPR);
729    if (irq)
730       irq = pci_attr_r8(devind, PCI_ILR);
731    ec->ec_irq = irq;
732 }
733 
734 /*===========================================================================*
735  *                              lance_probe                                  *
736  *===========================================================================*/
737 static int lance_probe(ether_card_t *ec, unsigned int skip)
738 {
739    unsigned short    pci_cmd;
740    unsigned short    ioaddr;
741    int               lance_version, chip_version;
742    int devind, r;
743    u16_t vid, did;
744 
745    pci_init();
746 
747    r= pci_first_dev(&devind, &vid, &did);
748    if (r == 0)
749       return 0;
750 
751    while (skip--)
752    {
753       r= pci_next_dev(&devind, &vid, &did);
754       if (!r)
755          return 0;
756    }
757 
758    pci_reserve(devind);
759 
760    get_addressing(devind, ec);
761 
762    /* ===== Bus Master ? ===== */
763    pci_cmd = pci_attr_r32(devind, PCI_CR);
764    if (!(pci_cmd & PCI_CR_MAST_EN)) {
765       pci_cmd |= PCI_CR_MAST_EN;
766       pci_attr_w32(devind, PCI_CR, pci_cmd);
767    }
768 
769    /* ===== Probe Details ===== */
770    ioaddr = ec->ec_port;
771 
772    /* Reset */
773    in_word(ioaddr+LANCE_RESET);
774 
775    if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP)
776    {
777       return 0;
778    }
779 
780    /* Probe Chip Version */
781    out_word(ioaddr+LANCE_ADDR, 88);     /* Get the version of the chip */
782    if (in_word(ioaddr+LANCE_ADDR) != 88)
783       lance_version = 0;
784    else
785    {
786       chip_version = read_csr(ioaddr, LANCE_CSR88);
787       chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16;
788 
789       if ((chip_version & 0xfff) != 0x3)
790       {
791 	 return 0;
792       }
793       chip_version = (chip_version >> 12) & 0xffff;
794       for (lance_version = 1; chip_table[lance_version].id_number != 0;
795            ++lance_version)
796          if (chip_table[lance_version].id_number == chip_version)
797             break;
798    }
799 
800 #if VERBOSE
801    printf("%s: %s at %X:%d\n",
802           ec->port_name, chip_table[lance_version].name,
803           ec->ec_port, ec->ec_irq);
804 #endif
805 
806    return lance_version;
807 }
808 
809 /*===========================================================================*
810  *                              virt_to_bus                                  *
811  *===========================================================================*/
812 static phys_bytes virt_to_bus(void *ptr)
813 {
814    phys_bytes value;
815    int r;
816 
817    if ((r = sys_umap(SELF, VM_D, (vir_bytes)ptr, 4, &value)) != OK)
818       panic("sys_umap failed: %d", r);
819 
820    return value;
821 }
822 
823 /*===========================================================================*
824  *                              lance_init_hw                                *
825  *===========================================================================*/
826 static void lance_init_hw(ether_card_t *ec, ether_addr_t *addr)
827 {
828    phys_bytes lance_buf_phys;
829    int i, r;
830    Address l;
831    unsigned short ioaddr = ec->ec_port;
832 
833    /* ============= setup init_block(cf. lance_probe1) ================ */
834    /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */
835 
836    /* Allocate memory */
837    if ((lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M,
838      &lance_buf_phys)) == NULL)
839       panic("alloc_contig failed: %d", LANCE_BUF_SIZE);
840 
841    l = (vir_bytes)lance_buf;
842    lp = (struct lance_interface *)l;
843 
844    /* disable Tx and Rx */
845    lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX;
846    lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
847    /* using multiple Rx/Tx buffer */
848    lp->init_block.rx_ring
849       = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
850    lp->init_block.tx_ring
851       = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
852 
853    l = virt_to_bus(&lp->init_block);
854    write_csr(ioaddr, LANCE_CSR1, (unsigned short)l);
855    write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16));
856    write_csr(ioaddr, LANCE_CSR4,
857              LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
858              |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
859 
860    /* ============= Get MAC address (cf. lance_probe1) ================ */
861    for (i = 0; i < 6; ++i)
862       addr->ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i);
863 
864    /* Allow the user to override the hardware address. */
865    ec_confaddr(addr);
866 
867    /* ============ (re)start init_block(cf. lance_reset) =============== */
868    /* Reset the LANCE */
869    (void)in_word(ioaddr+LANCE_RESET);
870 
871    /* ----- Re-initialize the LANCE ----- */
872    /* Set station address */
873    for (i = 0; i < 6; ++i)
874       lp->init_block.phys_addr[i] = addr->ea_addr[i];
875    /* Preset the receive ring headers */
876    for (i=0; i<RX_RING_SIZE; i++)
877    {
878       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
879       /* OWN */
880       lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
881       /* we set the top byte as the very last thing */
882       lp->rx_ring[i].u.addr[3] = 0x80;
883    }
884    /* Preset the transmitting ring headers */
885    for (i=0; i<TX_RING_SIZE; i++)
886    {
887       lp->tx_ring[i].u.base = 0;
888       tx_ring_base[i] = virt_to_bus(lp->tbuf[i]) & 0xffffff;
889       isstored[i] = 0;
890    }
891    /* enable Rx and Tx */
892    lp->init_block.mode = 0x0;
893 
894    l = (Address)virt_to_bus(&lp->init_block);
895    write_csr(ioaddr, LANCE_CSR1, (short)l);
896    write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16));
897    write_csr(ioaddr, LANCE_CSR4,
898              LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
899              |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
900 
901    /* ----- start when init done. ----- */
902    /* stop */
903    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
904    /* init */
905    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT);
906    /* poll for IDON */
907    for (i = 10000; i > 0; --i)
908       if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON)
909          break;
910 
911    /* Set 'Multicast Table' */
912    for (i=0;i<4;++i)
913    {
914       write_csr(ioaddr, LANCE_CSR8 + i, 0xffff);
915    }
916 
917    /* Set 'Receive Mode' */
918    if (ec->flags & ECF_PROMISC)
919    {
920       write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
921    }
922    else
923    {
924       if (ec->flags & (ECF_BROAD | ECF_MULTI))
925       {
926          write_csr(ioaddr, LANCE_CSR15, 0x0000);
927       }
928       else
929       {
930          write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
931       }
932    }
933 
934    /* Set the interrupt handler */
935    ec->ec_hook = ec->ec_irq;
936    if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK)
937       panic("couldn't set IRQ policy: %d", r);
938    if ((r = sys_irqenable(&ec->ec_hook)) != OK)
939       panic("couldn't enable interrupt: %d", r);
940 
941    /* start && enable interrupt */
942    write_csr(ioaddr, LANCE_CSR0,
943              LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
944 }
945 
946 /*===========================================================================*
947  *                              in_byte                                      *
948  *===========================================================================*/
949 static u8_t in_byte(port_t port)
950 {
951 	int r;
952 	u32_t value;
953 
954 	r= sys_inb(port, &value);
955 	if (r != OK)
956 		panic("sys_inb failed: %d", r);
957 	return value;
958 }
959 
960 /*===========================================================================*
961  *                              in_word                                      *
962  *===========================================================================*/
963 static u16_t in_word(port_t port)
964 {
965 	int r;
966 	u32_t value;
967 
968 	r= sys_inw(port, &value);
969 	if (r != OK)
970 		panic("sys_inw failed: %d", r);
971 	return value;
972 }
973 
974 
975 /*===========================================================================*
976  *                              out_word                                     *
977  *===========================================================================*/
978 static void out_word(port_t port, u16_t value)
979 {
980 	int r;
981 
982 	r= sys_outw(port, value);
983 	if (r != OK)
984 		panic("sys_outw failed: %d", r);
985 }
986 
987 /*===========================================================================*
988  *                              read_csr                                     *
989  *===========================================================================*/
990 static u16_t read_csr(port_t ioaddr, u16_t csrno)
991 {
992    out_word(ioaddr+LANCE_ADDR, csrno);
993    return in_word(ioaddr+LANCE_DATA);
994 }
995 
996 /*===========================================================================*
997  *                              write_csr                                    *
998  *===========================================================================*/
999 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value)
1000 {
1001    out_word(ioaddr+LANCE_ADDR, csrno);
1002    out_word(ioaddr+LANCE_DATA, value);
1003 }
1004