dec21140A ethernet driver for virtualpc, contributed by nicolas tittley.
[minix.git] / drivers / lance / lance.c
blob4d8b62c98901f0ce91e33ba519dfe6b0a3388dc5
1 /*
2 * lance.c
4 * This file contains a ethernet device driver for AMD LANCE based ethernet
5 * cards.
7 * The valid messages and their parameters are:
9 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
10 * |------------+----------+---------+----------+---------+---------+---------|
11 * | HARDINT | | | | | | |
12 * |------------|----------|---------|----------|---------|---------|---------|
13 * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
14 * |------------|----------|---------|----------|---------|---------|---------|
15 * | DL_READV_S | port nr | proc nr | count | | | grant |
16 * |------------|----------|---------|----------|---------|---------|---------|
17 * | DL_CONF | port nr | proc nr | | mode | address | |
18 * |------------|----------|---------|----------|---------|---------|---------|
19 * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
20 * |------------|----------|---------|----------|---------|---------|---------|
21 * | DL_STOP | port_nr | | | | | |
22 * |------------|----------|---------|----------|---------|---------|---------|
24 * The messages sent are:
26 * m-type DL_POR T DL_PROC DL_COUNT DL_STAT DL_CLCK
27 * |------------|----------|---------|----------|---------|---------|
28 * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
29 * |------------|----------|---------|----------|---------|---------|
31 * m_type m3_i1 m3_i2 m3_ca1
32 * |------------+---------+-----------+---------------|
33 * |DL_CONF_REPL| port nr | last port | ethernet addr |
34 * |------------|---------|-----------|---------------|
36 * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
37 * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
40 #define VERBOSE 0 /* Verbose debugging output */
41 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */
43 #include "../drivers.h"
45 #include <minix/keymap.h>
46 #include <net/hton.h>
47 #include <net/gen/ether.h>
48 #include <net/gen/eth_io.h>
49 #include <assert.h>
51 #include <minix/syslib.h>
52 #include <minix/endpoint.h>
53 #include <ibm/pci.h>
54 #include <minix/ds.h>
56 #include "lance.h"
58 #include <sys/ioc_memory.h>
60 static ether_card_t ec_table[EC_PORT_NR_MAX];
61 static int eth_tasknr= ANY;
62 static u16_t eth_ign_proto;
64 /* Configuration */
65 typedef struct ec_conf
67 port_t ec_port;
68 int ec_irq;
69 phys_bytes ec_mem;
70 char *ec_envvar;
71 } ec_conf_t;
73 /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */
74 ec_conf_t ec_conf[]= /* Card addresses */
76 /* I/O port, IRQ, Buffer address, Env. var, Buf selector. */
77 { 0x1000, 9, 0x00000, "LANCE0" },
78 { 0xD000, 15, 0x00000, "LANCE1" },
81 /* Actually, we use PCI-BIOS info. */
82 PRIVATE struct pcitab
84 u16_t vid;
85 u16_t did;
86 int checkclass;
87 } pcitab[]=
89 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0 }, /* AMD LANCE */
91 { 0x0000, 0x0000, 0 }
94 /* General */
95 _PROTOTYPE( static void do_init, (message *mp) );
96 _PROTOTYPE( static void ec_init, (ether_card_t *ec) );
97 _PROTOTYPE( static void ec_confaddr, (ether_card_t *ec) );
98 _PROTOTYPE( static void ec_reinit, (ether_card_t *ec) );
99 _PROTOTYPE( static void ec_check_ints, (ether_card_t *ec) );
100 _PROTOTYPE( static void conf_hw, (ether_card_t *ec) );
101 _PROTOTYPE( static void update_conf, (ether_card_t *ec, ec_conf_t *ecp) );
102 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
103 _PROTOTYPE( static void do_int, (ether_card_t *ec) );
104 _PROTOTYPE( static void reply,
105 (ether_card_t *ec, int err, int may_block) );
106 _PROTOTYPE( static void ec_reset, (ether_card_t *ec) );
107 _PROTOTYPE( static void ec_send, (ether_card_t *ec) );
108 _PROTOTYPE( static void ec_recv, (ether_card_t *ec) );
109 _PROTOTYPE( static void do_vwrite_s,
110 (message *mp, int from_int) );
111 _PROTOTYPE( static void do_vread_s, (message *mp) );
112 _PROTOTYPE( static void ec_user2nic,
113 (ether_card_t *dep, iovec_dat_t *iovp,
114 vir_bytes offset, int nic_addr,
115 vir_bytes count) );
116 _PROTOTYPE( static void ec_nic2user,
117 (ether_card_t *ec, int nic_addr,
118 iovec_dat_t *iovp, vir_bytes offset,
119 vir_bytes count) );
120 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
121 _PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp) );
122 _PROTOTYPE( static void do_getstat_s, (message *mp) );
123 _PROTOTYPE( static void do_stop, (message *mp) );
124 _PROTOTYPE( static void do_getname, (message *mp) );
126 _PROTOTYPE( static void lance_dump, (void) );
127 _PROTOTYPE( static void lance_stop, (void) );
128 _PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec) );
130 /* probe+init LANCE cards */
131 _PROTOTYPE( static int lance_probe, (ether_card_t *ec) );
132 _PROTOTYPE( static void lance_init_card, (ether_card_t *ec) );
134 /* Accesses Lance Control and Status Registers */
135 _PROTOTYPE( static u8_t in_byte, (port_t port) );
136 _PROTOTYPE( static u16_t in_word, (port_t port) );
137 _PROTOTYPE( static void out_byte, (port_t port, u8_t value) );
138 _PROTOTYPE( static void out_word, (port_t port, u16_t value) );
139 _PROTOTYPE( static u16_t read_csr, (port_t ioaddr, u16_t csrno) );
140 _PROTOTYPE( static void write_csr, (port_t ioaddr, u16_t csrno, u16_t value));
142 /* --- LANCE --- */
143 /* General */
144 #define Address unsigned long
146 #define virt_to_bus(x) (vir2phys((unsigned long)x))
147 unsigned long vir2phys( unsigned long x )
149 int r;
150 unsigned long value;
152 if ( (r=sys_umap( SELF, VM_D, x, 4, &value )) != OK ) {
153 printf("lance: umap of 0x%lx failed\n",x );
154 panic( "lance", "sys_umap failed", r );
157 return value;
160 /* DMA limitations */
161 #define DMA_ADDR_MASK 0xFFFFFF /* mask to verify DMA address is 24-bit */
163 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance_buf + sizeof(struct lance_interface)) & ~DMA_ADDR_MASK) == 0 )
165 #define ETH_FRAME_LEN 1518
167 #define LANCE_MUST_PAD 0x00000001
168 #define LANCE_ENABLE_AUTOSELECT 0x00000002
169 #define LANCE_SELECT_PHONELINE 0x00000004
170 #define LANCE_MUST_UNRESET 0x00000008
172 static const struct lance_chip_type
174 int id_number;
175 const char *name;
176 int flags;
177 } chip_table[] = {
178 {0x0000, "LANCE 7990", /* Ancient lance chip. */
179 LANCE_MUST_PAD + LANCE_MUST_UNRESET},
180 {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
181 LANCE_ENABLE_AUTOSELECT},
182 {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
183 LANCE_ENABLE_AUTOSELECT},
184 {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
185 LANCE_ENABLE_AUTOSELECT},
186 {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
187 LANCE_ENABLE_AUTOSELECT},
188 {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
189 LANCE_ENABLE_AUTOSELECT},
190 {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
191 LANCE_ENABLE_AUTOSELECT},
192 {0x2626, "PCnet/HomePNA 79C978",
193 LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
194 {0x0, "PCnet (unknown)",
195 LANCE_ENABLE_AUTOSELECT},
198 /* ############## for LANCE device ############## */
199 #define LANCE_ETH_ADDR 0x0
200 #define LANCE_DATA 0x10
201 #define LANCE_ADDR 0x12
202 #define LANCE_RESET 0x14
203 #define LANCE_BUS_IF 0x16
204 #define LANCE_TOTAL_SIZE 0x18
206 /* Use 2^4=16 {Rx,Tx} buffers */
207 #define LANCE_LOG_RX_BUFFERS 4
208 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
209 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
210 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
212 #define LANCE_LOG_TX_BUFFERS 4
213 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
214 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
215 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
217 /* for lance_interface */
218 struct lance_init_block
220 unsigned short mode;
221 unsigned char phys_addr[6];
222 unsigned long filter[2];
223 Address rx_ring;
224 Address tx_ring;
227 struct lance_rx_head
229 union {
230 Address base;
231 unsigned char addr[4];
232 } u;
233 short buf_length; /* 2s complement */
234 short msg_length;
237 struct lance_tx_head
239 union {
240 Address base;
241 unsigned char addr[4];
242 } u;
243 short buf_length; /* 2s complement */
244 short misc;
247 struct lance_interface
249 struct lance_init_block init_block;
250 struct lance_rx_head rx_ring[RX_RING_SIZE];
251 struct lance_tx_head tx_ring[TX_RING_SIZE];
252 unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN];
253 unsigned char tbuf[TX_RING_SIZE][ETH_FRAME_LEN];
256 /* =============== global variables =============== */
257 static struct lance_interface *lp;
258 #define LANCE_BUF_SIZE (sizeof(struct lance_interface))
259 static char *lance_buf = NULL;
260 static int rx_slot_nr = 0; /* Rx-slot number */
261 static int tx_slot_nr = 0; /* Tx-slot number */
262 static int cur_tx_slot_nr = 0; /* Tx-slot number */
263 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
264 static char *progname;
266 phys_bytes lance_buf_phys;
268 /* SEF functions and variables. */
269 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
270 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
271 EXTERN int env_argc;
272 EXTERN char **env_argv;
274 /*===========================================================================*
275 * main *
276 *===========================================================================*/
277 void main( int argc, char **argv )
279 message m;
280 int i,irq,r;
281 ether_card_t *ec;
283 /* SEF local startup. */
284 env_setargs(argc, argv);
285 sef_local_startup();
287 while (TRUE)
289 for (i=0;i<EC_PORT_NR_MAX;++i)
291 ec= &ec_table[i];
292 if (ec->ec_irq != 0)
293 sys_irqenable(&ec->ec_hook);
296 if ((r= sef_receive(ANY, &m)) != OK)
297 panic( "lance", "sef_receive failed", r);
299 for (i=0;i<EC_PORT_NR_MAX;++i)
301 ec= &ec_table[i];
302 if (ec->ec_irq != 0)
303 sys_irqdisable(&ec->ec_hook);
306 if (is_notify(m.m_type)) {
307 switch(_ENDPOINT_P(m.m_source)) {
308 case TTY_PROC_NR:
309 lance_dump();
310 break;
311 case HARDWARE:
312 for (i=0;i<EC_PORT_NR_MAX;++i)
314 ec= &ec_table[i];
315 if (ec->mode != EC_ENABLED)
316 continue;
318 irq=ec->ec_irq;
320 ec->ec_int_pending = 0;
321 ec_check_ints(ec);
322 do_int(ec);
325 break;
326 case PM_PROC_NR:
328 sigset_t set;
330 if (getsigset(&set) != 0) break;
332 if (sigismember(&set, SIGTERM))
333 lance_stop();
335 break;
337 default:
338 panic( "lance", "illegal notify source", m.m_source);
341 /* get next message */
342 continue;
345 switch (m.m_type)
347 case DL_WRITEV_S:
348 do_vwrite_s(&m, FALSE);
349 break;
350 case DL_READV_S:
351 do_vread_s(&m);
352 break;
353 case DL_CONF:
354 do_init(&m);
355 break;
356 case DL_GETSTAT_S:
357 do_getstat_s(&m);
358 break;
359 case DL_STOP:
360 do_stop(&m);
361 break;
362 case DL_GETNAME:
363 do_getname(&m);
364 break;
365 default:
366 panic( "lance", "illegal message", m.m_type);
371 /*===========================================================================*
372 * sef_local_startup *
373 *===========================================================================*/
374 PRIVATE void sef_local_startup()
376 /* Register init callbacks. */
377 sef_setcb_init_fresh(sef_cb_init_fresh);
378 sef_setcb_init_restart(sef_cb_init_fresh);
380 /* No live update support for now. */
382 /* Let SEF perform startup. */
383 sef_startup();
386 /*===========================================================================*
387 * sef_cb_init_fresh *
388 *===========================================================================*/
389 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
391 /* Initialize the lance driver. */
392 int r;
393 u32_t tasknr;
394 long v;
395 #if LANCE_FKEY
396 int fkeys, sfkeys;
397 #endif
399 (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
401 #if LANCE_FKEY
402 fkeys = sfkeys = 0;
403 bit_set( sfkeys, 7 );
404 if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
405 printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
406 #endif
408 v= 0;
409 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
410 eth_ign_proto= htons((u16_t) v);
412 /* Try to notify inet that we are present (again) */
413 r= ds_retrieve_label_num("inet", &tasknr);
414 if (r == OK)
415 notify(tasknr);
416 else if (r != ESRCH)
417 printf("lance: ds_retrieve_label_num failed for 'inet': %d\n", r);
419 return(OK);
422 /*===========================================================================*
423 * lance_dump *
424 *===========================================================================*/
425 static void lance_dump()
427 ether_card_t *ec;
428 int i, isr, csr;
429 unsigned short ioaddr;
431 printf("\n");
432 for (i= 0, ec = &ec_table[0]; i<EC_PORT_NR_MAX; i++, ec++)
434 if (ec->mode == EC_DISABLED)
435 printf("lance port %d is disabled\n", i);
436 else if (ec->mode == EC_SINK)
437 printf("lance port %d is in sink mode\n", i);
439 if (ec->mode != EC_ENABLED)
440 continue;
442 printf("lance statistics of port %d:\n", i);
444 printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr);
445 printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr);
446 printf("OVW :%8ld\n", ec->eth_stat.ets_OVW);
448 printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr);
449 printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll);
450 printf("missedP :%8ld\n", ec->eth_stat.ets_missedP);
452 printf("packetR :%8ld\t", ec->eth_stat.ets_packetR);
453 printf("packetT :%8ld\t", ec->eth_stat.ets_packetT);
454 printf("transDef :%8ld\n", ec->eth_stat.ets_transDef);
456 printf("collision :%8ld\t", ec->eth_stat.ets_collision);
457 printf("transAb :%8ld\t", ec->eth_stat.ets_transAb);
458 printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense);
460 printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder);
461 printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver);
462 printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
464 printf("OWC :%8ld\t", ec->eth_stat.ets_OWC);
466 ioaddr = ec->ec_port;
467 isr = read_csr(ioaddr, LANCE_CSR0);
468 printf("isr = 0x%x, flags = 0x%x\n", isr,
469 ec->flags);
471 printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
473 csr = read_csr(ioaddr, LANCE_CSR0);
474 printf("CSR0: 0x%x\n", csr);
475 csr = read_csr(ioaddr, LANCE_CSR3);
476 printf("CSR3: 0x%x\n", csr);
477 csr = read_csr(ioaddr, LANCE_CSR4);
478 printf("CSR4: 0x%x\n", csr);
479 csr = read_csr(ioaddr, LANCE_CSR5);
480 printf("CSR5: 0x%x\n", csr);
481 csr = read_csr(ioaddr, LANCE_CSR15);
482 printf("CSR15: 0x%x\n", csr);
487 /*===========================================================================*
488 * lance_stop *
489 *===========================================================================*/
490 static void lance_stop()
492 message mess;
493 int i;
495 for (i= 0; i<EC_PORT_NR_MAX; i++)
497 if (ec_table[i].mode != EC_ENABLED)
498 continue;
499 mess.m_type= DL_STOP;
500 mess.DL_PORT= i;
501 do_stop(&mess);
504 #if VERBOSE
505 printf("LANCE driver stopped.\n");
506 #endif
508 exit( 0 );
512 /*===========================================================================*
513 * do_init *
514 *===========================================================================*/
515 static void do_init(mp)
516 message *mp;
518 int port;
519 ether_card_t *ec;
520 message reply_mess;
522 pci_init();
524 if(!lance_buf && !(lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M, &lance_buf_phys))) {
525 panic( "lance", "alloc_contig failed", LANCE_BUF_SIZE);
528 port = mp->DL_PORT;
529 if (port < 0 || port >= EC_PORT_NR_MAX)
531 reply_mess.m_type= DL_CONF_REPLY;
532 reply_mess.m3_i1= ENXIO;
533 mess_reply(mp, &reply_mess);
534 return;
537 ec= &ec_table[port];
538 strcpy(ec->port_name, "eth_card#0");
539 ec->port_name[9] += port;
541 if (ec->mode == EC_DISABLED)
543 /* This is the default, try to (re)locate the device. */
544 /* only try to enable if memory is correct for DMA */
545 if ( CORRECT_DMA_MEM() )
547 conf_hw(ec);
549 else
551 report( "LANCE", "DMA denied because address out of range", NO_NUM );
554 if (ec->mode == EC_DISABLED)
556 /* Probe failed, or the device is configured off. */
557 reply_mess.m_type= DL_CONF_REPLY;
558 reply_mess.m3_i1= ENXIO;
559 mess_reply(mp, &reply_mess);
560 return;
562 if (ec->mode == EC_ENABLED)
563 ec_init(ec);
566 if (ec->mode == EC_SINK)
568 ec->mac_address.ea_addr[0] =
569 ec->mac_address.ea_addr[1] =
570 ec->mac_address.ea_addr[2] =
571 ec->mac_address.ea_addr[3] =
572 ec->mac_address.ea_addr[4] =
573 ec->mac_address.ea_addr[5] = 0;
574 ec_confaddr(ec);
575 reply_mess.m_type = DL_CONF_REPLY;
576 reply_mess.m3_i1 = mp->DL_PORT;
577 reply_mess.m3_i2 = EC_PORT_NR_MAX;
578 *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
579 mess_reply(mp, &reply_mess);
580 return;
582 assert(ec->mode == EC_ENABLED);
583 assert(ec->flags & ECF_ENABLED);
585 ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD);
587 if (mp->DL_MODE & DL_PROMISC_REQ)
588 ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD;
589 if (mp->DL_MODE & DL_MULTI_REQ)
590 ec->flags |= ECF_MULTI;
591 if (mp->DL_MODE & DL_BROAD_REQ)
592 ec->flags |= ECF_BROAD;
594 ec->client = mp->m_source;
596 ec_reinit(ec);
598 reply_mess.m_type = DL_CONF_REPLY;
599 reply_mess.m3_i1 = mp->DL_PORT;
600 reply_mess.m3_i2 = EC_PORT_NR_MAX;
601 *(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
603 mess_reply(mp, &reply_mess);
607 /*===========================================================================*
608 * do_int *
609 *===========================================================================*/
610 static void do_int(ec)
611 ether_card_t *ec;
613 if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV))
614 reply(ec, OK, TRUE);
618 /*===========================================================================*
619 * conf_hw *
620 *===========================================================================*/
621 static void conf_hw(ec)
622 ether_card_t *ec;
624 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
626 int ifnr;
627 ec_conf_t *ecp;
629 ec->mode= EC_DISABLED; /* Superfluous */
630 ifnr= ec-ec_table;
632 ecp= &ec_conf[ifnr];
633 update_conf(ec, ecp);
634 if (ec->mode != EC_ENABLED)
635 return;
637 if (!lance_probe(ec))
639 printf("%s: No ethernet card found on PCI-BIOS info.\n",
640 ec->port_name);
641 ec->mode= EC_DISABLED;
642 return;
645 /* XXX */ if (ec->ec_linmem == 0) ec->ec_linmem= 0xFFFF0000;
647 ec->flags = ECF_EMPTY;
648 ec->eth_stat = empty_stat;
652 /*===========================================================================*
653 * update_conf *
654 *===========================================================================*/
655 static void update_conf(ec, ecp)
656 ether_card_t *ec;
657 ec_conf_t *ecp;
659 long v;
660 static char ec_fmt[] = "x:d:x:x";
662 /* Get the default settings and modify them from the environment. */
663 ec->mode= EC_SINK;
664 v= ecp->ec_port;
665 switch (env_parse(ecp->ec_envvar, ec_fmt, 0, &v, 0x0000L, 0xFFFFL))
667 case EP_OFF:
668 ec->mode= EC_DISABLED;
669 break;
670 case EP_ON:
671 case EP_SET:
672 default:
673 ec->mode= EC_ENABLED; /* Might become disabled if
674 * all probes fail */
675 break;
678 ec->ec_port= v;
680 v= ecp->ec_irq | DEI_DEFAULT;
681 (void) env_parse(ecp->ec_envvar, ec_fmt, 1, &v, 0L,
682 (long) NR_IRQ_VECTORS - 1);
683 ec->ec_irq= v;
685 v= ecp->ec_mem;
686 (void) env_parse(ecp->ec_envvar, ec_fmt, 2, &v, 0L, 0xFFFFFL);
687 ec->ec_linmem= v;
689 v= 0;
690 (void) env_parse(ecp->ec_envvar, ec_fmt, 3, &v, 0x2000L, 0x8000L);
691 ec->ec_ramsize= v;
695 /*===========================================================================*
696 * ec_init *
697 *===========================================================================*/
698 static void ec_init(ec)
699 ether_card_t *ec;
701 int i, r;
703 /* General initialization */
704 ec->flags = ECF_EMPTY;
705 lance_init_card(ec); /* Get mac_address, etc ...*/
707 ec_confaddr(ec);
709 #if VERBOSE
710 printf("%s: Ethernet address ", ec->port_name);
711 for (i= 0; i < 6; i++)
712 printf("%x%c", ec->mac_address.ea_addr[i],
713 i < 5 ? ':' : '\n');
714 #endif
716 /* Finish the initialization */
717 ec->flags |= ECF_ENABLED;
719 /* Set the interrupt handler */
720 ec->ec_hook = ec->ec_irq;
721 if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK)
722 printf("lance: error, couldn't set IRQ policy: %d\n", r);
724 return;
728 /*===========================================================================*
729 * reply *
730 *===========================================================================*/
731 static void reply(ec, err, may_block)
732 ether_card_t *ec;
733 int err;
734 int may_block;
736 message reply;
737 int status,r;
738 clock_t now;
740 status = 0;
741 if (ec->flags & ECF_PACK_SEND)
742 status |= DL_PACK_SEND;
743 if (ec->flags & ECF_PACK_RECV)
744 status |= DL_PACK_RECV;
746 reply.m_type = DL_TASK_REPLY;
747 reply.DL_PORT = ec - ec_table;
748 reply.DL_PROC = ec->client;
749 reply.DL_STAT = status | ((u32_t) err << 16);
750 reply.DL_COUNT = ec->read_s;
752 if ((r=getuptime(&now)) != OK)
753 panic("lance", "getuptime() failed:", r);
754 reply.DL_CLCK = now;
756 r = send(ec->client, &reply);
757 if (r == ELOCKED && may_block)
759 return;
761 if (r < 0)
762 panic( "lance", "send failed:", r);
764 ec->read_s = 0;
765 ec->flags &= ~(ECF_PACK_SEND | ECF_PACK_RECV);
769 /*===========================================================================*
770 * mess_reply *
771 *===========================================================================*/
772 static void mess_reply(req, reply_mess)
773 message *req;
774 message *reply_mess;
776 if (send(req->m_source, reply_mess) != OK)
777 panic( "lance", "unable to mess_reply", NO_NUM);
781 /*===========================================================================*
782 * ec_confaddr *
783 *===========================================================================*/
784 static void ec_confaddr(ec)
785 ether_card_t *ec;
787 int i;
788 char eakey[16];
789 static char eafmt[]= "x:x:x:x:x:x";
790 long v;
792 /* User defined ethernet address? */
793 strcpy(eakey, ec_conf[ec-ec_table].ec_envvar);
794 strcat(eakey, "_EA");
796 for (i = 0; i < 6; i++)
798 v= ec->mac_address.ea_addr[i];
799 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
800 break;
801 ec->mac_address.ea_addr[i]= v;
804 if (i != 0 && i != 6)
806 /* It's all or nothing; force a panic. */
807 (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
812 /*===========================================================================*
813 * ec_reinit *
814 *===========================================================================*/
815 static void ec_reinit(ec)
816 ether_card_t *ec;
818 int i;
819 unsigned short ioaddr = ec->ec_port;
821 /* stop */
822 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
824 /* purge Tx-ring */
825 tx_slot_nr = cur_tx_slot_nr = 0;
826 for (i=0; i<TX_RING_SIZE; i++)
828 lp->tx_ring[i].u.base = 0;
829 isstored[i]=0;
832 /* re-init Rx-ring */
833 rx_slot_nr = 0;
834 for (i=0; i<RX_RING_SIZE; i++)
836 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
837 lp->rx_ring[i].u.addr[3] |= 0x80;
840 /* Set 'Receive Mode' */
841 if (ec->flags & ECF_PROMISC)
843 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
845 else
847 if (ec->flags & (ECF_BROAD | ECF_MULTI))
849 write_csr(ioaddr, LANCE_CSR15, 0x0000);
851 else
853 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
857 /* start && enable interrupt */
858 write_csr(ioaddr, LANCE_CSR0,
859 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
861 return;
864 /*===========================================================================*
865 * ec_check_ints *
866 *===========================================================================*/
867 static void ec_check_ints(ec)
868 ether_card_t *ec;
870 int must_restart = 0;
871 int check,status;
872 int isr = 0x0000;
873 unsigned short ioaddr = ec->ec_port;
875 if (!(ec->flags & ECF_ENABLED))
876 panic( "lance", "got premature interrupt", NO_NUM);
878 for (;;)
880 #if VERBOSE
881 printf("ETH: Reading ISR...");
882 #endif
883 isr = read_csr(ioaddr, LANCE_CSR0);
884 if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) {
885 write_csr(ioaddr, LANCE_CSR0,
886 isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP
887 |LANCE_CSR0_STRT|LANCE_CSR0_INIT) );
889 write_csr(ioaddr, LANCE_CSR0,
890 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR
891 |LANCE_CSR0_IDON|LANCE_CSR0_IENA);
893 #define ISR_RST 0x0000
895 if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS
896 |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000)
898 #if VERBOSE
899 printf("OK\n");
900 #endif
901 break;
904 if (isr & LANCE_CSR0_MISS)
906 #if VERBOSE
907 printf("RX Missed Frame\n");
908 #endif
909 ec->eth_stat.ets_recvErr++;
911 if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT))
913 if (isr & LANCE_CSR0_BABL)
915 #if VERBOSE
916 printf("TX Timeout\n");
917 #endif
918 ec->eth_stat.ets_sendErr++;
920 if (isr & LANCE_CSR0_TINT)
922 #if VERBOSE
923 printf("TX INT\n");
924 #endif
925 /* status check: restart if needed. */
926 status = lp->tx_ring[cur_tx_slot_nr].u.base;
928 /* ??? */
929 if (status & 0x40000000)
931 status = lp->tx_ring[cur_tx_slot_nr].misc;
932 ec->eth_stat.ets_sendErr++;
933 if (status & 0x0400)
934 ec->eth_stat.ets_transAb++;
935 if (status & 0x0800)
936 ec->eth_stat.ets_carrSense++;
937 if (status & 0x1000)
938 ec->eth_stat.ets_OWC++;
939 if (status & 0x4000)
941 ec->eth_stat.ets_fifoUnder++;
942 must_restart=1;
945 else
947 if (status & 0x18000000)
948 ec->eth_stat.ets_collision++;
949 ec->eth_stat.ets_packetT++;
952 /* transmit a packet on the next slot if it exists. */
953 check = 0;
954 if (isstored[cur_tx_slot_nr]==1)
956 /* free the tx-slot just transmitted */
957 isstored[cur_tx_slot_nr]=0;
958 cur_tx_slot_nr = (++cur_tx_slot_nr) & TX_RING_MOD_MASK;
960 /* next tx-slot is ready? */
961 if (isstored[cur_tx_slot_nr]==1)
962 check=1;
963 else
964 check=0;
966 else
968 panic( "lance", "got premature TX INT...", NO_NUM);
970 if (check==1)
972 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
973 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
975 else
976 if (check==-1)
977 continue;
978 /* we set a buffered message in the slot if it exists. */
979 /* and transmit it, if needed. */
980 if (ec->flags & ECF_SEND_AVAIL)
981 ec_send(ec);
983 if (isr & LANCE_CSR0_RINT)
985 #if VERBOSE
986 printf("RX INT\n");
987 #endif
988 ec_recv(ec);
991 if (isr & ISR_RST)
993 ec->flags = ECF_STOPPED;
994 #if VERBOSE
995 printf("ISR_RST\n");
996 #endif
997 break;
1000 /* ??? cf. lance driver on linux */
1001 if (must_restart == 1)
1003 #if VERBOSE
1004 printf("ETH: restarting...\n");
1005 #endif
1006 /* stop */
1007 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1008 /* start */
1009 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
1013 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
1015 #if VERBOSE
1016 printf("ETH: resetting...\n");
1017 #endif
1018 ec_reset(ec);
1022 /*===========================================================================*
1023 * ec_reset *
1024 *===========================================================================*/
1025 static void ec_reset(ec)
1026 ether_card_t *ec;
1028 /* Stop/start the chip, and clear all RX,TX-slots */
1029 unsigned short ioaddr = ec->ec_port;
1030 int i;
1032 /* stop */
1033 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1034 /* start */
1035 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
1037 /* purge Tx-ring */
1038 tx_slot_nr = cur_tx_slot_nr = 0;
1039 for (i=0; i<TX_RING_SIZE; i++)
1041 lp->tx_ring[i].u.base = 0;
1042 isstored[i]=0;
1045 /* re-init Rx-ring */
1046 rx_slot_nr = 0;
1047 for (i=0; i<RX_RING_SIZE; i++)
1049 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
1050 lp->rx_ring[i].u.addr[3] |= 0x80;
1053 /* store a buffered message on the slot if exists */
1054 ec_send(ec);
1055 ec->flags &= ~ECF_STOPPED;
1058 /*===========================================================================*
1059 * ec_send *
1060 *===========================================================================*/
1061 static void ec_send(ec)
1062 ether_card_t *ec;
1064 /* from ec_check_ints() or ec_reset(). */
1065 /* this function proccesses the buffered message. (slot/transmit) */
1066 if (!(ec->flags & ECF_SEND_AVAIL))
1067 return;
1069 ec->flags &= ~ECF_SEND_AVAIL;
1070 switch(ec->sendmsg.m_type)
1072 case DL_WRITEV_S: do_vwrite_s(&ec->sendmsg, TRUE); break;
1073 default:
1074 panic( "lance", "wrong type:", ec->sendmsg.m_type);
1075 break;
1079 /*===========================================================================*
1080 * do_vread_s *
1081 *===========================================================================*/
1082 static void do_vread_s(mp)
1083 message *mp;
1085 int port, count, size, r;
1086 ether_card_t *ec;
1088 port = mp->DL_PORT;
1089 count = mp->DL_COUNT;
1090 ec= &ec_table[port];
1091 ec->client= mp->DL_PROC;
1093 r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0,
1094 (vir_bytes)ec->read_iovec.iod_iovec,
1095 (count > IOVEC_NR ? IOVEC_NR : count) *
1096 sizeof(iovec_s_t), D);
1097 if (r != OK)
1098 panic(__FILE__,
1099 "do_vread_s: sys_safecopyfrom failed: %d\n", r);
1100 ec->read_iovec.iod_iovec_s = count;
1101 ec->read_iovec.iod_proc_nr = mp->DL_PROC;
1102 ec->read_iovec.iod_grant = (vir_bytes) mp->DL_GRANT;
1103 ec->read_iovec.iod_iovec_offset = 0;
1105 ec->tmp_iovec = ec->read_iovec;
1106 size= calc_iovec_size(&ec->tmp_iovec);
1108 ec->flags |= ECF_READING;
1110 ec_recv(ec);
1112 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
1113 ec_reset(ec);
1114 reply(ec, OK, FALSE);
1117 /*===========================================================================*
1118 * ec_recv *
1119 *===========================================================================*/
1120 static void ec_recv(ec)
1121 ether_card_t *ec;
1123 vir_bytes length;
1124 int packet_processed;
1125 int status;
1126 unsigned short ioaddr = ec->ec_port;
1128 if ((ec->flags & ECF_READING)==0)
1129 return;
1130 if (!(ec->flags & ECF_ENABLED))
1131 return;
1133 /* we check all the received slots until find a properly received packet */
1134 packet_processed = FALSE;
1135 while (!packet_processed)
1137 status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1138 if ( (status & 0x80) == 0x00 )
1140 status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1142 /* ??? */
1143 if (status != 0x03)
1145 if (status & 0x01)
1146 ec->eth_stat.ets_recvErr++;
1147 if (status & 0x04)
1148 ec->eth_stat.ets_fifoOver++;
1149 if (status & 0x08)
1150 ec->eth_stat.ets_CRCerr++;
1151 if (status & 0x10)
1152 ec->eth_stat.ets_OVW++;
1153 if (status & 0x20)
1154 ec->eth_stat.ets_frameAll++;
1155 length = 0;
1157 else
1159 ec->eth_stat.ets_packetR++;
1160 length = lp->rx_ring[rx_slot_nr].msg_length;
1162 if (length > 0)
1164 ec_nic2user(ec, (int)(lp->rbuf[rx_slot_nr]),
1165 &ec->read_iovec, 0, length);
1167 ec->read_s = length;
1168 ec->flags |= ECF_PACK_RECV;
1169 ec->flags &= ~ECF_READING;
1170 packet_processed = TRUE;
1172 /* set up this slot again, and we move to the next slot */
1173 lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN;
1174 lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80;
1176 write_csr(ioaddr, LANCE_CSR0,
1177 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS
1178 |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA);
1180 rx_slot_nr = (++rx_slot_nr) & RX_RING_MOD_MASK;
1182 else
1183 break;
1187 /*===========================================================================*
1188 * do_vwrite_s *
1189 *===========================================================================*/
1190 static void do_vwrite_s(mp, from_int)
1191 message *mp;
1192 int from_int;
1194 int port, count, check, r;
1195 ether_card_t *ec;
1196 unsigned short ioaddr;
1198 port = mp->DL_PORT;
1199 count = mp->DL_COUNT;
1200 ec = &ec_table[port];
1201 ec->client= mp->DL_PROC;
1203 if (isstored[tx_slot_nr]==1)
1205 /* all slots are used, so this message is buffered */
1206 ec->sendmsg= *mp;
1207 ec->flags |= ECF_SEND_AVAIL;
1208 reply(ec, OK, FALSE);
1209 return;
1212 /* convert the message to write_iovec */
1213 r = sys_safecopyfrom(mp->DL_PROC, mp->DL_GRANT, 0,
1214 (vir_bytes)ec->write_iovec.iod_iovec,
1215 (count > IOVEC_NR ? IOVEC_NR : count) *
1216 sizeof(iovec_s_t), D);
1217 if (r != OK)
1218 panic(__FILE__,
1219 "do_vwrite_s: sys_safecopyfrom failed: %d\n", r);
1221 ec->write_iovec.iod_iovec_s = count;
1222 ec->write_iovec.iod_proc_nr = mp->DL_PROC;
1223 ec->write_iovec.iod_grant = mp->DL_GRANT;
1224 ec->write_iovec.iod_iovec_offset = 0;
1226 ec->tmp_iovec = ec->write_iovec;
1227 ec->write_s = calc_iovec_size(&ec->tmp_iovec);
1229 /* copy write_iovec to the slot on DMA address */
1230 ec_user2nic(ec, &ec->write_iovec, 0,
1231 (int)(lp->tbuf[tx_slot_nr]), ec->write_s);
1232 /* set-up for transmitting, and transmit it if needed. */
1233 lp->tx_ring[tx_slot_nr].buf_length = -ec->write_s;
1234 lp->tx_ring[tx_slot_nr].misc = 0x0;
1235 lp->tx_ring[tx_slot_nr].u.base
1236 = virt_to_bus(lp->tbuf[tx_slot_nr]) & 0xffffff;
1237 isstored[tx_slot_nr]=1;
1238 if (cur_tx_slot_nr == tx_slot_nr)
1239 check=1;
1240 else
1241 check=0;
1242 tx_slot_nr = (++tx_slot_nr) & TX_RING_MOD_MASK;
1244 if (check == 1)
1246 ioaddr = ec->ec_port;
1247 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
1248 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
1251 ec->flags |= ECF_PACK_SEND;
1253 /* reply by calling do_int() if this function is called from interrupt. */
1254 if (from_int)
1255 return;
1256 reply(ec, OK, FALSE);
1260 /*===========================================================================*
1261 * ec_user2nic *
1262 *===========================================================================*/
1263 static void ec_user2nic(ec, iovp, offset, nic_addr, count)
1264 ether_card_t *ec;
1265 iovec_dat_t *iovp;
1266 vir_bytes offset;
1267 int nic_addr;
1268 vir_bytes count;
1270 int bytes, i, r;
1272 i= 0;
1273 while (count > 0)
1275 if (i >= IOVEC_NR)
1277 ec_next_iovec(iovp);
1278 i= 0;
1279 continue;
1281 if (offset >= iovp->iod_iovec[i].iov_size)
1283 offset -= iovp->iod_iovec[i].iov_size;
1284 i++;
1285 continue;
1287 bytes = iovp->iod_iovec[i].iov_size - offset;
1288 if (bytes > count)
1289 bytes = count;
1291 if ( (r=sys_safecopyfrom(iovp->iod_proc_nr,
1292 iovp->iod_iovec[i].iov_grant, offset,
1293 nic_addr, bytes, D )) != OK )
1294 panic( __FILE__, "ec_user2nic: sys_safecopyfrom failed", r );
1296 count -= bytes;
1297 nic_addr += bytes;
1298 offset += bytes;
1302 /*===========================================================================*
1303 * ec_nic2user *
1304 *===========================================================================*/
1305 static void ec_nic2user(ec, nic_addr, iovp, offset, count)
1306 ether_card_t *ec;
1307 int nic_addr;
1308 iovec_dat_t *iovp;
1309 vir_bytes offset;
1310 vir_bytes count;
1312 int bytes, i, r;
1314 i= 0;
1315 while (count > 0)
1317 if (i >= IOVEC_NR)
1319 ec_next_iovec(iovp);
1320 i= 0;
1321 continue;
1323 if (offset >= iovp->iod_iovec[i].iov_size)
1325 offset -= iovp->iod_iovec[i].iov_size;
1326 i++;
1327 continue;
1329 bytes = iovp->iod_iovec[i].iov_size - offset;
1330 if (bytes > count)
1331 bytes = count;
1332 if ( (r=sys_safecopyto( iovp->iod_proc_nr, iovp->iod_iovec[i].iov_grant,
1333 offset, nic_addr, bytes, D )) != OK )
1334 panic( __FILE__, "ec_nic2user: sys_safecopyto failed: ", r );
1336 count -= bytes;
1337 nic_addr += bytes;
1338 offset += bytes;
1343 /*===========================================================================*
1344 * calc_iovec_size *
1345 *===========================================================================*/
1346 static int calc_iovec_size(iovp)
1347 iovec_dat_t *iovp;
1349 int size,i;
1351 size = i = 0;
1353 while (i < iovp->iod_iovec_s)
1355 if (i >= IOVEC_NR)
1357 ec_next_iovec(iovp);
1358 i= 0;
1359 continue;
1361 size += iovp->iod_iovec[i].iov_size;
1362 i++;
1365 return size;
1368 /*===========================================================================*
1369 * ec_next_iovec *
1370 *===========================================================================*/
1371 static void ec_next_iovec(iovp)
1372 iovec_dat_t *iovp;
1374 int r;
1376 iovp->iod_iovec_s -= IOVEC_NR;
1377 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_s_t);
1379 r = sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_grant,
1380 iovp->iod_iovec_offset,
1381 (vir_bytes)iovp->iod_iovec,
1382 (iovp->iod_iovec_s > IOVEC_NR ?
1383 IOVEC_NR : iovp->iod_iovec_s) *
1384 sizeof(iovec_s_t), D);
1385 if (r != OK)
1386 panic(__FILE__,
1387 "ec_next_iovec: sys_safecopyfrom failed: %d\n", r);
1391 /*===========================================================================*
1392 * do_getstat_s *
1393 *===========================================================================*/
1394 static void do_getstat_s(mp)
1395 message *mp;
1397 int r, port;
1398 ether_card_t *ec;
1400 port = mp->DL_PORT;
1401 if (port < 0 || port >= EC_PORT_NR_MAX)
1402 panic( "lance", "illegal port", port);
1404 ec= &ec_table[port];
1405 ec->client= mp->DL_PROC;
1407 r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
1408 (vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat), D);
1410 if (r != OK)
1411 panic(__FILE__,
1412 "do_getstat_s: sys_safecopyto failed: %d\n", r);
1414 mp->m_type= DL_STAT_REPLY;
1415 mp->DL_PORT= port;
1416 mp->DL_STAT= OK;
1417 r= send(mp->m_source, mp);
1418 if (r != OK)
1419 panic(__FILE__, "do_getstat_s: send failed: %d\n", r);
1422 /*===========================================================================*
1423 * do_stop *
1424 *===========================================================================*/
1425 static void do_stop(mp)
1426 message *mp;
1428 int port;
1429 ether_card_t *ec;
1430 unsigned short ioaddr;
1432 port = mp->DL_PORT;
1433 if (port < 0 || port >= EC_PORT_NR_MAX)
1434 panic( "lance", "illegal port", port);
1435 ec = &ec_table[port];
1437 if (!(ec->flags & ECF_ENABLED))
1438 return;
1440 ioaddr = ec->ec_port;
1442 /* stop */
1443 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1445 /* Reset */
1446 in_word(ioaddr+LANCE_RESET);
1448 ec->flags = ECF_EMPTY;
1451 /*===========================================================================*
1452 * getAddressing *
1453 *===========================================================================*/
1454 static void getAddressing(devind, ec)
1455 int devind;
1456 ether_card_t *ec;
1458 unsigned int membase, ioaddr;
1459 int reg, irq;
1461 for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4)
1463 ioaddr = pci_attr_r32(devind, reg);
1465 if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0
1466 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
1467 continue;
1468 /* Strip the I/O address out of the returned value */
1469 ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
1470 /* Get the memory base address */
1471 membase = pci_attr_r32(devind, PCI_BASE_ADDRESS_1);
1472 /* KK: Get the IRQ number */
1473 irq = pci_attr_r8(devind, PCI_INTERRUPT_PIN);
1474 if (irq)
1475 irq = pci_attr_r8(devind, PCI_INTERRUPT_LINE);
1477 ec->ec_linmem = membase;
1478 ec->ec_port = ioaddr;
1479 ec->ec_irq = irq;
1483 /*===========================================================================*
1484 * lance_probe *
1485 *===========================================================================*/
1486 static int lance_probe(ec)
1487 ether_card_t *ec;
1489 unsigned short pci_cmd;
1490 unsigned short ioaddr;
1491 int lance_version, chip_version;
1492 int devind, just_one, i, r;
1494 u16_t vid, did;
1495 char *dname;
1497 if ((ec->ec_pcibus | ec->ec_pcidev | ec->ec_pcifunc) != 0)
1499 /* Look for specific PCI device */
1500 r= pci_find_dev(ec->ec_pcibus, ec->ec_pcidev,
1501 ec->ec_pcifunc, &devind);
1502 if (r == 0)
1504 printf("%s: no PCI found at %d.%d.%d\n",
1505 ec->port_name, ec->ec_pcibus,
1506 ec->ec_pcidev, ec->ec_pcifunc);
1507 return 0;
1509 pci_ids(devind, &vid, &did);
1510 just_one= TRUE;
1512 else
1514 r= pci_first_dev(&devind, &vid, &did);
1515 if (r == 0)
1516 return 0;
1517 just_one= FALSE;
1520 for(;;)
1522 for (i= 0; pcitab[i].vid != 0; i++)
1524 if (pcitab[i].vid != vid)
1525 continue;
1526 if (pcitab[i].did != did)
1527 continue;
1528 if (pcitab[i].checkclass)
1530 panic("lance",
1531 "class check not implemented", NO_NUM);
1533 break;
1535 if (pcitab[i].vid != 0)
1536 break;
1538 if (just_one)
1540 printf(
1541 "%s: wrong PCI device (%04x/%04x) found at %d.%d.%d\n",
1542 ec->port_name, vid, did,
1543 ec->ec_pcibus,
1544 ec->ec_pcidev, ec->ec_pcifunc);
1545 return 0;
1548 r= pci_next_dev(&devind, &vid, &did);
1549 if (!r)
1550 return 0;
1553 dname= pci_dev_name(vid, did);
1554 if (!dname)
1555 dname= "unknown device";
1557 pci_reserve(devind);
1559 getAddressing(devind, ec);
1562 /* ===== Bus Master ? ===== */
1563 pci_cmd = pci_attr_r32(devind, PCI_CR);
1564 if (!(pci_cmd & PCI_COMMAND_MASTER)) {
1565 pci_cmd |= PCI_COMMAND_MASTER;
1566 pci_attr_w32(devind, PCI_CR, pci_cmd);
1569 /* ===== Probe Details ===== */
1570 ioaddr = ec->ec_port;
1572 /* Reset */
1573 in_word(ioaddr+LANCE_RESET);
1575 if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP)
1577 ec->mode=EC_DISABLED;
1580 /* Probe Chip Version */
1581 out_word(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */
1582 if (in_word(ioaddr+LANCE_ADDR) != 88)
1583 lance_version = 0;
1584 else
1586 chip_version = read_csr(ioaddr, LANCE_CSR88);
1587 chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16;
1589 if ((chip_version & 0xfff) != 0x3)
1591 ec->mode=EC_DISABLED;
1593 chip_version = (chip_version >> 12) & 0xffff;
1594 for (lance_version = 1; chip_table[lance_version].id_number != 0;
1595 ++lance_version)
1596 if (chip_table[lance_version].id_number == chip_version)
1597 break;
1600 #if VERBOSE
1601 printf("%s: %s at %X:%d\n",
1602 ec->port_name, chip_table[lance_version].name,
1603 ec->ec_port, ec->ec_irq);
1604 #endif
1606 return lance_version;
1609 /*===========================================================================*
1610 * do_getname *
1611 *===========================================================================*/
1612 static void do_getname(mp)
1613 message *mp;
1615 int r;
1617 strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
1618 mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
1619 mp->m_type= DL_NAME_REPLY;
1620 r= send(mp->m_source, mp);
1621 if (r != OK)
1622 panic("LANCE", "do_getname: send failed", r);
1625 /*===========================================================================*
1626 * lance_init_card *
1627 *===========================================================================*/
1628 static void lance_init_card(ec)
1629 ether_card_t *ec;
1631 int i;
1632 Address l = (vir_bytes)lance_buf;
1633 unsigned short ioaddr = ec->ec_port;
1635 /* ============= setup init_block(cf. lance_probe1) ================ */
1636 /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */
1638 lp = (struct lance_interface *)l;
1640 /* disable Tx and Rx */
1641 lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX;
1642 lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
1643 /* using multiple Rx/Tx buffer */
1644 lp->init_block.rx_ring
1645 = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
1646 lp->init_block.tx_ring
1647 = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
1649 l = virt_to_bus(&lp->init_block);
1650 write_csr(ioaddr, LANCE_CSR1, (unsigned short)l);
1651 write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16));
1652 write_csr(ioaddr, LANCE_CSR4,
1653 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1654 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1656 /* ============= Get MAC address (cf. lance_probe1) ================ */
1657 for (i = 0; i < 6; ++i)
1658 ec->mac_address.ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i);
1660 /* ============ (re)start init_block(cf. lance_reset) =============== */
1661 /* Reset the LANCE */
1662 (void)in_word(ioaddr+LANCE_RESET);
1664 /* ----- Re-initialize the LANCE ----- */
1665 /* Set station address */
1666 for (i = 0; i < 6; ++i)
1667 lp->init_block.phys_addr[i] = ec->mac_address.ea_addr[i];
1668 /* Preset the receive ring headers */
1669 for (i=0; i<RX_RING_SIZE; i++)
1671 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
1672 /* OWN */
1673 lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
1674 /* we set the top byte as the very last thing */
1675 lp->rx_ring[i].u.addr[3] = 0x80;
1677 /* Preset the transmitting ring headers */
1678 for (i=0; i<TX_RING_SIZE; i++)
1680 lp->tx_ring[i].u.base = 0;
1681 isstored[i] = 0;
1683 /* enable Rx and Tx */
1684 lp->init_block.mode = 0x0;
1686 l = (Address)virt_to_bus(&lp->init_block);
1687 write_csr(ioaddr, LANCE_CSR1, (short)l);
1688 write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16));
1689 write_csr(ioaddr, LANCE_CSR4,
1690 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1691 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1693 /* ----- start when init done. ----- */
1694 /* stop */
1695 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1696 /* init */
1697 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT);
1698 /* poll for IDON */
1699 for (i = 10000; i > 0; --i)
1700 if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON)
1701 break;
1703 /* Set 'Multicast Table' */
1704 for (i=0;i<4;++i)
1706 write_csr(ioaddr, LANCE_CSR8 + i, 0xffff);
1709 /* Set 'Receive Mode' */
1710 if (ec->flags & ECF_PROMISC)
1712 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
1714 else
1716 if (ec->flags & (ECF_BROAD | ECF_MULTI))
1718 write_csr(ioaddr, LANCE_CSR15, 0x0000);
1720 else
1722 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
1726 /* start && enable interrupt */
1727 write_csr(ioaddr, LANCE_CSR0,
1728 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
1730 return;
1733 /*===========================================================================*
1734 * in_byte *
1735 *===========================================================================*/
1736 static u8_t in_byte(port_t port)
1738 int r;
1739 u32_t value;
1741 r= sys_inb(port, &value);
1742 if (r != OK)
1743 panic("lance","sys_inb failed", r);
1744 return value;
1747 /*===========================================================================*
1748 * in_word *
1749 *===========================================================================*/
1750 static u16_t in_word(port_t port)
1752 int r;
1753 u32_t value;
1755 r= sys_inw(port, &value);
1756 if (r != OK)
1757 panic("lance","sys_inw failed", r);
1758 return value;
1761 /*===========================================================================*
1762 * out_byte *
1763 *===========================================================================*/
1764 static void out_byte(port_t port, u8_t value)
1766 int r;
1768 r= sys_outb(port, value);
1769 if (r != OK)
1770 panic("lance","sys_outb failed", r);
1773 /*===========================================================================*
1774 * out_word *
1775 *===========================================================================*/
1776 static void out_word(port_t port, u16_t value)
1778 int r;
1780 r= sys_outw(port, value);
1781 if (r != OK)
1782 panic("lance","sys_outw failed", r);
1785 /*===========================================================================*
1786 * read_csr *
1787 *===========================================================================*/
1788 static u16_t read_csr(port_t ioaddr, u16_t csrno)
1790 out_word(ioaddr+LANCE_ADDR, csrno);
1791 return in_word(ioaddr+LANCE_DATA);
1794 /*===========================================================================*
1795 * write_csr *
1796 *===========================================================================*/
1797 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value)
1799 out_word(ioaddr+LANCE_ADDR, csrno);
1800 out_word(ioaddr+LANCE_DATA, value);