xref: /minix/minix/drivers/net/lance/lance.c (revision 83133719)
1 /*
2  * lance.c
3  *
4  * This file contains a ethernet device driver for AMD LANCE based ethernet
5  * cards.
6  *
7  * The valid messages and their parameters are:
8  *
9  *   m_type        DL_COUNT   DL_MODE   DL_GRANT
10  * |--------------+----------+---------+---------|
11  * | DL_WRITEV_S  | count    |         | grant   |
12  * |--------------|----------|---------|---------|
13  * | DL_READV_S   | count    |         | grant   |
14  * |--------------|----------|---------|---------|
15  * | DL_CONF      |          | mode    |         |
16  * |--------------|----------|---------|---------|
17  * | DL_GETSTAT_S |          |         | grant   |
18  * |--------------|----------|---------|---------|
19  * | hardware int |          |         |         |
20  * |--------------|----------|---------|---------|
21  *
22  * The messages sent are:
23  *
24  *   m_type         DL_COUNT   DL_FLAGS
25  * |---------------+----------+---------|
26  * | DL_TASK_REPLY | rd-count | flags   |
27  * |---------------|----------|---------|
28  *
29  *   m_type
30  * |---------------|
31  * | DL_STAT_REPLY |
32  * |---------------|
33  *
34  *   m_type         DL_STAT   DL_ADDR
35  * |---------------+---------+---------------|
36  * | DL_CONF_REPLY | code    | ethernet addr |
37  * |---------------|---------|---------------|
38  *
39  * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
40  * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
41  */
42 
43 #define VERBOSE 0 /* Verbose debugging output */
44 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */
45 
46 #include <minix/drivers.h>
47 #include <minix/netdriver.h>
48 
49 #include <net/hton.h>
50 #include <net/gen/ether.h>
51 #include <net/gen/eth_io.h>
52 #include <assert.h>
53 
54 #include <minix/syslib.h>
55 #include <minix/endpoint.h>
56 #include <machine/pci.h>
57 #include <minix/ds.h>
58 
59 #include "lance.h"
60 
61 static ether_card_t ec_state;
62 static int ec_instance;
63 
64 /* Configuration */
65 typedef struct ec_conf
66 {
67    port_t ec_port;
68    int ec_irq;
69    phys_bytes ec_mem;
70 } ec_conf_t;
71 
72 /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */
73 #define EC_CONF_NR 3
74 ec_conf_t ec_conf[EC_CONF_NR]=    /* Card addresses */
75 {
76    /* I/O port, IRQ,  Buffer address. */
77    {  0x1000,     9,    0x00000,     },
78    {  0xD000,    15,    0x00000,     },
79    {  0x0000,     0,    0x00000,     },
80 };
81 
82 /* General */
83 static void do_init(message *mp);
84 static void ec_init(ether_card_t *ec);
85 static void ec_confaddr(ether_card_t *ec);
86 static void ec_reinit(ether_card_t *ec);
87 static void ec_check_ints(ether_card_t *ec);
88 static void conf_hw(ether_card_t *ec);
89 static void update_conf(ether_card_t *ec, ec_conf_t *ecp);
90 static void mess_reply(message *req, message *reply);
91 static void do_int(ether_card_t *ec);
92 static void reply(ether_card_t *ec);
93 static void ec_reset(ether_card_t *ec);
94 static void ec_send(ether_card_t *ec);
95 static void ec_recv(ether_card_t *ec);
96 static void do_vwrite_s(message *mp, int from_int);
97 static void do_vread_s(const message *mp);
98 static void ec_user2nic(ether_card_t *dep, iovec_dat_t *iovp, vir_bytes
99 	offset, int nic_addr, vir_bytes count);
100 static void ec_nic2user(ether_card_t *ec, int nic_addr, iovec_dat_t
101 	*iovp, vir_bytes offset, vir_bytes count);
102 static int calc_iovec_size(iovec_dat_t *iovp);
103 static void ec_next_iovec(iovec_dat_t *iovp);
104 static void do_getstat_s(message *mp);
105 static void lance_stop(ether_card_t *ec);
106 
107 static void lance_dump(void);
108 static void getAddressing(int devind, ether_card_t *ec);
109 
110 /* probe+init LANCE cards */
111 static int lance_probe(ether_card_t *ec, int skip);
112 static void lance_init_card(ether_card_t *ec);
113 
114 /* Accesses Lance Control and Status Registers */
115 static u8_t in_byte(port_t port);
116 static u16_t in_word(port_t port);
117 static void out_word(port_t port, u16_t value);
118 static u16_t read_csr(port_t ioaddr, u16_t csrno);
119 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value);
120 
121 /* --- LANCE --- */
122 /* General */
123 typedef unsigned long Address;
124 
125 #define virt_to_bus(x)          (vir2phys((unsigned long)x))
126 unsigned long vir2phys( unsigned long x )
127 {
128    int r;
129    unsigned long value;
130 
131    if ( (r=sys_umap( SELF, VM_D, x, 4, &value )) != OK ) {
132       printf("lance: umap of 0x%lx failed\n",x );
133       panic("sys_umap failed: %d", r);
134    }
135 
136    return value;
137 }
138 
139 /* DMA limitations */
140 #define DMA_ADDR_MASK  0xFFFFFF  /* mask to verify DMA address is 24-bit */
141 
142 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance_buf + sizeof(struct lance_interface)) & ~DMA_ADDR_MASK) == 0 )
143 
144 #define ETH_FRAME_LEN           1518
145 
146 #define LANCE_MUST_PAD          0x00000001
147 #define LANCE_ENABLE_AUTOSELECT 0x00000002
148 #define LANCE_SELECT_PHONELINE  0x00000004
149 #define LANCE_MUST_UNRESET      0x00000008
150 
151 static const struct lance_chip_type
152 {
153    int        id_number;
154    const char *name;
155    int        flags;
156 } chip_table[] = {
157    {0x0000, "LANCE 7990",           /* Ancient lance chip.  */
158     LANCE_MUST_PAD + LANCE_MUST_UNRESET},
159    {0x0003, "PCnet/ISA 79C960",     /* 79C960 PCnet/ISA.  */
160     LANCE_ENABLE_AUTOSELECT},
161    {0x2260, "PCnet/ISA+ 79C961",    /* 79C961 PCnet/ISA+, Plug-n-Play.  */
162     LANCE_ENABLE_AUTOSELECT},
163    {0x2420, "PCnet/PCI 79C970",     /* 79C970 or 79C974 PCnet-SCSI, PCI. */
164     LANCE_ENABLE_AUTOSELECT},
165    {0x2430, "PCnet32",              /* 79C965 PCnet for VL bus. */
166     LANCE_ENABLE_AUTOSELECT},
167    {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
168     LANCE_ENABLE_AUTOSELECT},
169    {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
170     LANCE_ENABLE_AUTOSELECT},
171    {0x2626, "PCnet/HomePNA 79C978",
172     LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
173    {0x0, "PCnet (unknown)",
174     LANCE_ENABLE_AUTOSELECT},
175 };
176 
177 /* ############## for LANCE device ############## */
178 #define LANCE_ETH_ADDR          0x0
179 #define LANCE_DATA              0x10
180 #define LANCE_ADDR              0x12
181 #define LANCE_RESET             0x14
182 #define LANCE_BUS_IF            0x16
183 #define LANCE_TOTAL_SIZE        0x18
184 
185 /* Use 2^4=16 {Rx,Tx} buffers */
186 #define LANCE_LOG_RX_BUFFERS    4
187 #define RX_RING_SIZE            (1 << (LANCE_LOG_RX_BUFFERS))
188 #define RX_RING_MOD_MASK        (RX_RING_SIZE - 1)
189 #define RX_RING_LEN_BITS        ((LANCE_LOG_RX_BUFFERS) << 29)
190 
191 #define LANCE_LOG_TX_BUFFERS    4
192 #define TX_RING_SIZE            (1 << (LANCE_LOG_TX_BUFFERS))
193 #define TX_RING_MOD_MASK        (TX_RING_SIZE - 1)
194 #define TX_RING_LEN_BITS        ((LANCE_LOG_TX_BUFFERS) << 29)
195 
196 /* for lance_interface */
197 struct lance_init_block
198 {
199    unsigned short  mode;
200    unsigned char   phys_addr[6];
201    unsigned long   filter[2];
202    Address         rx_ring;
203    Address         tx_ring;
204 };
205 
206 struct lance_rx_head
207 {
208    union {
209       Address         base;
210       unsigned char   addr[4];
211    } u;
212    short           buf_length;     /* 2s complement */
213    short           msg_length;
214 };
215 
216 struct lance_tx_head
217 {
218    union {
219       Address         base;
220       unsigned char   addr[4];
221    } u;
222    short           buf_length;     /* 2s complement */
223    short           misc;
224 };
225 
226 struct lance_interface
227 {
228    struct lance_init_block init_block;
229    struct lance_rx_head    rx_ring[RX_RING_SIZE];
230    struct lance_tx_head    tx_ring[TX_RING_SIZE];
231    unsigned char           rbuf[RX_RING_SIZE][ETH_FRAME_LEN];
232    unsigned char           tbuf[TX_RING_SIZE][ETH_FRAME_LEN];
233 };
234 
235 /* =============== global variables =============== */
236 /* AKA the stuff that really should have been in ether_card_t */
237 static struct lance_interface  *lp;
238 #define LANCE_BUF_SIZE (sizeof(struct lance_interface))
239 static char *lance_buf = NULL;
240 static int rx_slot_nr = 0;          /* Rx-slot number */
241 static int tx_slot_nr = 0;          /* Tx-slot number */
242 static int cur_tx_slot_nr = 0;      /* Tx-slot number */
243 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
244 
245 phys_bytes lance_buf_phys;
246 
247 /* SEF functions and variables. */
248 static void sef_local_startup(void);
249 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
250 static void sef_cb_signal_handler(int signo);
251 
252 /*===========================================================================*
253  *                              main                                         *
254  *===========================================================================*/
255 int main( int argc, char **argv )
256 {
257    message m;
258    int ipc_status;
259    int r;
260    ether_card_t *ec;
261 
262    /* SEF local startup. */
263    env_setargs(argc, argv);
264    sef_local_startup();
265 
266    ec= &ec_state;
267 
268    while (TRUE)
269    {
270       if (ec->ec_irq != 0)
271          sys_irqenable(&ec->ec_hook);
272 
273       if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
274         panic("netdriver_receive failed: %d", r);
275 
276       if (ec->ec_irq != 0)
277          sys_irqdisable(&ec->ec_hook);
278 
279       if (is_ipc_notify(ipc_status)) {
280 	      switch(_ENDPOINT_P(m.m_source)) {
281 		      case TTY_PROC_NR:
282 			      lance_dump();
283 			      break;
284 		      case HARDWARE:
285 			      if (ec->mode == EC_ENABLED)
286 			      {
287 				 ec->ec_int_pending = 0;
288 				 ec_check_ints(ec);
289 				 do_int(ec);
290 			      }
291 			      break;
292 		      default:
293 			      panic("illegal notify source: %d", m.m_source);
294 	      }
295 
296 	      /* get next message */
297 	      continue;
298       }
299 
300       switch (m.m_type)
301       {
302       case DL_WRITEV_S:
303          do_vwrite_s(&m, FALSE);
304          break;
305       case DL_READV_S:
306          do_vread_s(&m);
307          break;
308       case DL_CONF:
309          do_init(&m);
310          break;
311       case DL_GETSTAT_S:
312          do_getstat_s(&m);
313          break;
314       default:
315          panic("illegal message: %d", m.m_type);
316       }
317    }
318 
319    return 0;
320 }
321 
322 /*===========================================================================*
323  *			       sef_local_startup			     *
324  *===========================================================================*/
325 static void sef_local_startup()
326 {
327   /* Register init callbacks. */
328   sef_setcb_init_fresh(sef_cb_init_fresh);
329   sef_setcb_init_lu(sef_cb_init_fresh);
330   sef_setcb_init_restart(sef_cb_init_fresh);
331 
332   /* Register live update callbacks. */
333   sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
334   sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
335 
336   /* Register signal callbacks. */
337   sef_setcb_signal_handler(sef_cb_signal_handler);
338 
339   /* Let SEF perform startup. */
340   sef_startup();
341 }
342 
343 /*===========================================================================*
344  *		            sef_cb_init_fresh                                *
345  *===========================================================================*/
346 static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
347 {
348 /* Initialize the lance driver. */
349    long v;
350 #if LANCE_FKEY
351    int r, fkeys, sfkeys;
352 #endif
353 
354 #if LANCE_FKEY
355    fkeys = sfkeys = 0;
356    bit_set( sfkeys, 7 );
357    if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
358       printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
359 #endif
360 
361    v = 0;
362    (void) env_parse("instance", "d", 0, &v, 0, 255);
363    ec_instance = (int) v;
364 
365    /* Announce we are up! */
366    netdriver_announce();
367 
368    return OK;
369 }
370 
371 /*===========================================================================*
372  *		           sef_cb_signal_handler                             *
373  *===========================================================================*/
374 static void sef_cb_signal_handler(int signo)
375 {
376 
377    /* Only check for termination signal, ignore anything else. */
378    if (signo != SIGTERM) return;
379 
380    if (ec_state.mode == EC_ENABLED)
381       lance_stop(&ec_state);
382 
383 #if VERBOSE
384    printf("LANCE driver stopped.\n");
385 #endif
386 
387    exit(0);
388 }
389 
390 /*===========================================================================*
391  *                              lance_dump                                   *
392  *===========================================================================*/
393 static void lance_dump()
394 {
395    ether_card_t *ec;
396    int isr, csr;
397    unsigned short ioaddr;
398 
399    printf("\n");
400    ec = &ec_state;
401    if (ec->mode == EC_DISABLED)
402       printf("lance instance %d is disabled\n", ec_instance);
403    else if (ec->mode == EC_SINK)
404       printf("lance instance %d is in sink mode\n", ec_instance);
405 
406    if (ec->mode != EC_ENABLED)
407       return;
408 
409    printf("lance statistics of instance %d:\n", ec_instance);
410 
411    printf("recvErr    :%8ld\t", ec->eth_stat.ets_recvErr);
412    printf("sendErr    :%8ld\t", ec->eth_stat.ets_sendErr);
413    printf("OVW        :%8ld\n", ec->eth_stat.ets_OVW);
414 
415    printf("CRCerr     :%8ld\t", ec->eth_stat.ets_CRCerr);
416    printf("frameAll   :%8ld\t", ec->eth_stat.ets_frameAll);
417    printf("missedP    :%8ld\n", ec->eth_stat.ets_missedP);
418 
419    printf("packetR    :%8ld\t", ec->eth_stat.ets_packetR);
420    printf("packetT    :%8ld\t", ec->eth_stat.ets_packetT);
421    printf("transDef   :%8ld\n", ec->eth_stat.ets_transDef);
422 
423    printf("collision  :%8ld\t", ec->eth_stat.ets_collision);
424    printf("transAb    :%8ld\t", ec->eth_stat.ets_transAb);
425    printf("carrSense  :%8ld\n", ec->eth_stat.ets_carrSense);
426 
427    printf("fifoUnder  :%8ld\t", ec->eth_stat.ets_fifoUnder);
428    printf("fifoOver   :%8ld\t", ec->eth_stat.ets_fifoOver);
429    printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
430 
431    printf("OWC        :%8ld\t", ec->eth_stat.ets_OWC);
432 
433    ioaddr = ec->ec_port;
434    isr = read_csr(ioaddr, LANCE_CSR0);
435    printf("isr = 0x%x, flags = 0x%x\n", isr,
436              ec->flags);
437 
438    printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
439 
440    csr = read_csr(ioaddr, LANCE_CSR0);
441    printf("CSR0: 0x%x\n", csr);
442    csr = read_csr(ioaddr, LANCE_CSR3);
443    printf("CSR3: 0x%x\n", csr);
444    csr = read_csr(ioaddr, LANCE_CSR4);
445    printf("CSR4: 0x%x\n", csr);
446    csr = read_csr(ioaddr, LANCE_CSR5);
447    printf("CSR5: 0x%x\n", csr);
448    csr = read_csr(ioaddr, LANCE_CSR15);
449    printf("CSR15: 0x%x\n", csr);
450 }
451 
452 /*===========================================================================*
453  *                              do_init                                      *
454  *===========================================================================*/
455 static void do_init(mp)
456 message *mp;
457 {
458    ether_card_t *ec;
459    message reply_mess;
460 
461    pci_init();
462 
463    if(!lance_buf && !(lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M, &lance_buf_phys))) {
464       panic("alloc_contig failed: %d", LANCE_BUF_SIZE);
465    }
466 
467    ec= &ec_state;
468    strlcpy(ec->port_name, "lance#0", sizeof(ec->port_name));
469    ec->port_name[6] += ec_instance;
470 
471    if (ec->mode == EC_DISABLED)
472    {
473       /* This is the default, try to (re)locate the device. */
474       /* only try to enable if memory is correct for DMA */
475       if ( CORRECT_DMA_MEM() )
476       {
477          conf_hw(ec);
478       }
479       else
480       {
481          printf("LANCE: DMA denied because address out of range\n" );
482       }
483 
484       if (ec->mode == EC_DISABLED)
485       {
486          /* Probe failed, or the device is configured off. */
487          reply_mess.m_type= DL_CONF_REPLY;
488          reply_mess.m_netdrv_net_dl_conf.stat = ENXIO;
489          mess_reply(mp, &reply_mess);
490          return;
491       }
492       if (ec->mode == EC_ENABLED)
493          ec_init(ec);
494    }
495 
496    if (ec->mode == EC_SINK)
497    {
498       ec->mac_address.ea_addr[0] =
499          ec->mac_address.ea_addr[1] =
500          ec->mac_address.ea_addr[2] =
501          ec->mac_address.ea_addr[3] =
502          ec->mac_address.ea_addr[4] =
503          ec->mac_address.ea_addr[5] = 0;
504       ec_confaddr(ec);
505       reply_mess.m_type = DL_CONF_REPLY;
506       reply_mess.m_netdrv_net_dl_conf.stat = OK;
507       memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, ec->mac_address.ea_addr,
508 	      sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr));
509       mess_reply(mp, &reply_mess);
510       return;
511    }
512    assert(ec->mode == EC_ENABLED);
513    assert(ec->flags & ECF_ENABLED);
514 
515    ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD);
516 
517    if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ)
518       ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD;
519    if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ)
520       ec->flags |= ECF_MULTI;
521    if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ)
522       ec->flags |= ECF_BROAD;
523 
524    ec_reinit(ec);
525 
526    reply_mess.m_type = DL_CONF_REPLY;
527    reply_mess.m_netdrv_net_dl_conf.stat = OK;
528    memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, ec->mac_address.ea_addr,
529       sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr));
530 
531    mess_reply(mp, &reply_mess);
532 }
533 
534 
535 /*===========================================================================*
536  *                              do_int                                       *
537  *===========================================================================*/
538 static void do_int(ec)
539 ether_card_t *ec;
540 {
541    if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV))
542       reply(ec);
543 }
544 
545 
546 /*===========================================================================*
547  *                              conf_hw                                      *
548  *===========================================================================*/
549 static void conf_hw(ec)
550 ether_card_t *ec;
551 {
552    static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */ };
553 
554    int confnr;
555    ec_conf_t *ecp;
556 
557    ec->mode= EC_DISABLED;     /* Superfluous */
558 
559    /* Pick a default configuration. This hardly matters anymore. */
560    confnr= MIN(ec_instance, EC_CONF_NR-1);
561 
562    ecp= &ec_conf[confnr];
563    update_conf(ec, ecp);
564    if (ec->mode != EC_ENABLED)
565       return;
566 
567    if (!lance_probe(ec, ec_instance))
568    {
569       printf("%s: No ethernet card found on PCI-BIOS info.\n",
570              ec->port_name);
571       ec->mode= EC_DISABLED;
572       return;
573    }
574 
575    /* XXX */ if (ec->ec_linmem == 0) ec->ec_linmem= 0xFFFF0000;
576 
577    ec->flags = ECF_EMPTY;
578    ec->eth_stat = empty_stat;
579 }
580 
581 
582 /*===========================================================================*
583  *                              update_conf                                  *
584  *===========================================================================*/
585 static void update_conf(ec, ecp)
586 ether_card_t *ec;
587 ec_conf_t *ecp;
588 {
589    long v;
590    char eckey[16];
591    static char ec_fmt[] = "x:d:x:x";
592 
593    /* Get the default settings and modify them from the environment. */
594    strlcpy(eckey, "LANCE0", sizeof(eckey));
595    eckey[5] += ec_instance;
596    ec->mode= EC_SINK;
597    v= ecp->ec_port;
598    switch (env_parse(eckey, ec_fmt, 0, &v, 0x0000L, 0xFFFFL))
599    {
600    case EP_OFF:
601       ec->mode= EC_DISABLED;
602       break;
603    case EP_ON:
604    case EP_SET:
605    default:
606       ec->mode= EC_ENABLED;      /* Might become disabled if
607                                   * all probes fail */
608       break;
609    }
610 
611    ec->ec_port= v;
612 
613    v= ecp->ec_irq | DEI_DEFAULT;
614    (void) env_parse(eckey, ec_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
615    ec->ec_irq= v;
616 
617    v= ecp->ec_mem;
618    (void) env_parse(eckey, ec_fmt, 2, &v, 0L, 0xFFFFFL);
619    ec->ec_linmem= v;
620 
621    v= 0;
622    (void) env_parse(eckey, ec_fmt, 3, &v, 0x2000L, 0x8000L);
623    ec->ec_ramsize= v;
624 }
625 
626 
627 /*===========================================================================*
628  *                              ec_init                                      *
629  *===========================================================================*/
630 static void ec_init(ec)
631 ether_card_t *ec;
632 {
633    int r;
634 #if VERBOSE
635    int i;
636 #endif
637 
638    /* General initialization */
639    ec->flags = ECF_EMPTY;
640    lance_init_card(ec); /* Get mac_address, etc ...*/
641 
642    ec_confaddr(ec);
643 
644 #if VERBOSE
645    printf("%s: Ethernet address ", ec->port_name);
646    for (i= 0; i < 6; i++)
647       printf("%x%c", ec->mac_address.ea_addr[i],
648              i < 5 ? ':' : '\n');
649 #endif
650 
651    /* Finish the initialization */
652    ec->flags |= ECF_ENABLED;
653 
654    /* Set the interrupt handler */
655    ec->ec_hook = ec->ec_irq;
656    if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK)
657       printf("lance: error, couldn't set IRQ policy: %d\n", r);
658 
659    return;
660 }
661 
662 
663 /*===========================================================================*
664  *                              reply                                        *
665  *===========================================================================*/
666 static void reply(ec)
667 ether_card_t *ec;
668 {
669    message reply;
670    int flags,r;
671 
672    flags = DL_NOFLAGS;
673    if (ec->flags & ECF_PACK_SEND)
674       flags |= DL_PACK_SEND;
675    if (ec->flags & ECF_PACK_RECV)
676       flags |= DL_PACK_RECV;
677 
678    reply.m_type   = DL_TASK_REPLY;
679    reply.m_netdrv_net_dl_task.flags = flags;
680    reply.m_netdrv_net_dl_task.count = ec->read_s;
681 
682    r = ipc_send(ec->client, &reply);
683    if (r < 0)
684       panic("ipc_send failed: %d", r);
685 
686    ec->read_s = 0;
687    ec->flags &= ~(ECF_PACK_SEND | ECF_PACK_RECV);
688 }
689 
690 
691 /*===========================================================================*
692  *                              mess_reply                                   *
693  *===========================================================================*/
694 static void mess_reply(req, reply_mess)
695 message *req;
696 message *reply_mess;
697 {
698    if (ipc_send(req->m_source, reply_mess) != OK)
699       panic("unable to mess_reply");
700 }
701 
702 
703 /*===========================================================================*
704  *                              ec_confaddr                                  *
705  *===========================================================================*/
706 static void ec_confaddr(ec)
707 ether_card_t *ec;
708 {
709    int i;
710    char eakey[16];
711    static char eafmt[]= "x:x:x:x:x:x";
712    long v;
713 
714    /* User defined ethernet address? */
715    strlcpy(eakey, "LANCE0_EA", sizeof(eakey));
716    eakey[5] += ec_instance;
717 
718    for (i = 0; i < 6; i++)
719    {
720       v= ec->mac_address.ea_addr[i];
721       if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
722          break;
723       ec->mac_address.ea_addr[i]= v;
724    }
725 
726    if (i != 0 && i != 6)
727    {
728       /* It's all or nothing; force a panic. */
729       (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
730    }
731 }
732 
733 
734 /*===========================================================================*
735  *                              ec_reinit                                    *
736  *===========================================================================*/
737 static void ec_reinit(ec)
738 ether_card_t *ec;
739 {
740    int i;
741    unsigned short ioaddr = ec->ec_port;
742 
743    /* stop */
744    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
745 
746    /* purge Tx-ring */
747    tx_slot_nr = cur_tx_slot_nr = 0;
748    for (i=0; i<TX_RING_SIZE; i++)
749    {
750       lp->tx_ring[i].u.base = 0;
751       isstored[i]=0;
752    }
753 
754    /* re-init Rx-ring */
755    rx_slot_nr = 0;
756    for (i=0; i<RX_RING_SIZE; i++)
757    {
758       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
759       lp->rx_ring[i].u.addr[3] |= 0x80;
760    }
761 
762    /* Set 'Receive Mode' */
763    if (ec->flags & ECF_PROMISC)
764    {
765       write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
766    }
767    else
768    {
769       if (ec->flags & (ECF_BROAD | ECF_MULTI))
770       {
771          write_csr(ioaddr, LANCE_CSR15, 0x0000);
772       }
773       else
774       {
775          write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
776       }
777    }
778 
779    /* start && enable interrupt */
780    write_csr(ioaddr, LANCE_CSR0,
781              LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
782 
783    return;
784 }
785 
786 /*===========================================================================*
787  *                              ec_check_ints                                *
788  *===========================================================================*/
789 static void ec_check_ints(ec)
790 ether_card_t *ec;
791 {
792    int must_restart = 0;
793    int check,status;
794    int isr = 0x0000;
795    unsigned short ioaddr = ec->ec_port;
796 
797    if (!(ec->flags & ECF_ENABLED))
798       panic("got premature interrupt");
799 
800    for (;;)
801    {
802 #if VERBOSE
803       printf("ETH: Reading ISR...");
804 #endif
805       isr = read_csr(ioaddr, LANCE_CSR0);
806       if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) {
807          write_csr(ioaddr, LANCE_CSR0,
808                    isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP
809                            |LANCE_CSR0_STRT|LANCE_CSR0_INIT) );
810       }
811       write_csr(ioaddr, LANCE_CSR0,
812                 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR
813                 |LANCE_CSR0_IDON|LANCE_CSR0_IENA);
814 
815 #define ISR_RST  0x0000
816 
817       if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS
818                   |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000)
819       {
820 #if VERBOSE
821          printf("OK\n");
822 #endif
823          break;
824       }
825 
826       if (isr & LANCE_CSR0_MISS)
827       {
828 #if VERBOSE
829          printf("RX Missed Frame\n");
830 #endif
831          ec->eth_stat.ets_recvErr++;
832       }
833       if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT))
834       {
835          if (isr & LANCE_CSR0_BABL)
836          {
837 #if VERBOSE
838             printf("TX Timeout\n");
839 #endif
840             ec->eth_stat.ets_sendErr++;
841          }
842          if (isr & LANCE_CSR0_TINT)
843          {
844 #if VERBOSE
845             printf("TX INT\n");
846 #endif
847             /* status check: restart if needed. */
848             status = lp->tx_ring[cur_tx_slot_nr].u.base;
849 
850             /* ??? */
851             if (status & 0x40000000)
852             {
853                status = lp->tx_ring[cur_tx_slot_nr].misc;
854                ec->eth_stat.ets_sendErr++;
855                if (status & 0x0400)
856                   ec->eth_stat.ets_transAb++;
857                if (status & 0x0800)
858                   ec->eth_stat.ets_carrSense++;
859                if (status & 0x1000)
860                   ec->eth_stat.ets_OWC++;
861                if (status & 0x4000)
862                {
863                   ec->eth_stat.ets_fifoUnder++;
864                   must_restart=1;
865                }
866             }
867             else
868             {
869                if (status & 0x18000000)
870                   ec->eth_stat.ets_collision++;
871                ec->eth_stat.ets_packetT++;
872             }
873          }
874          /* transmit a packet on the next slot if it exists. */
875          check = 0;
876          if (isstored[cur_tx_slot_nr]==1)
877          {
878             /* free the tx-slot just transmitted */
879             isstored[cur_tx_slot_nr]=0;
880             cur_tx_slot_nr = (cur_tx_slot_nr + 1) & TX_RING_MOD_MASK;
881 
882             /* next tx-slot is ready? */
883             if (isstored[cur_tx_slot_nr]==1)
884                check=1;
885             else
886                check=0;
887          }
888          else
889          {
890             panic("got premature TX INT..");
891          }
892          if (check==1)
893          {
894             lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
895             write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
896          }
897          /* we set a buffered message in the slot if it exists. */
898          /* and transmit it, if needed. */
899          if (ec->flags & ECF_SEND_AVAIL)
900             ec_send(ec);
901       }
902       if (isr & LANCE_CSR0_RINT)
903       {
904 #if VERBOSE
905          printf("RX INT\n");
906 #endif
907          ec_recv(ec);
908       }
909 
910       if (isr & ISR_RST)
911       {
912          ec->flags = ECF_STOPPED;
913 #if VERBOSE
914          printf("ISR_RST\n");
915 #endif
916          break;
917       }
918 
919       /* ??? cf. lance driver on linux */
920       if (must_restart == 1)
921       {
922 #if VERBOSE
923          printf("ETH: restarting...\n");
924 #endif
925          /* stop */
926          write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
927          /* start */
928          write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
929       }
930    }
931 
932    if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
933    {
934 #if VERBOSE
935       printf("ETH: resetting...\n");
936 #endif
937       ec_reset(ec);
938    }
939 }
940 
941 /*===========================================================================*
942  *                              ec_reset                                     *
943  *===========================================================================*/
944 static void ec_reset(ec)
945 ether_card_t *ec;
946 {
947    /* Stop/start the chip, and clear all RX,TX-slots */
948    unsigned short ioaddr = ec->ec_port;
949    int i;
950 
951    /* stop */
952    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
953    /* start */
954    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
955 
956    /* purge Tx-ring */
957    tx_slot_nr = cur_tx_slot_nr = 0;
958    for (i=0; i<TX_RING_SIZE; i++)
959    {
960       lp->tx_ring[i].u.base = 0;
961       isstored[i]=0;
962    }
963 
964    /* re-init Rx-ring */
965    rx_slot_nr = 0;
966    for (i=0; i<RX_RING_SIZE; i++)
967    {
968       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
969       lp->rx_ring[i].u.addr[3] |= 0x80;
970    }
971 
972    /* store a buffered message on the slot if exists */
973    ec_send(ec);
974    ec->flags &= ~ECF_STOPPED;
975 }
976 
977 /*===========================================================================*
978  *                              ec_send                                      *
979  *===========================================================================*/
980 static void ec_send(ec)
981 ether_card_t *ec;
982 {
983    /* from ec_check_ints() or ec_reset(). */
984    /* this function proccesses the buffered message. (slot/transmit) */
985    if (!(ec->flags & ECF_SEND_AVAIL))
986       return;
987 
988    ec->flags &= ~ECF_SEND_AVAIL;
989    switch(ec->sendmsg.m_type)
990    {
991    case DL_WRITEV_S: do_vwrite_s(&ec->sendmsg, TRUE);        break;
992    default:
993       panic("wrong type: %d", ec->sendmsg.m_type);
994       break;
995    }
996 }
997 
998 /*===========================================================================*
999  *                              do_vread_s                                   *
1000  *===========================================================================*/
1001 static void do_vread_s(const message *mp)
1002 {
1003    int count, r;
1004    ether_card_t *ec;
1005 
1006    ec= &ec_state;
1007 
1008    ec->client= mp->m_source;
1009    count = mp->m_net_netdrv_dl_readv_s.count;
1010 
1011    r = sys_safecopyfrom(mp->m_source, mp->m_net_netdrv_dl_readv_s.grant, 0,
1012                         (vir_bytes)ec->read_iovec.iod_iovec,
1013                         (count > IOVEC_NR ? IOVEC_NR : count) *
1014                         sizeof(iovec_s_t));
1015    if (r != OK)
1016 	panic("do_vread_s: sys_safecopyfrom failed: %d", r);
1017    ec->read_iovec.iod_iovec_s    = count;
1018    ec->read_iovec.iod_proc_nr    = mp->m_source;
1019    ec->read_iovec.iod_grant = mp->m_net_netdrv_dl_readv_s.grant;
1020    ec->read_iovec.iod_iovec_offset = 0;
1021 
1022    ec->tmp_iovec = ec->read_iovec;
1023 
1024    ec->flags |= ECF_READING;
1025 
1026    ec_recv(ec);
1027 
1028    if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
1029       ec_reset(ec);
1030    reply(ec);
1031 }
1032 
1033 /*===========================================================================*
1034  *                              ec_recv                                      *
1035  *===========================================================================*/
1036 static void ec_recv(ec)
1037 ether_card_t *ec;
1038 {
1039    vir_bytes length;
1040    int packet_processed;
1041    int status;
1042    unsigned short ioaddr = ec->ec_port;
1043 
1044    if ((ec->flags & ECF_READING)==0)
1045       return;
1046    if (!(ec->flags & ECF_ENABLED))
1047       return;
1048 
1049    /* we check all the received slots until find a properly received packet */
1050    packet_processed = FALSE;
1051    while (!packet_processed)
1052    {
1053       status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1054       if ( (status & 0x80) == 0x00 )
1055       {
1056          status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1057 
1058          /* ??? */
1059          if (status != 0x03)
1060          {
1061             if (status & 0x01)
1062                ec->eth_stat.ets_recvErr++;
1063             if (status & 0x04)
1064                ec->eth_stat.ets_fifoOver++;
1065             if (status & 0x08)
1066                ec->eth_stat.ets_CRCerr++;
1067             if (status & 0x10)
1068                ec->eth_stat.ets_OVW++;
1069             if (status & 0x20)
1070                ec->eth_stat.ets_frameAll++;
1071             length = 0;
1072          }
1073          else
1074          {
1075             ec->eth_stat.ets_packetR++;
1076             length = lp->rx_ring[rx_slot_nr].msg_length;
1077          }
1078          if (length > 0)
1079          {
1080             ec_nic2user(ec, (int)(lp->rbuf[rx_slot_nr]),
1081                         &ec->read_iovec, 0, length);
1082 
1083             ec->read_s = length;
1084             ec->flags |= ECF_PACK_RECV;
1085             ec->flags &= ~ECF_READING;
1086             packet_processed = TRUE;
1087          }
1088          /* set up this slot again, and we move to the next slot */
1089          lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN;
1090          lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80;
1091 
1092          write_csr(ioaddr, LANCE_CSR0,
1093                    LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS
1094                    |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA);
1095 
1096          rx_slot_nr = (rx_slot_nr + 1) & RX_RING_MOD_MASK;
1097       }
1098       else
1099          break;
1100    }
1101 }
1102 
1103 /*===========================================================================*
1104  *                              do_vwrite_s                                  *
1105  *===========================================================================*/
1106 static void do_vwrite_s(mp, from_int)
1107 message *mp;
1108 int from_int;
1109 {
1110    int count, check, r;
1111    ether_card_t *ec;
1112    unsigned short ioaddr;
1113 
1114    ec = &ec_state;
1115 
1116    ec->client= mp->m_source;
1117    count = mp->m_net_netdrv_dl_writev_s.count;
1118 
1119    if (isstored[tx_slot_nr]==1)
1120    {
1121       /* all slots are used, so this message is buffered */
1122       ec->sendmsg= *mp;
1123       ec->flags |= ECF_SEND_AVAIL;
1124       reply(ec);
1125       return;
1126    }
1127 
1128    /* convert the message to write_iovec */
1129    r = sys_safecopyfrom(mp->m_source, mp->m_net_netdrv_dl_writev_s.grant, 0,
1130                         (vir_bytes)ec->write_iovec.iod_iovec,
1131                         (count > IOVEC_NR ? IOVEC_NR : count) *
1132                         sizeof(iovec_s_t));
1133    if (r != OK)
1134 	panic("do_vwrite_s: sys_safecopyfrom failed: %d", r);
1135    ec->write_iovec.iod_iovec_s    = count;
1136    ec->write_iovec.iod_proc_nr    = mp->m_source;
1137    ec->write_iovec.iod_grant      = mp->m_net_netdrv_dl_writev_s.grant;
1138    ec->write_iovec.iod_iovec_offset = 0;
1139 
1140    ec->tmp_iovec = ec->write_iovec;
1141    ec->write_s = calc_iovec_size(&ec->tmp_iovec);
1142 
1143    /* copy write_iovec to the slot on DMA address */
1144    ec_user2nic(ec, &ec->write_iovec, 0,
1145                (int)(lp->tbuf[tx_slot_nr]), ec->write_s);
1146    /* set-up for transmitting, and transmit it if needed. */
1147    lp->tx_ring[tx_slot_nr].buf_length = -ec->write_s;
1148    lp->tx_ring[tx_slot_nr].misc = 0x0;
1149    lp->tx_ring[tx_slot_nr].u.base
1150       = virt_to_bus(lp->tbuf[tx_slot_nr]) & 0xffffff;
1151    isstored[tx_slot_nr]=1;
1152    if (cur_tx_slot_nr == tx_slot_nr)
1153       check=1;
1154    else
1155       check=0;
1156    tx_slot_nr = (tx_slot_nr + 1) & TX_RING_MOD_MASK;
1157 
1158    if (check == 1)
1159    {
1160       ioaddr = ec->ec_port;
1161       lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
1162       write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
1163    }
1164 
1165    ec->flags |= ECF_PACK_SEND;
1166 
1167    /* reply by calling do_int() if this function is called from interrupt. */
1168    if (from_int)
1169       return;
1170    reply(ec);
1171 }
1172 
1173 
1174 /*===========================================================================*
1175  *                              ec_user2nic                                  *
1176  *===========================================================================*/
1177 static void ec_user2nic(ec, iovp, offset, nic_addr, count)
1178 ether_card_t *ec;
1179 iovec_dat_t *iovp;
1180 vir_bytes offset;
1181 int nic_addr;
1182 vir_bytes count;
1183 {
1184    int bytes, i, r;
1185 
1186    i= 0;
1187    while (count > 0)
1188    {
1189       if (i >= IOVEC_NR)
1190       {
1191          ec_next_iovec(iovp);
1192          i= 0;
1193          continue;
1194       }
1195       if (offset >= iovp->iod_iovec[i].iov_size)
1196       {
1197          offset -= iovp->iod_iovec[i].iov_size;
1198          i++;
1199          continue;
1200       }
1201       bytes = iovp->iod_iovec[i].iov_size - offset;
1202       if (bytes > count)
1203          bytes = count;
1204 
1205       if ( (r=sys_safecopyfrom(iovp->iod_proc_nr,
1206                                iovp->iod_iovec[i].iov_grant, offset,
1207                                nic_addr, bytes )) != OK )
1208          panic("ec_user2nic: sys_safecopyfrom failed: %d", r);
1209 
1210       count -= bytes;
1211       nic_addr += bytes;
1212       offset += bytes;
1213    }
1214 }
1215 
1216 /*===========================================================================*
1217  *                              ec_nic2user                                  *
1218  *===========================================================================*/
1219 static void ec_nic2user(ec, nic_addr, iovp, offset, count)
1220 ether_card_t *ec;
1221 int nic_addr;
1222 iovec_dat_t *iovp;
1223 vir_bytes offset;
1224 vir_bytes count;
1225 {
1226    int bytes, i, r;
1227 
1228    i= 0;
1229    while (count > 0)
1230    {
1231       if (i >= IOVEC_NR)
1232       {
1233          ec_next_iovec(iovp);
1234          i= 0;
1235          continue;
1236       }
1237       if (offset >= iovp->iod_iovec[i].iov_size)
1238       {
1239          offset -= iovp->iod_iovec[i].iov_size;
1240          i++;
1241          continue;
1242       }
1243       bytes = iovp->iod_iovec[i].iov_size - offset;
1244       if (bytes > count)
1245          bytes = count;
1246       if ( (r=sys_safecopyto( iovp->iod_proc_nr, iovp->iod_iovec[i].iov_grant,
1247                               offset, nic_addr, bytes )) != OK )
1248          panic("ec_nic2user: sys_safecopyto failed: %d", r);
1249 
1250       count -= bytes;
1251       nic_addr += bytes;
1252       offset += bytes;
1253    }
1254 }
1255 
1256 
1257 /*===========================================================================*
1258  *                              calc_iovec_size                              *
1259  *===========================================================================*/
1260 static int calc_iovec_size(iovec_dat_t *iovp)
1261 {
1262    int size,i;
1263 
1264    size = i = 0;
1265 
1266    while (i < iovp->iod_iovec_s)
1267    {
1268       if (i >= IOVEC_NR)
1269       {
1270          ec_next_iovec(iovp);
1271          i= 0;
1272          continue;
1273       }
1274       size += iovp->iod_iovec[i].iov_size;
1275       i++;
1276    }
1277 
1278    return size;
1279 }
1280 
1281 /*===========================================================================*
1282  *                              ec_next_iovec                                *
1283  *===========================================================================*/
1284 static void ec_next_iovec(iovp)
1285 iovec_dat_t *iovp;
1286 {
1287    int r;
1288 
1289    iovp->iod_iovec_s -= IOVEC_NR;
1290    iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_s_t);
1291 
1292    r = sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_grant,
1293                         iovp->iod_iovec_offset,
1294                         (vir_bytes)iovp->iod_iovec,
1295                         (iovp->iod_iovec_s > IOVEC_NR ?
1296                          IOVEC_NR : iovp->iod_iovec_s) *
1297                         sizeof(iovec_s_t));
1298    if (r != OK)
1299 	panic("ec_next_iovec: sys_safecopyfrom failed: %d", r);
1300 }
1301 
1302 
1303 /*===========================================================================*
1304  *                              do_getstat_s                                 *
1305  *===========================================================================*/
1306 static void do_getstat_s(mp)
1307 message *mp;
1308 {
1309    int r;
1310    ether_card_t *ec;
1311 
1312    ec= &ec_state;
1313 
1314    r = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0,
1315                       (vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat));
1316 
1317    if (r != OK)
1318 	panic("do_getstat_s: sys_safecopyto failed: %d", r);
1319 
1320    mp->m_type= DL_STAT_REPLY;
1321    r= ipc_send(mp->m_source, mp);
1322    if (r != OK)
1323       panic("do_getstat_s: send failed: %d", r);
1324 }
1325 
1326 /*===========================================================================*
1327  *                              lance_stop                                   *
1328  *===========================================================================*/
1329 static void lance_stop(ec)
1330 ether_card_t *ec;
1331 {
1332    unsigned short ioaddr;
1333 
1334    if (!(ec->flags & ECF_ENABLED))
1335       return;
1336 
1337    ioaddr = ec->ec_port;
1338 
1339    /* stop */
1340    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1341 
1342    /* Reset */
1343    in_word(ioaddr+LANCE_RESET);
1344 
1345    ec->flags = ECF_EMPTY;
1346 }
1347 
1348 /*===========================================================================*
1349  *                              getAddressing                                *
1350  *===========================================================================*/
1351 static void getAddressing(devind, ec)
1352 int devind;
1353 ether_card_t *ec;
1354 {
1355    unsigned int      membase, ioaddr;
1356    int reg, irq;
1357 
1358    for (reg = PCI_BAR; reg <= PCI_BAR_6; reg += 4)
1359    {
1360       ioaddr = pci_attr_r32(devind, reg);
1361 
1362       if ((ioaddr & PCI_BAR_IO_MASK) == 0 || (ioaddr & PCI_BAR_IO) == 0)
1363          continue;
1364       /* Strip the I/O address out of the returned value */
1365       ioaddr &= PCI_BAR_IO_MASK;
1366       /* Get the memory base address */
1367       membase = pci_attr_r32(devind, PCI_BAR_2);
1368       /* KK: Get the IRQ number */
1369       irq = pci_attr_r8(devind, PCI_IPR);
1370       if (irq)
1371          irq = pci_attr_r8(devind, PCI_ILR);
1372 
1373       ec->ec_linmem = membase;
1374       ec->ec_port = ioaddr;
1375       ec->ec_irq = irq;
1376    }
1377 }
1378 
1379 /*===========================================================================*
1380  *                              lance_probe                                  *
1381  *===========================================================================*/
1382 static int lance_probe(ec, skip)
1383 ether_card_t *ec;
1384 int skip;
1385 {
1386    unsigned short    pci_cmd;
1387    unsigned short    ioaddr;
1388    int               lance_version, chip_version;
1389    int devind, r;
1390    u16_t vid, did;
1391 
1392    r= pci_first_dev(&devind, &vid, &did);
1393    if (r == 0)
1394       return 0;
1395 
1396    while (skip--)
1397    {
1398       r= pci_next_dev(&devind, &vid, &did);
1399       if (!r)
1400          return 0;
1401    }
1402 
1403    pci_reserve(devind);
1404 
1405    getAddressing(devind, ec);
1406 
1407 
1408    /* ===== Bus Master ? ===== */
1409    pci_cmd = pci_attr_r32(devind, PCI_CR);
1410    if (!(pci_cmd & PCI_CR_MAST_EN)) {
1411       pci_cmd |= PCI_CR_MAST_EN;
1412       pci_attr_w32(devind, PCI_CR, pci_cmd);
1413    }
1414 
1415    /* ===== Probe Details ===== */
1416    ioaddr = ec->ec_port;
1417 
1418    /* Reset */
1419    in_word(ioaddr+LANCE_RESET);
1420 
1421    if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP)
1422    {
1423       ec->mode=EC_DISABLED;
1424    }
1425 
1426    /* Probe Chip Version */
1427    out_word(ioaddr+LANCE_ADDR, 88);     /* Get the version of the chip */
1428    if (in_word(ioaddr+LANCE_ADDR) != 88)
1429       lance_version = 0;
1430    else
1431    {
1432       chip_version = read_csr(ioaddr, LANCE_CSR88);
1433       chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16;
1434 
1435       if ((chip_version & 0xfff) != 0x3)
1436       {
1437          ec->mode=EC_DISABLED;
1438       }
1439       chip_version = (chip_version >> 12) & 0xffff;
1440       for (lance_version = 1; chip_table[lance_version].id_number != 0;
1441            ++lance_version)
1442          if (chip_table[lance_version].id_number == chip_version)
1443             break;
1444    }
1445 
1446 #if VERBOSE
1447    printf("%s: %s at %X:%d\n",
1448           ec->port_name, chip_table[lance_version].name,
1449           ec->ec_port, ec->ec_irq);
1450 #endif
1451 
1452    return lance_version;
1453 }
1454 
1455 /*===========================================================================*
1456  *                              lance_init_card                              *
1457  *===========================================================================*/
1458 static void lance_init_card(ec)
1459 ether_card_t *ec;
1460 {
1461    int i;
1462    Address l = (vir_bytes)lance_buf;
1463    unsigned short ioaddr = ec->ec_port;
1464 
1465    /* ============= setup init_block(cf. lance_probe1) ================ */
1466    /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */
1467 
1468    lp = (struct lance_interface *)l;
1469 
1470    /* disable Tx and Rx */
1471    lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX;
1472    lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
1473    /* using multiple Rx/Tx buffer */
1474    lp->init_block.rx_ring
1475       = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
1476    lp->init_block.tx_ring
1477       = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
1478 
1479    l = virt_to_bus(&lp->init_block);
1480    write_csr(ioaddr, LANCE_CSR1, (unsigned short)l);
1481    write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16));
1482    write_csr(ioaddr, LANCE_CSR4,
1483              LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1484              |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1485 
1486    /* ============= Get MAC address (cf. lance_probe1) ================ */
1487    for (i = 0; i < 6; ++i)
1488       ec->mac_address.ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i);
1489 
1490    /* ============ (re)start init_block(cf. lance_reset) =============== */
1491    /* Reset the LANCE */
1492    (void)in_word(ioaddr+LANCE_RESET);
1493 
1494    /* ----- Re-initialize the LANCE ----- */
1495    /* Set station address */
1496    for (i = 0; i < 6; ++i)
1497       lp->init_block.phys_addr[i] = ec->mac_address.ea_addr[i];
1498    /* Preset the receive ring headers */
1499    for (i=0; i<RX_RING_SIZE; i++)
1500    {
1501       lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
1502       /* OWN */
1503       lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
1504       /* we set the top byte as the very last thing */
1505       lp->rx_ring[i].u.addr[3] = 0x80;
1506    }
1507    /* Preset the transmitting ring headers */
1508    for (i=0; i<TX_RING_SIZE; i++)
1509    {
1510       lp->tx_ring[i].u.base = 0;
1511       isstored[i] = 0;
1512    }
1513    /* enable Rx and Tx */
1514    lp->init_block.mode = 0x0;
1515 
1516    l = (Address)virt_to_bus(&lp->init_block);
1517    write_csr(ioaddr, LANCE_CSR1, (short)l);
1518    write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16));
1519    write_csr(ioaddr, LANCE_CSR4,
1520              LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1521              |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1522 
1523    /* ----- start when init done. ----- */
1524    /* stop */
1525    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1526    /* init */
1527    write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT);
1528    /* poll for IDON */
1529    for (i = 10000; i > 0; --i)
1530       if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON)
1531          break;
1532 
1533    /* Set 'Multicast Table' */
1534    for (i=0;i<4;++i)
1535    {
1536       write_csr(ioaddr, LANCE_CSR8 + i, 0xffff);
1537    }
1538 
1539    /* Set 'Receive Mode' */
1540    if (ec->flags & ECF_PROMISC)
1541    {
1542       write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
1543    }
1544    else
1545    {
1546       if (ec->flags & (ECF_BROAD | ECF_MULTI))
1547       {
1548          write_csr(ioaddr, LANCE_CSR15, 0x0000);
1549       }
1550       else
1551       {
1552          write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
1553       }
1554    }
1555 
1556    /* start && enable interrupt */
1557    write_csr(ioaddr, LANCE_CSR0,
1558              LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
1559 
1560    return;
1561 }
1562 
1563 /*===========================================================================*
1564  *                              in_byte                                      *
1565  *===========================================================================*/
1566 static u8_t in_byte(port_t port)
1567 {
1568 	int r;
1569 	u32_t value;
1570 
1571 	r= sys_inb(port, &value);
1572 	if (r != OK)
1573 		panic("sys_inb failed: %d", r);
1574 	return value;
1575 }
1576 
1577 /*===========================================================================*
1578  *                              in_word                                      *
1579  *===========================================================================*/
1580 static u16_t in_word(port_t port)
1581 {
1582 	int r;
1583 	u32_t value;
1584 
1585 	r= sys_inw(port, &value);
1586 	if (r != OK)
1587 		panic("sys_inw failed: %d", r);
1588 	return value;
1589 }
1590 
1591 
1592 /*===========================================================================*
1593  *                              out_word                                     *
1594  *===========================================================================*/
1595 static void out_word(port_t port, u16_t value)
1596 {
1597 	int r;
1598 
1599 	r= sys_outw(port, value);
1600 	if (r != OK)
1601 		panic("sys_outw failed: %d", r);
1602 }
1603 
1604 /*===========================================================================*
1605  *                              read_csr                                     *
1606  *===========================================================================*/
1607 static u16_t read_csr(port_t ioaddr, u16_t csrno)
1608 {
1609    out_word(ioaddr+LANCE_ADDR, csrno);
1610    return in_word(ioaddr+LANCE_DATA);
1611 }
1612 
1613 /*===========================================================================*
1614  *                              write_csr                                    *
1615  *===========================================================================*/
1616 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value)
1617 {
1618    out_word(ioaddr+LANCE_ADDR, csrno);
1619    out_word(ioaddr+LANCE_DATA, value);
1620 }
1621