3.1.7 branch.
[minix.git] / drivers / lance / lance.c
blob4af5a7c2e86bd86a5ce7715159676f659beb5cde
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_ENDPT DL_COUNT DL_MODE DL_GRANT
10 * |--------------+---------+----------+---------+---------|
11 * | DL_WRITEV_S | endpt | count | | grant |
12 * |--------------|---------|----------|---------|---------|
13 * | DL_READV_S | endpt | count | | grant |
14 * |--------------|---------|----------|---------|---------|
15 * | DL_CONF | | | mode | |
16 * |--------------|---------|----------|---------|---------|
17 * | DL_GETSTAT_S | endpt | | | grant |
18 * |--------------|---------|----------|---------|---------|
19 * | hardware int | | | | |
20 * |--------------|---------|----------|---------|---------|
22 * The messages sent are:
24 * m_type DL_COUNT DL_FLAGS
25 * |---------------+----------+---------|
26 * | DL_TASK_REPLY | rd-count | flags |
27 * |---------------|----------|---------|
29 * m_type
30 * |---------------|
31 * | DL_STAT_REPLY |
32 * |---------------|
34 * m_type DL_STAT DL_ADDR
35 * |---------------+---------+---------------|
36 * | DL_CONF_REPLY | code | ethernet addr |
37 * |---------------|---------|---------------|
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>
43 #define VERBOSE 0 /* Verbose debugging output */
44 #define LANCE_FKEY 0 /* Use function key to dump Lance stats */
46 #include <minix/drivers.h>
47 #include <minix/netdriver.h>
49 #include <net/hton.h>
50 #include <net/gen/ether.h>
51 #include <net/gen/eth_io.h>
52 #include <assert.h>
54 #include <minix/syslib.h>
55 #include <minix/endpoint.h>
56 #include <machine/pci.h>
57 #include <minix/ds.h>
59 #include "lance.h"
61 static ether_card_t ec_state;
62 static int ec_instance;
64 /* Configuration */
65 typedef struct ec_conf
67 port_t ec_port;
68 int ec_irq;
69 phys_bytes ec_mem;
70 } ec_conf_t;
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 */
76 /* I/O port, IRQ, Buffer address. */
77 { 0x1000, 9, 0x00000, },
78 { 0xD000, 15, 0x00000, },
79 { 0x0000, 0, 0x00000, },
82 /* Actually, we use PCI-BIOS info. */
83 PRIVATE struct pcitab
85 u16_t vid;
86 u16_t did;
87 int checkclass;
88 } pcitab[]=
90 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0 }, /* AMD LANCE */
92 { 0x0000, 0x0000, 0 }
95 /* General */
96 _PROTOTYPE( static void do_init, (message *mp) );
97 _PROTOTYPE( static void ec_init, (ether_card_t *ec) );
98 _PROTOTYPE( static void ec_confaddr, (ether_card_t *ec) );
99 _PROTOTYPE( static void ec_reinit, (ether_card_t *ec) );
100 _PROTOTYPE( static void ec_check_ints, (ether_card_t *ec) );
101 _PROTOTYPE( static void conf_hw, (ether_card_t *ec) );
102 _PROTOTYPE( static void update_conf, (ether_card_t *ec, ec_conf_t *ecp) );
103 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
104 _PROTOTYPE( static void do_int, (ether_card_t *ec) );
105 _PROTOTYPE( static void reply, (ether_card_t *ec) );
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, (message *mp, int from_int) );
110 _PROTOTYPE( static void do_vread_s, (const message *mp) );
111 _PROTOTYPE( static void ec_user2nic,
112 (ether_card_t *dep, iovec_dat_t *iovp,
113 vir_bytes offset, int nic_addr,
114 vir_bytes count) );
115 _PROTOTYPE( static void ec_nic2user,
116 (ether_card_t *ec, int nic_addr,
117 iovec_dat_t *iovp, vir_bytes offset,
118 vir_bytes count) );
119 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
120 _PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp) );
121 _PROTOTYPE( static void do_getstat_s, (message *mp) );
122 _PROTOTYPE( static void lance_stop, (ether_card_t *ec) );
124 _PROTOTYPE( static void lance_dump, (void) );
125 _PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec) );
127 /* probe+init LANCE cards */
128 _PROTOTYPE( static int lance_probe, (ether_card_t *ec, int skip) );
129 _PROTOTYPE( static void lance_init_card, (ether_card_t *ec) );
131 /* Accesses Lance Control and Status Registers */
132 _PROTOTYPE( static u8_t in_byte, (port_t port) );
133 _PROTOTYPE( static u16_t in_word, (port_t port) );
134 _PROTOTYPE( static void out_word, (port_t port, u16_t value) );
135 _PROTOTYPE( static u16_t read_csr, (port_t ioaddr, u16_t csrno) );
136 _PROTOTYPE( static void write_csr, (port_t ioaddr, u16_t csrno, u16_t value));
138 /* --- LANCE --- */
139 /* General */
140 typedef unsigned long Address;
142 #define virt_to_bus(x) (vir2phys((unsigned long)x))
143 unsigned long vir2phys( unsigned long x )
145 int r;
146 unsigned long value;
148 if ( (r=sys_umap( SELF, VM_D, x, 4, &value )) != OK ) {
149 printf("lance: umap of 0x%lx failed\n",x );
150 panic("sys_umap failed: %d", r);
153 return value;
156 /* DMA limitations */
157 #define DMA_ADDR_MASK 0xFFFFFF /* mask to verify DMA address is 24-bit */
159 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance_buf + sizeof(struct lance_interface)) & ~DMA_ADDR_MASK) == 0 )
161 #define ETH_FRAME_LEN 1518
163 #define LANCE_MUST_PAD 0x00000001
164 #define LANCE_ENABLE_AUTOSELECT 0x00000002
165 #define LANCE_SELECT_PHONELINE 0x00000004
166 #define LANCE_MUST_UNRESET 0x00000008
168 static const struct lance_chip_type
170 int id_number;
171 const char *name;
172 int flags;
173 } chip_table[] = {
174 {0x0000, "LANCE 7990", /* Ancient lance chip. */
175 LANCE_MUST_PAD + LANCE_MUST_UNRESET},
176 {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
177 LANCE_ENABLE_AUTOSELECT},
178 {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
179 LANCE_ENABLE_AUTOSELECT},
180 {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
181 LANCE_ENABLE_AUTOSELECT},
182 {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
183 LANCE_ENABLE_AUTOSELECT},
184 {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
185 LANCE_ENABLE_AUTOSELECT},
186 {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
187 LANCE_ENABLE_AUTOSELECT},
188 {0x2626, "PCnet/HomePNA 79C978",
189 LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
190 {0x0, "PCnet (unknown)",
191 LANCE_ENABLE_AUTOSELECT},
194 /* ############## for LANCE device ############## */
195 #define LANCE_ETH_ADDR 0x0
196 #define LANCE_DATA 0x10
197 #define LANCE_ADDR 0x12
198 #define LANCE_RESET 0x14
199 #define LANCE_BUS_IF 0x16
200 #define LANCE_TOTAL_SIZE 0x18
202 /* Use 2^4=16 {Rx,Tx} buffers */
203 #define LANCE_LOG_RX_BUFFERS 4
204 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
205 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
206 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
208 #define LANCE_LOG_TX_BUFFERS 4
209 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
210 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
211 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
213 /* for lance_interface */
214 struct lance_init_block
216 unsigned short mode;
217 unsigned char phys_addr[6];
218 unsigned long filter[2];
219 Address rx_ring;
220 Address tx_ring;
223 struct lance_rx_head
225 union {
226 Address base;
227 unsigned char addr[4];
228 } u;
229 short buf_length; /* 2s complement */
230 short msg_length;
233 struct lance_tx_head
235 union {
236 Address base;
237 unsigned char addr[4];
238 } u;
239 short buf_length; /* 2s complement */
240 short misc;
243 struct lance_interface
245 struct lance_init_block init_block;
246 struct lance_rx_head rx_ring[RX_RING_SIZE];
247 struct lance_tx_head tx_ring[TX_RING_SIZE];
248 unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN];
249 unsigned char tbuf[TX_RING_SIZE][ETH_FRAME_LEN];
252 /* =============== global variables =============== */
253 /* AKA the stuff that really should have been in ether_card_t */
254 static struct lance_interface *lp;
255 #define LANCE_BUF_SIZE (sizeof(struct lance_interface))
256 static char *lance_buf = NULL;
257 static int rx_slot_nr = 0; /* Rx-slot number */
258 static int tx_slot_nr = 0; /* Tx-slot number */
259 static int cur_tx_slot_nr = 0; /* Tx-slot number */
260 static char isstored[TX_RING_SIZE]; /* Tx-slot in-use */
262 phys_bytes lance_buf_phys;
264 /* SEF functions and variables. */
265 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
266 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
267 FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
268 EXTERN char **env_argv;
270 /*===========================================================================*
271 * main *
272 *===========================================================================*/
273 int main( int argc, char **argv )
275 message m;
276 int ipc_status;
277 int r;
278 ether_card_t *ec;
280 /* SEF local startup. */
281 env_setargs(argc, argv);
282 sef_local_startup();
284 ec= &ec_state;
286 while (TRUE)
288 if (ec->ec_irq != 0)
289 sys_irqenable(&ec->ec_hook);
291 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
292 panic("netdriver_receive failed: %d", r);
294 if (ec->ec_irq != 0)
295 sys_irqdisable(&ec->ec_hook);
297 if (is_ipc_notify(ipc_status)) {
298 switch(_ENDPOINT_P(m.m_source)) {
299 case TTY_PROC_NR:
300 lance_dump();
301 break;
302 case HARDWARE:
303 if (ec->mode == EC_ENABLED)
305 ec->ec_int_pending = 0;
306 ec_check_ints(ec);
307 do_int(ec);
309 break;
310 default:
311 panic("illegal notify source: %d", m.m_source);
314 /* get next message */
315 continue;
318 switch (m.m_type)
320 case DL_WRITEV_S:
321 do_vwrite_s(&m, FALSE);
322 break;
323 case DL_READV_S:
324 do_vread_s(&m);
325 break;
326 case DL_CONF:
327 do_init(&m);
328 break;
329 case DL_GETSTAT_S:
330 do_getstat_s(&m);
331 break;
332 default:
333 panic("illegal message: %d", m.m_type);
337 return 0;
340 /*===========================================================================*
341 * sef_local_startup *
342 *===========================================================================*/
343 PRIVATE void sef_local_startup()
345 /* Register init callbacks. */
346 sef_setcb_init_fresh(sef_cb_init_fresh);
347 sef_setcb_init_lu(sef_cb_init_fresh);
348 sef_setcb_init_restart(sef_cb_init_fresh);
350 /* Register live update callbacks. */
351 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
352 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
354 /* Register signal callbacks. */
355 sef_setcb_signal_handler(sef_cb_signal_handler);
357 /* Let SEF perform startup. */
358 sef_startup();
361 /*===========================================================================*
362 * sef_cb_init_fresh *
363 *===========================================================================*/
364 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
366 /* Initialize the lance driver. */
367 long v;
368 #if LANCE_FKEY
369 int r, fkeys, sfkeys;
370 #endif
372 #if LANCE_FKEY
373 fkeys = sfkeys = 0;
374 bit_set( sfkeys, 7 );
375 if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
376 printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
377 #endif
379 v = 0;
380 (void) env_parse("instance", "d", 0, &v, 0, 255);
381 ec_instance = (int) v;
383 /* Announce we are up! */
384 netdriver_announce();
386 return OK;
389 /*===========================================================================*
390 * sef_cb_signal_handler *
391 *===========================================================================*/
392 PRIVATE void sef_cb_signal_handler(int signo)
395 /* Only check for termination signal, ignore anything else. */
396 if (signo != SIGTERM) return;
398 if (ec_state.mode == EC_ENABLED)
399 lance_stop(&ec_state);
401 #if VERBOSE
402 printf("LANCE driver stopped.\n");
403 #endif
405 exit(0);
408 /*===========================================================================*
409 * lance_dump *
410 *===========================================================================*/
411 static void lance_dump()
413 ether_card_t *ec;
414 int isr, csr;
415 unsigned short ioaddr;
417 printf("\n");
418 ec = &ec_state;
419 if (ec->mode == EC_DISABLED)
420 printf("lance instance %d is disabled\n", ec_instance);
421 else if (ec->mode == EC_SINK)
422 printf("lance instance %d is in sink mode\n", ec_instance);
424 if (ec->mode != EC_ENABLED)
425 return;
427 printf("lance statistics of instance %d:\n", ec_instance);
429 printf("recvErr :%8ld\t", ec->eth_stat.ets_recvErr);
430 printf("sendErr :%8ld\t", ec->eth_stat.ets_sendErr);
431 printf("OVW :%8ld\n", ec->eth_stat.ets_OVW);
433 printf("CRCerr :%8ld\t", ec->eth_stat.ets_CRCerr);
434 printf("frameAll :%8ld\t", ec->eth_stat.ets_frameAll);
435 printf("missedP :%8ld\n", ec->eth_stat.ets_missedP);
437 printf("packetR :%8ld\t", ec->eth_stat.ets_packetR);
438 printf("packetT :%8ld\t", ec->eth_stat.ets_packetT);
439 printf("transDef :%8ld\n", ec->eth_stat.ets_transDef);
441 printf("collision :%8ld\t", ec->eth_stat.ets_collision);
442 printf("transAb :%8ld\t", ec->eth_stat.ets_transAb);
443 printf("carrSense :%8ld\n", ec->eth_stat.ets_carrSense);
445 printf("fifoUnder :%8ld\t", ec->eth_stat.ets_fifoUnder);
446 printf("fifoOver :%8ld\t", ec->eth_stat.ets_fifoOver);
447 printf("CDheartbeat:%8ld\n", ec->eth_stat.ets_CDheartbeat);
449 printf("OWC :%8ld\t", ec->eth_stat.ets_OWC);
451 ioaddr = ec->ec_port;
452 isr = read_csr(ioaddr, LANCE_CSR0);
453 printf("isr = 0x%x, flags = 0x%x\n", isr,
454 ec->flags);
456 printf("irq = %d\tioadr = 0x%x\n", ec->ec_irq, ec->ec_port);
458 csr = read_csr(ioaddr, LANCE_CSR0);
459 printf("CSR0: 0x%x\n", csr);
460 csr = read_csr(ioaddr, LANCE_CSR3);
461 printf("CSR3: 0x%x\n", csr);
462 csr = read_csr(ioaddr, LANCE_CSR4);
463 printf("CSR4: 0x%x\n", csr);
464 csr = read_csr(ioaddr, LANCE_CSR5);
465 printf("CSR5: 0x%x\n", csr);
466 csr = read_csr(ioaddr, LANCE_CSR15);
467 printf("CSR15: 0x%x\n", csr);
470 /*===========================================================================*
471 * do_init *
472 *===========================================================================*/
473 static void do_init(mp)
474 message *mp;
476 ether_card_t *ec;
477 message reply_mess;
479 pci_init();
481 if(!lance_buf && !(lance_buf = alloc_contig(LANCE_BUF_SIZE, AC_ALIGN4K|AC_LOWER16M, &lance_buf_phys))) {
482 panic("alloc_contig failed: %d", LANCE_BUF_SIZE);
485 ec= &ec_state;
486 strcpy(ec->port_name, "lance#0");
487 ec->port_name[6] += ec_instance;
489 if (ec->mode == EC_DISABLED)
491 /* This is the default, try to (re)locate the device. */
492 /* only try to enable if memory is correct for DMA */
493 if ( CORRECT_DMA_MEM() )
495 conf_hw(ec);
497 else
499 printf("LANCE: DMA denied because address out of range\n" );
502 if (ec->mode == EC_DISABLED)
504 /* Probe failed, or the device is configured off. */
505 reply_mess.m_type= DL_CONF_REPLY;
506 reply_mess.DL_STAT = ENXIO;
507 mess_reply(mp, &reply_mess);
508 return;
510 if (ec->mode == EC_ENABLED)
511 ec_init(ec);
514 if (ec->mode == EC_SINK)
516 ec->mac_address.ea_addr[0] =
517 ec->mac_address.ea_addr[1] =
518 ec->mac_address.ea_addr[2] =
519 ec->mac_address.ea_addr[3] =
520 ec->mac_address.ea_addr[4] =
521 ec->mac_address.ea_addr[5] = 0;
522 ec_confaddr(ec);
523 reply_mess.m_type = DL_CONF_REPLY;
524 reply_mess.DL_STAT = OK;
525 *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address;
526 mess_reply(mp, &reply_mess);
527 return;
529 assert(ec->mode == EC_ENABLED);
530 assert(ec->flags & ECF_ENABLED);
532 ec->flags &= ~(ECF_PROMISC | ECF_MULTI | ECF_BROAD);
534 if (mp->DL_MODE & DL_PROMISC_REQ)
535 ec->flags |= ECF_PROMISC | ECF_MULTI | ECF_BROAD;
536 if (mp->DL_MODE & DL_MULTI_REQ)
537 ec->flags |= ECF_MULTI;
538 if (mp->DL_MODE & DL_BROAD_REQ)
539 ec->flags |= ECF_BROAD;
541 ec_reinit(ec);
543 reply_mess.m_type = DL_CONF_REPLY;
544 reply_mess.DL_STAT = OK;
545 *(ether_addr_t *) reply_mess.DL_HWADDR = ec->mac_address;
547 mess_reply(mp, &reply_mess);
551 /*===========================================================================*
552 * do_int *
553 *===========================================================================*/
554 static void do_int(ec)
555 ether_card_t *ec;
557 if (ec->flags & (ECF_PACK_SEND | ECF_PACK_RECV))
558 reply(ec);
562 /*===========================================================================*
563 * conf_hw *
564 *===========================================================================*/
565 static void conf_hw(ec)
566 ether_card_t *ec;
568 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
570 int confnr;
571 ec_conf_t *ecp;
573 ec->mode= EC_DISABLED; /* Superfluous */
575 /* Pick a default configuration. This hardly matters anymore. */
576 confnr= MIN(ec_instance, EC_CONF_NR-1);
578 ecp= &ec_conf[confnr];
579 update_conf(ec, ecp);
580 if (ec->mode != EC_ENABLED)
581 return;
583 if (!lance_probe(ec, ec_instance))
585 printf("%s: No ethernet card found on PCI-BIOS info.\n",
586 ec->port_name);
587 ec->mode= EC_DISABLED;
588 return;
591 /* XXX */ if (ec->ec_linmem == 0) ec->ec_linmem= 0xFFFF0000;
593 ec->flags = ECF_EMPTY;
594 ec->eth_stat = empty_stat;
598 /*===========================================================================*
599 * update_conf *
600 *===========================================================================*/
601 static void update_conf(ec, ecp)
602 ether_card_t *ec;
603 ec_conf_t *ecp;
605 long v;
606 char eckey[16];
607 static char ec_fmt[] = "x:d:x:x";
609 /* Get the default settings and modify them from the environment. */
610 strcpy(eckey, "LANCE0");
611 eckey[5] += ec_instance;
612 ec->mode= EC_SINK;
613 v= ecp->ec_port;
614 switch (env_parse(eckey, ec_fmt, 0, &v, 0x0000L, 0xFFFFL))
616 case EP_OFF:
617 ec->mode= EC_DISABLED;
618 break;
619 case EP_ON:
620 case EP_SET:
621 default:
622 ec->mode= EC_ENABLED; /* Might become disabled if
623 * all probes fail */
624 break;
627 ec->ec_port= v;
629 v= ecp->ec_irq | DEI_DEFAULT;
630 (void) env_parse(eckey, ec_fmt, 1, &v, 0L, (long) NR_IRQ_VECTORS - 1);
631 ec->ec_irq= v;
633 v= ecp->ec_mem;
634 (void) env_parse(eckey, ec_fmt, 2, &v, 0L, 0xFFFFFL);
635 ec->ec_linmem= v;
637 v= 0;
638 (void) env_parse(eckey, ec_fmt, 3, &v, 0x2000L, 0x8000L);
639 ec->ec_ramsize= v;
643 /*===========================================================================*
644 * ec_init *
645 *===========================================================================*/
646 static void ec_init(ec)
647 ether_card_t *ec;
649 int i, r;
651 /* General initialization */
652 ec->flags = ECF_EMPTY;
653 lance_init_card(ec); /* Get mac_address, etc ...*/
655 ec_confaddr(ec);
657 #if VERBOSE
658 printf("%s: Ethernet address ", ec->port_name);
659 for (i= 0; i < 6; i++)
660 printf("%x%c", ec->mac_address.ea_addr[i],
661 i < 5 ? ':' : '\n');
662 #endif
664 /* Finish the initialization */
665 ec->flags |= ECF_ENABLED;
667 /* Set the interrupt handler */
668 ec->ec_hook = ec->ec_irq;
669 if ((r=sys_irqsetpolicy(ec->ec_irq, 0, &ec->ec_hook)) != OK)
670 printf("lance: error, couldn't set IRQ policy: %d\n", r);
672 return;
676 /*===========================================================================*
677 * reply *
678 *===========================================================================*/
679 static void reply(ec)
680 ether_card_t *ec;
682 message reply;
683 int flags,r;
685 flags = DL_NOFLAGS;
686 if (ec->flags & ECF_PACK_SEND)
687 flags |= DL_PACK_SEND;
688 if (ec->flags & ECF_PACK_RECV)
689 flags |= DL_PACK_RECV;
691 reply.m_type = DL_TASK_REPLY;
692 reply.DL_FLAGS = flags;
693 reply.DL_COUNT = ec->read_s;
695 r = send(ec->client, &reply);
696 if (r < 0)
697 panic("send failed: %d", r);
699 ec->read_s = 0;
700 ec->flags &= ~(ECF_PACK_SEND | ECF_PACK_RECV);
704 /*===========================================================================*
705 * mess_reply *
706 *===========================================================================*/
707 static void mess_reply(req, reply_mess)
708 message *req;
709 message *reply_mess;
711 if (send(req->m_source, reply_mess) != OK)
712 panic("unable to mess_reply");
716 /*===========================================================================*
717 * ec_confaddr *
718 *===========================================================================*/
719 static void ec_confaddr(ec)
720 ether_card_t *ec;
722 int i;
723 char eakey[16];
724 static char eafmt[]= "x:x:x:x:x:x";
725 long v;
727 /* User defined ethernet address? */
728 strcpy(eakey, "LANCE0_EA");
729 eakey[5] += ec_instance;
731 for (i = 0; i < 6; i++)
733 v= ec->mac_address.ea_addr[i];
734 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
735 break;
736 ec->mac_address.ea_addr[i]= v;
739 if (i != 0 && i != 6)
741 /* It's all or nothing; force a panic. */
742 (void) env_parse(eakey, "?", 0, &v, 0L, 0L);
747 /*===========================================================================*
748 * ec_reinit *
749 *===========================================================================*/
750 static void ec_reinit(ec)
751 ether_card_t *ec;
753 int i;
754 unsigned short ioaddr = ec->ec_port;
756 /* stop */
757 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
759 /* purge Tx-ring */
760 tx_slot_nr = cur_tx_slot_nr = 0;
761 for (i=0; i<TX_RING_SIZE; i++)
763 lp->tx_ring[i].u.base = 0;
764 isstored[i]=0;
767 /* re-init Rx-ring */
768 rx_slot_nr = 0;
769 for (i=0; i<RX_RING_SIZE; i++)
771 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
772 lp->rx_ring[i].u.addr[3] |= 0x80;
775 /* Set 'Receive Mode' */
776 if (ec->flags & ECF_PROMISC)
778 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
780 else
782 if (ec->flags & (ECF_BROAD | ECF_MULTI))
784 write_csr(ioaddr, LANCE_CSR15, 0x0000);
786 else
788 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
792 /* start && enable interrupt */
793 write_csr(ioaddr, LANCE_CSR0,
794 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
796 return;
799 /*===========================================================================*
800 * ec_check_ints *
801 *===========================================================================*/
802 static void ec_check_ints(ec)
803 ether_card_t *ec;
805 int must_restart = 0;
806 int check,status;
807 int isr = 0x0000;
808 unsigned short ioaddr = ec->ec_port;
810 if (!(ec->flags & ECF_ENABLED))
811 panic("got premature interrupt");
813 for (;;)
815 #if VERBOSE
816 printf("ETH: Reading ISR...");
817 #endif
818 isr = read_csr(ioaddr, LANCE_CSR0);
819 if (isr & (LANCE_CSR0_ERR|LANCE_CSR0_RINT|LANCE_CSR0_TINT)) {
820 write_csr(ioaddr, LANCE_CSR0,
821 isr & ~(LANCE_CSR0_IENA|LANCE_CSR0_TDMD|LANCE_CSR0_STOP
822 |LANCE_CSR0_STRT|LANCE_CSR0_INIT) );
824 write_csr(ioaddr, LANCE_CSR0,
825 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS|LANCE_CSR0_MERR
826 |LANCE_CSR0_IDON|LANCE_CSR0_IENA);
828 #define ISR_RST 0x0000
830 if ((isr & (LANCE_CSR0_TINT|LANCE_CSR0_RINT|LANCE_CSR0_MISS
831 |LANCE_CSR0_BABL|LANCE_CSR0_ERR)) == 0x0000)
833 #if VERBOSE
834 printf("OK\n");
835 #endif
836 break;
839 if (isr & LANCE_CSR0_MISS)
841 #if VERBOSE
842 printf("RX Missed Frame\n");
843 #endif
844 ec->eth_stat.ets_recvErr++;
846 if ((isr & LANCE_CSR0_BABL) || (isr & LANCE_CSR0_TINT))
848 if (isr & LANCE_CSR0_BABL)
850 #if VERBOSE
851 printf("TX Timeout\n");
852 #endif
853 ec->eth_stat.ets_sendErr++;
855 if (isr & LANCE_CSR0_TINT)
857 #if VERBOSE
858 printf("TX INT\n");
859 #endif
860 /* status check: restart if needed. */
861 status = lp->tx_ring[cur_tx_slot_nr].u.base;
863 /* ??? */
864 if (status & 0x40000000)
866 status = lp->tx_ring[cur_tx_slot_nr].misc;
867 ec->eth_stat.ets_sendErr++;
868 if (status & 0x0400)
869 ec->eth_stat.ets_transAb++;
870 if (status & 0x0800)
871 ec->eth_stat.ets_carrSense++;
872 if (status & 0x1000)
873 ec->eth_stat.ets_OWC++;
874 if (status & 0x4000)
876 ec->eth_stat.ets_fifoUnder++;
877 must_restart=1;
880 else
882 if (status & 0x18000000)
883 ec->eth_stat.ets_collision++;
884 ec->eth_stat.ets_packetT++;
887 /* transmit a packet on the next slot if it exists. */
888 check = 0;
889 if (isstored[cur_tx_slot_nr]==1)
891 /* free the tx-slot just transmitted */
892 isstored[cur_tx_slot_nr]=0;
893 cur_tx_slot_nr = (++cur_tx_slot_nr) & TX_RING_MOD_MASK;
895 /* next tx-slot is ready? */
896 if (isstored[cur_tx_slot_nr]==1)
897 check=1;
898 else
899 check=0;
901 else
903 panic("got premature TX INT..");
905 if (check==1)
907 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
908 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
910 else
911 if (check==-1)
912 continue;
913 /* we set a buffered message in the slot if it exists. */
914 /* and transmit it, if needed. */
915 if (ec->flags & ECF_SEND_AVAIL)
916 ec_send(ec);
918 if (isr & LANCE_CSR0_RINT)
920 #if VERBOSE
921 printf("RX INT\n");
922 #endif
923 ec_recv(ec);
926 if (isr & ISR_RST)
928 ec->flags = ECF_STOPPED;
929 #if VERBOSE
930 printf("ISR_RST\n");
931 #endif
932 break;
935 /* ??? cf. lance driver on linux */
936 if (must_restart == 1)
938 #if VERBOSE
939 printf("ETH: restarting...\n");
940 #endif
941 /* stop */
942 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
943 /* start */
944 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
948 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
950 #if VERBOSE
951 printf("ETH: resetting...\n");
952 #endif
953 ec_reset(ec);
957 /*===========================================================================*
958 * ec_reset *
959 *===========================================================================*/
960 static void ec_reset(ec)
961 ether_card_t *ec;
963 /* Stop/start the chip, and clear all RX,TX-slots */
964 unsigned short ioaddr = ec->ec_port;
965 int i;
967 /* stop */
968 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
969 /* start */
970 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STRT);
972 /* purge Tx-ring */
973 tx_slot_nr = cur_tx_slot_nr = 0;
974 for (i=0; i<TX_RING_SIZE; i++)
976 lp->tx_ring[i].u.base = 0;
977 isstored[i]=0;
980 /* re-init Rx-ring */
981 rx_slot_nr = 0;
982 for (i=0; i<RX_RING_SIZE; i++)
984 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
985 lp->rx_ring[i].u.addr[3] |= 0x80;
988 /* store a buffered message on the slot if exists */
989 ec_send(ec);
990 ec->flags &= ~ECF_STOPPED;
993 /*===========================================================================*
994 * ec_send *
995 *===========================================================================*/
996 static void ec_send(ec)
997 ether_card_t *ec;
999 /* from ec_check_ints() or ec_reset(). */
1000 /* this function proccesses the buffered message. (slot/transmit) */
1001 if (!(ec->flags & ECF_SEND_AVAIL))
1002 return;
1004 ec->flags &= ~ECF_SEND_AVAIL;
1005 switch(ec->sendmsg.m_type)
1007 case DL_WRITEV_S: do_vwrite_s(&ec->sendmsg, TRUE); break;
1008 default:
1009 panic("wrong type: %d", ec->sendmsg.m_type);
1010 break;
1014 /*===========================================================================*
1015 * do_vread_s *
1016 *===========================================================================*/
1017 static void do_vread_s(const message *mp)
1019 int count, r;
1020 ether_card_t *ec;
1022 ec= &ec_state;
1024 ec->client= mp->m_source;
1025 count = mp->DL_COUNT;
1027 r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0,
1028 (vir_bytes)ec->read_iovec.iod_iovec,
1029 (count > IOVEC_NR ? IOVEC_NR : count) *
1030 sizeof(iovec_s_t), D);
1031 if (r != OK)
1032 panic("do_vread_s: sys_safecopyfrom failed: %d", r);
1033 ec->read_iovec.iod_iovec_s = count;
1034 ec->read_iovec.iod_proc_nr = mp->DL_ENDPT;
1035 ec->read_iovec.iod_grant = (cp_grant_id_t) mp->DL_GRANT;
1036 ec->read_iovec.iod_iovec_offset = 0;
1038 ec->tmp_iovec = ec->read_iovec;
1040 ec->flags |= ECF_READING;
1042 ec_recv(ec);
1044 if ((ec->flags & (ECF_READING|ECF_STOPPED)) == (ECF_READING|ECF_STOPPED))
1045 ec_reset(ec);
1046 reply(ec);
1049 /*===========================================================================*
1050 * ec_recv *
1051 *===========================================================================*/
1052 static void ec_recv(ec)
1053 ether_card_t *ec;
1055 vir_bytes length;
1056 int packet_processed;
1057 int status;
1058 unsigned short ioaddr = ec->ec_port;
1060 if ((ec->flags & ECF_READING)==0)
1061 return;
1062 if (!(ec->flags & ECF_ENABLED))
1063 return;
1065 /* we check all the received slots until find a properly received packet */
1066 packet_processed = FALSE;
1067 while (!packet_processed)
1069 status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1070 if ( (status & 0x80) == 0x00 )
1072 status = lp->rx_ring[rx_slot_nr].u.base >> 24;
1074 /* ??? */
1075 if (status != 0x03)
1077 if (status & 0x01)
1078 ec->eth_stat.ets_recvErr++;
1079 if (status & 0x04)
1080 ec->eth_stat.ets_fifoOver++;
1081 if (status & 0x08)
1082 ec->eth_stat.ets_CRCerr++;
1083 if (status & 0x10)
1084 ec->eth_stat.ets_OVW++;
1085 if (status & 0x20)
1086 ec->eth_stat.ets_frameAll++;
1087 length = 0;
1089 else
1091 ec->eth_stat.ets_packetR++;
1092 length = lp->rx_ring[rx_slot_nr].msg_length;
1094 if (length > 0)
1096 ec_nic2user(ec, (int)(lp->rbuf[rx_slot_nr]),
1097 &ec->read_iovec, 0, length);
1099 ec->read_s = length;
1100 ec->flags |= ECF_PACK_RECV;
1101 ec->flags &= ~ECF_READING;
1102 packet_processed = TRUE;
1104 /* set up this slot again, and we move to the next slot */
1105 lp->rx_ring[rx_slot_nr].buf_length = -ETH_FRAME_LEN;
1106 lp->rx_ring[rx_slot_nr].u.addr[3] |= 0x80;
1108 write_csr(ioaddr, LANCE_CSR0,
1109 LANCE_CSR0_BABL|LANCE_CSR0_CERR|LANCE_CSR0_MISS
1110 |LANCE_CSR0_MERR|LANCE_CSR0_IDON|LANCE_CSR0_IENA);
1112 rx_slot_nr = (++rx_slot_nr) & RX_RING_MOD_MASK;
1114 else
1115 break;
1119 /*===========================================================================*
1120 * do_vwrite_s *
1121 *===========================================================================*/
1122 static void do_vwrite_s(mp, from_int)
1123 message *mp;
1124 int from_int;
1126 int count, check, r;
1127 ether_card_t *ec;
1128 unsigned short ioaddr;
1130 ec = &ec_state;
1132 ec->client= mp->m_source;
1133 count = mp->DL_COUNT;
1135 if (isstored[tx_slot_nr]==1)
1137 /* all slots are used, so this message is buffered */
1138 ec->sendmsg= *mp;
1139 ec->flags |= ECF_SEND_AVAIL;
1140 reply(ec);
1141 return;
1144 /* convert the message to write_iovec */
1145 r = sys_safecopyfrom(mp->DL_ENDPT, mp->DL_GRANT, 0,
1146 (vir_bytes)ec->write_iovec.iod_iovec,
1147 (count > IOVEC_NR ? IOVEC_NR : count) *
1148 sizeof(iovec_s_t), D);
1149 if (r != OK)
1150 panic("do_vwrite_s: sys_safecopyfrom failed: %d", r);
1151 ec->write_iovec.iod_iovec_s = count;
1152 ec->write_iovec.iod_proc_nr = mp->DL_ENDPT;
1153 ec->write_iovec.iod_grant = mp->DL_GRANT;
1154 ec->write_iovec.iod_iovec_offset = 0;
1156 ec->tmp_iovec = ec->write_iovec;
1157 ec->write_s = calc_iovec_size(&ec->tmp_iovec);
1159 /* copy write_iovec to the slot on DMA address */
1160 ec_user2nic(ec, &ec->write_iovec, 0,
1161 (int)(lp->tbuf[tx_slot_nr]), ec->write_s);
1162 /* set-up for transmitting, and transmit it if needed. */
1163 lp->tx_ring[tx_slot_nr].buf_length = -ec->write_s;
1164 lp->tx_ring[tx_slot_nr].misc = 0x0;
1165 lp->tx_ring[tx_slot_nr].u.base
1166 = virt_to_bus(lp->tbuf[tx_slot_nr]) & 0xffffff;
1167 isstored[tx_slot_nr]=1;
1168 if (cur_tx_slot_nr == tx_slot_nr)
1169 check=1;
1170 else
1171 check=0;
1172 tx_slot_nr = (++tx_slot_nr) & TX_RING_MOD_MASK;
1174 if (check == 1)
1176 ioaddr = ec->ec_port;
1177 lp->tx_ring[cur_tx_slot_nr].u.addr[3] = 0x83;
1178 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_IENA|LANCE_CSR0_TDMD);
1181 ec->flags |= ECF_PACK_SEND;
1183 /* reply by calling do_int() if this function is called from interrupt. */
1184 if (from_int)
1185 return;
1186 reply(ec);
1190 /*===========================================================================*
1191 * ec_user2nic *
1192 *===========================================================================*/
1193 static void ec_user2nic(ec, iovp, offset, nic_addr, count)
1194 ether_card_t *ec;
1195 iovec_dat_t *iovp;
1196 vir_bytes offset;
1197 int nic_addr;
1198 vir_bytes count;
1200 int bytes, i, r;
1202 i= 0;
1203 while (count > 0)
1205 if (i >= IOVEC_NR)
1207 ec_next_iovec(iovp);
1208 i= 0;
1209 continue;
1211 if (offset >= iovp->iod_iovec[i].iov_size)
1213 offset -= iovp->iod_iovec[i].iov_size;
1214 i++;
1215 continue;
1217 bytes = iovp->iod_iovec[i].iov_size - offset;
1218 if (bytes > count)
1219 bytes = count;
1221 if ( (r=sys_safecopyfrom(iovp->iod_proc_nr,
1222 iovp->iod_iovec[i].iov_grant, offset,
1223 nic_addr, bytes, D )) != OK )
1224 panic("ec_user2nic: sys_safecopyfrom failed: %d", r);
1226 count -= bytes;
1227 nic_addr += bytes;
1228 offset += bytes;
1232 /*===========================================================================*
1233 * ec_nic2user *
1234 *===========================================================================*/
1235 static void ec_nic2user(ec, nic_addr, iovp, offset, count)
1236 ether_card_t *ec;
1237 int nic_addr;
1238 iovec_dat_t *iovp;
1239 vir_bytes offset;
1240 vir_bytes count;
1242 int bytes, i, r;
1244 i= 0;
1245 while (count > 0)
1247 if (i >= IOVEC_NR)
1249 ec_next_iovec(iovp);
1250 i= 0;
1251 continue;
1253 if (offset >= iovp->iod_iovec[i].iov_size)
1255 offset -= iovp->iod_iovec[i].iov_size;
1256 i++;
1257 continue;
1259 bytes = iovp->iod_iovec[i].iov_size - offset;
1260 if (bytes > count)
1261 bytes = count;
1262 if ( (r=sys_safecopyto( iovp->iod_proc_nr, iovp->iod_iovec[i].iov_grant,
1263 offset, nic_addr, bytes, D )) != OK )
1264 panic("ec_nic2user: sys_safecopyto failed: %d", r);
1266 count -= bytes;
1267 nic_addr += bytes;
1268 offset += bytes;
1273 /*===========================================================================*
1274 * calc_iovec_size *
1275 *===========================================================================*/
1276 static int calc_iovec_size(iovec_dat_t *iovp)
1278 int size,i;
1280 size = i = 0;
1282 while (i < iovp->iod_iovec_s)
1284 if (i >= IOVEC_NR)
1286 ec_next_iovec(iovp);
1287 i= 0;
1288 continue;
1290 size += iovp->iod_iovec[i].iov_size;
1291 i++;
1294 return size;
1297 /*===========================================================================*
1298 * ec_next_iovec *
1299 *===========================================================================*/
1300 static void ec_next_iovec(iovp)
1301 iovec_dat_t *iovp;
1303 int r;
1305 iovp->iod_iovec_s -= IOVEC_NR;
1306 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_s_t);
1308 r = sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_grant,
1309 iovp->iod_iovec_offset,
1310 (vir_bytes)iovp->iod_iovec,
1311 (iovp->iod_iovec_s > IOVEC_NR ?
1312 IOVEC_NR : iovp->iod_iovec_s) *
1313 sizeof(iovec_s_t), D);
1314 if (r != OK)
1315 panic("ec_next_iovec: sys_safecopyfrom failed: %d", r);
1319 /*===========================================================================*
1320 * do_getstat_s *
1321 *===========================================================================*/
1322 static void do_getstat_s(mp)
1323 message *mp;
1325 int r;
1326 ether_card_t *ec;
1328 ec= &ec_state;
1330 r = sys_safecopyto(mp->DL_ENDPT, mp->DL_GRANT, 0,
1331 (vir_bytes)&ec->eth_stat, sizeof(ec->eth_stat), D);
1333 if (r != OK)
1334 panic("do_getstat_s: sys_safecopyto failed: %d", r);
1336 mp->m_type= DL_STAT_REPLY;
1337 r= send(mp->m_source, mp);
1338 if (r != OK)
1339 panic("do_getstat_s: send failed: %d", r);
1342 /*===========================================================================*
1343 * lance_stop *
1344 *===========================================================================*/
1345 static void lance_stop(ec)
1346 ether_card_t *ec;
1348 unsigned short ioaddr;
1350 if (!(ec->flags & ECF_ENABLED))
1351 return;
1353 ioaddr = ec->ec_port;
1355 /* stop */
1356 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1358 /* Reset */
1359 in_word(ioaddr+LANCE_RESET);
1361 ec->flags = ECF_EMPTY;
1364 /*===========================================================================*
1365 * getAddressing *
1366 *===========================================================================*/
1367 static void getAddressing(devind, ec)
1368 int devind;
1369 ether_card_t *ec;
1371 unsigned int membase, ioaddr;
1372 int reg, irq;
1374 for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4)
1376 ioaddr = pci_attr_r32(devind, reg);
1378 if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0
1379 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
1380 continue;
1381 /* Strip the I/O address out of the returned value */
1382 ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
1383 /* Get the memory base address */
1384 membase = pci_attr_r32(devind, PCI_BASE_ADDRESS_1);
1385 /* KK: Get the IRQ number */
1386 irq = pci_attr_r8(devind, PCI_INTERRUPT_PIN);
1387 if (irq)
1388 irq = pci_attr_r8(devind, PCI_INTERRUPT_LINE);
1390 ec->ec_linmem = membase;
1391 ec->ec_port = ioaddr;
1392 ec->ec_irq = irq;
1396 /*===========================================================================*
1397 * lance_probe *
1398 *===========================================================================*/
1399 static int lance_probe(ec, skip)
1400 ether_card_t *ec;
1401 int skip;
1403 unsigned short pci_cmd;
1404 unsigned short ioaddr;
1405 int lance_version, chip_version;
1406 int devind, just_one, i, r;
1408 u16_t vid, did;
1410 if ((ec->ec_pcibus | ec->ec_pcidev | ec->ec_pcifunc) != 0)
1412 /* Look for specific PCI device */
1413 r= pci_find_dev(ec->ec_pcibus, ec->ec_pcidev,
1414 ec->ec_pcifunc, &devind);
1415 if (r == 0)
1417 printf("%s: no PCI found at %d.%d.%d\n",
1418 ec->port_name, ec->ec_pcibus,
1419 ec->ec_pcidev, ec->ec_pcifunc);
1420 return 0;
1422 pci_ids(devind, &vid, &did);
1423 just_one= TRUE;
1425 else
1427 r= pci_first_dev(&devind, &vid, &did);
1428 if (r == 0)
1429 return 0;
1430 just_one= FALSE;
1433 for(;;)
1435 for (i= 0; pcitab[i].vid != 0; i++)
1437 if (pcitab[i].vid != vid)
1438 continue;
1439 if (pcitab[i].did != did)
1440 continue;
1441 if (pcitab[i].checkclass) {
1442 panic("class check not implemented");
1444 break;
1446 if (pcitab[i].vid != 0)
1448 if (just_one || !skip)
1449 break;
1450 skip--;
1453 if (just_one)
1455 printf(
1456 "%s: wrong PCI device (%04x/%04x) found at %d.%d.%d\n",
1457 ec->port_name, vid, did,
1458 ec->ec_pcibus,
1459 ec->ec_pcidev, ec->ec_pcifunc);
1460 return 0;
1463 r= pci_next_dev(&devind, &vid, &did);
1464 if (!r)
1465 return 0;
1468 pci_reserve(devind);
1470 getAddressing(devind, ec);
1473 /* ===== Bus Master ? ===== */
1474 pci_cmd = pci_attr_r32(devind, PCI_CR);
1475 if (!(pci_cmd & PCI_COMMAND_MASTER)) {
1476 pci_cmd |= PCI_COMMAND_MASTER;
1477 pci_attr_w32(devind, PCI_CR, pci_cmd);
1480 /* ===== Probe Details ===== */
1481 ioaddr = ec->ec_port;
1483 /* Reset */
1484 in_word(ioaddr+LANCE_RESET);
1486 if (read_csr(ioaddr, LANCE_CSR0) != LANCE_CSR0_STOP)
1488 ec->mode=EC_DISABLED;
1491 /* Probe Chip Version */
1492 out_word(ioaddr+LANCE_ADDR, 88); /* Get the version of the chip */
1493 if (in_word(ioaddr+LANCE_ADDR) != 88)
1494 lance_version = 0;
1495 else
1497 chip_version = read_csr(ioaddr, LANCE_CSR88);
1498 chip_version |= read_csr(ioaddr, LANCE_CSR89) << 16;
1500 if ((chip_version & 0xfff) != 0x3)
1502 ec->mode=EC_DISABLED;
1504 chip_version = (chip_version >> 12) & 0xffff;
1505 for (lance_version = 1; chip_table[lance_version].id_number != 0;
1506 ++lance_version)
1507 if (chip_table[lance_version].id_number == chip_version)
1508 break;
1511 #if VERBOSE
1512 printf("%s: %s at %X:%d\n",
1513 ec->port_name, chip_table[lance_version].name,
1514 ec->ec_port, ec->ec_irq);
1515 #endif
1517 return lance_version;
1520 /*===========================================================================*
1521 * lance_init_card *
1522 *===========================================================================*/
1523 static void lance_init_card(ec)
1524 ether_card_t *ec;
1526 int i;
1527 Address l = (vir_bytes)lance_buf;
1528 unsigned short ioaddr = ec->ec_port;
1530 /* ============= setup init_block(cf. lance_probe1) ================ */
1531 /* make sure data structure is 8-byte aligned and below 16MB (for DMA) */
1533 lp = (struct lance_interface *)l;
1535 /* disable Tx and Rx */
1536 lp->init_block.mode = LANCE_CSR15_DTX|LANCE_CSR15_DRX;
1537 lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
1538 /* using multiple Rx/Tx buffer */
1539 lp->init_block.rx_ring
1540 = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
1541 lp->init_block.tx_ring
1542 = (virt_to_bus(&lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
1544 l = virt_to_bus(&lp->init_block);
1545 write_csr(ioaddr, LANCE_CSR1, (unsigned short)l);
1546 write_csr(ioaddr, LANCE_CSR2, (unsigned short)(l >> 16));
1547 write_csr(ioaddr, LANCE_CSR4,
1548 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1549 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1551 /* ============= Get MAC address (cf. lance_probe1) ================ */
1552 for (i = 0; i < 6; ++i)
1553 ec->mac_address.ea_addr[i]=in_byte(ioaddr+LANCE_ETH_ADDR+i);
1555 /* ============ (re)start init_block(cf. lance_reset) =============== */
1556 /* Reset the LANCE */
1557 (void)in_word(ioaddr+LANCE_RESET);
1559 /* ----- Re-initialize the LANCE ----- */
1560 /* Set station address */
1561 for (i = 0; i < 6; ++i)
1562 lp->init_block.phys_addr[i] = ec->mac_address.ea_addr[i];
1563 /* Preset the receive ring headers */
1564 for (i=0; i<RX_RING_SIZE; i++)
1566 lp->rx_ring[i].buf_length = -ETH_FRAME_LEN;
1567 /* OWN */
1568 lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
1569 /* we set the top byte as the very last thing */
1570 lp->rx_ring[i].u.addr[3] = 0x80;
1572 /* Preset the transmitting ring headers */
1573 for (i=0; i<TX_RING_SIZE; i++)
1575 lp->tx_ring[i].u.base = 0;
1576 isstored[i] = 0;
1578 /* enable Rx and Tx */
1579 lp->init_block.mode = 0x0;
1581 l = (Address)virt_to_bus(&lp->init_block);
1582 write_csr(ioaddr, LANCE_CSR1, (short)l);
1583 write_csr(ioaddr, LANCE_CSR2, (short)(l >> 16));
1584 write_csr(ioaddr, LANCE_CSR4,
1585 LANCE_CSR4_APAD_XMT|LANCE_CSR4_MFCOM|LANCE_CSR4_RCVCCOM
1586 |LANCE_CSR4_TXSTRTM|LANCE_CSR4_JABM);
1588 /* ----- start when init done. ----- */
1589 /* stop */
1590 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_STOP);
1591 /* init */
1592 write_csr(ioaddr, LANCE_CSR0, LANCE_CSR0_INIT);
1593 /* poll for IDON */
1594 for (i = 10000; i > 0; --i)
1595 if (read_csr(ioaddr, LANCE_CSR0) & LANCE_CSR0_IDON)
1596 break;
1598 /* Set 'Multicast Table' */
1599 for (i=0;i<4;++i)
1601 write_csr(ioaddr, LANCE_CSR8 + i, 0xffff);
1604 /* Set 'Receive Mode' */
1605 if (ec->flags & ECF_PROMISC)
1607 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_PROM);
1609 else
1611 if (ec->flags & (ECF_BROAD | ECF_MULTI))
1613 write_csr(ioaddr, LANCE_CSR15, 0x0000);
1615 else
1617 write_csr(ioaddr, LANCE_CSR15, LANCE_CSR15_DRCVBC);
1621 /* start && enable interrupt */
1622 write_csr(ioaddr, LANCE_CSR0,
1623 LANCE_CSR0_IDON|LANCE_CSR0_IENA|LANCE_CSR0_STRT);
1625 return;
1628 /*===========================================================================*
1629 * in_byte *
1630 *===========================================================================*/
1631 static u8_t in_byte(port_t port)
1633 int r;
1634 u32_t value;
1636 r= sys_inb(port, &value);
1637 if (r != OK)
1638 panic("sys_inb failed: %d", r);
1639 return value;
1642 /*===========================================================================*
1643 * in_word *
1644 *===========================================================================*/
1645 static u16_t in_word(port_t port)
1647 int r;
1648 u32_t value;
1650 r= sys_inw(port, &value);
1651 if (r != OK)
1652 panic("sys_inw failed: %d", r);
1653 return value;
1657 /*===========================================================================*
1658 * out_word *
1659 *===========================================================================*/
1660 static void out_word(port_t port, u16_t value)
1662 int r;
1664 r= sys_outw(port, value);
1665 if (r != OK)
1666 panic("sys_outw failed: %d", r);
1669 /*===========================================================================*
1670 * read_csr *
1671 *===========================================================================*/
1672 static u16_t read_csr(port_t ioaddr, u16_t csrno)
1674 out_word(ioaddr+LANCE_ADDR, csrno);
1675 return in_word(ioaddr+LANCE_DATA);
1678 /*===========================================================================*
1679 * write_csr *
1680 *===========================================================================*/
1681 static void write_csr(port_t ioaddr, u16_t csrno, u16_t value)
1683 out_word(ioaddr+LANCE_ADDR, csrno);
1684 out_word(ioaddr+LANCE_DATA, value);