4 * This file contains a ethernet device driver for AMD LANCE based ethernet
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_WRITE | port nr | proc nr | count | mode | address | |
14 * |------------|----------|---------|----------|---------|---------|---------|
15 * | DL_WRITEV | port nr | proc nr | count | mode | address | |
16 * |------------|----------|---------|----------|---------|---------|---------|
17 * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
18 * |------------|----------|---------|----------|---------|---------|---------|
19 * | DL_READ | port nr | proc nr | count | | address | |
20 * |------------|----------|---------|----------|---------|---------|---------|
21 * | DL_READV | port nr | proc nr | count | | address | |
22 * |------------|----------|---------|----------|---------|---------|---------|
23 * | DL_READV_S | port nr | proc nr | count | | | grant |
24 * |------------|----------|---------|----------|---------|---------|---------|
25 * | DL_CONF | port nr | proc nr | | mode | address | |
26 * |------------|----------|---------|----------|---------|---------|---------|
27 * | DL_GETSTAT | port nr | proc nr | | | address | |
28 * |------------|----------|---------|----------|---------|---------|---------|
29 * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
30 * |------------|----------|---------|----------|---------|---------|---------|
31 * | DL_STOP | port_nr | | | | | |
32 * |------------|----------|---------|----------|---------|---------|---------|
34 * The messages sent are:
36 * m-type DL_POR T DL_PROC DL_COUNT DL_STAT DL_CLCK
37 * |------------|----------|---------|----------|---------|---------|
38 * |DL_TASK_REPL| port nr | proc nr | rd-count | err|stat| clock |
39 * |------------|----------|---------|----------|---------|---------|
41 * m_type m3_i1 m3_i2 m3_ca1
42 * |------------+---------+-----------+---------------|
43 * |DL_CONF_REPL| port nr | last port | ethernet addr |
44 * |------------|---------|-----------|---------------|
46 * Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
47 * Adapted for Minix 3: Sep 05, 2005 by Joren l'Ami <jwlami@cs.vu.nl>
52 #include "../drivers.h"
54 #include <minix/keymap.h>
56 #include <net/gen/ether.h>
57 #include <net/gen/eth_io.h>
60 #include <minix/syslib.h>
66 #include <sys/ioc_memory.h>
68 /* new I/O functions in Minix 3 */
69 #define out_byte( x, y ) sys_outb( x, y )
70 #define out_word( x, y ) sys_outw( x, y )
72 static U8_t
in_byte(U16_t port
)
76 if ((s
=sys_inb(port
, &value
)) != OK
)
77 printf( "lance: warning, sys_inb failed: %d\n", s
);
81 static U16_t
in_word( U16_t port
)
85 if ((s
=sys_inw(port
, &value
)) != OK
)
86 printf( "lance: warning, sys_inw failed: %d\n", s
);
90 #define in_byte( x ) inb( x )
91 #define in_word( x ) inw( x )
94 static ether_card_t ec_table
[EC_PORT_NR_MAX
];
95 static int eth_tasknr
= ANY
;
96 static u16_t eth_ign_proto
;
99 typedef struct ec_conf
107 /* We hardly use these. Just "LANCE0=on/off" "LANCE1=on/off" mean. */
108 ec_conf_t ec_conf
[]= /* Card addresses */
110 /* I/O port, IRQ, Buffer address, Env. var, Buf selector. */
111 { 0x1000, 9, 0x00000, "LANCE0" },
112 { 0xD000, 15, 0x00000, "LANCE1" },
115 /* Actually, we use PCI-BIOS info. */
116 PRIVATE
struct pcitab
123 { PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD_LANCE
, 0 }, /* AMD LANCE */
125 { 0x0000, 0x0000, 0 }
128 struct pci_device pci_dev_list[] = {
129 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
130 "AMD Lance/PCI", 0, 0, 0, 0, 0, 0},
131 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
132 "AMD Lance/PCI", 0, 0, 0, 0, 0, 0},
133 {0, 0, NULL, 0, 0, 0, 0, 0, 0}
138 _PROTOTYPE( static void do_init
, (message
*mp
) );
139 _PROTOTYPE( static void ec_init
, (ether_card_t
*ec
) );
140 _PROTOTYPE( static void ec_confaddr
, (ether_card_t
*ec
) );
141 _PROTOTYPE( static void ec_reinit
, (ether_card_t
*ec
) );
142 _PROTOTYPE( static void ec_check_ints
, (ether_card_t
*ec
) );
143 _PROTOTYPE( static void conf_hw
, (ether_card_t
*ec
) );
144 /*_PROTOTYPE( static int ec_handler, (irq_hook_t *hook) );*/
145 _PROTOTYPE( static void update_conf
, (ether_card_t
*ec
, ec_conf_t
*ecp
) );
146 _PROTOTYPE( static void mess_reply
, (message
*req
, message
*reply
) );
147 _PROTOTYPE( static void do_int
, (ether_card_t
*ec
) );
148 _PROTOTYPE( static void reply
,
149 (ether_card_t
*ec
, int err
, int may_block
) );
150 _PROTOTYPE( static void ec_reset
, (ether_card_t
*ec
) );
151 _PROTOTYPE( static void ec_send
, (ether_card_t
*ec
) );
152 _PROTOTYPE( static void ec_recv
, (ether_card_t
*ec
) );
153 _PROTOTYPE( static void do_vwrite_s
,
154 (message
*mp
, int from_int
) );
155 _PROTOTYPE( static void do_vread_s
, (message
*mp
) );
156 _PROTOTYPE( static void get_userdata_s
,
157 (int user_proc
, cp_grant_id_t grant
, vir_bytes offset
,
158 vir_bytes count
, void *loc_addr
) );
159 _PROTOTYPE( static void ec_user2nic
,
160 (ether_card_t
*dep
, iovec_dat_t
*iovp
,
161 vir_bytes offset
, int nic_addr
,
163 _PROTOTYPE( static void ec_nic2user
,
164 (ether_card_t
*ec
, int nic_addr
,
165 iovec_dat_t
*iovp
, vir_bytes offset
,
167 _PROTOTYPE( static int calc_iovec_size
, (iovec_dat_t
*iovp
) );
168 _PROTOTYPE( static void ec_next_iovec
, (iovec_dat_t
*iovp
) );
169 _PROTOTYPE( static void do_getstat_s
, (message
*mp
) );
170 _PROTOTYPE( static void put_userdata_s
,
171 (int user_proc
, cp_grant_id_t grant
,
172 void *loc_addr
, vir_bytes count
) );
173 _PROTOTYPE( static void do_stop
, (message
*mp
) );
174 _PROTOTYPE( static void do_getname
, (message
*mp
) );
176 _PROTOTYPE( static void lance_dump
, (void) );
177 _PROTOTYPE( static void lance_stop
, (void) );
178 _PROTOTYPE( static void getAddressing
, (int devind
, ether_card_t
*ec
) );
180 /* probe+init LANCE cards */
181 _PROTOTYPE( static int lance_probe
, (ether_card_t
*ec
) );
182 _PROTOTYPE( static void lance_init_card
, (ether_card_t
*ec
) );
186 #define Address unsigned long
190 #define virt_to_bus(x) (vir2phys((unsigned long)x))
191 unsigned long vir2phys( unsigned long x
)
196 if ( (r
=sys_umap( SELF
, D
, x
, 4, &value
)) != OK
)
197 panic( "lance", "sys_umap failed", r
);
202 /* DMA limitations */
203 #define DMA_ADDR_MASK 0xFFFFFF /* mask to verify DMA address is 24-bit */
205 #define CORRECT_DMA_MEM() ( (virt_to_bus(lance + sizeof(lance)) & ~DMA_ADDR_MASK) == 0 )
207 #define ETH_FRAME_LEN 1518
209 #define LANCE_MUST_PAD 0x00000001
210 #define LANCE_ENABLE_AUTOSELECT 0x00000002
211 #define LANCE_SELECT_PHONELINE 0x00000004
212 #define LANCE_MUST_UNRESET 0x00000008
214 static const struct lance_chip_type
220 {0x0000, "LANCE 7990", /* Ancient lance chip. */
221 LANCE_MUST_PAD
+ LANCE_MUST_UNRESET
},
222 {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
223 LANCE_ENABLE_AUTOSELECT
},
224 {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
225 LANCE_ENABLE_AUTOSELECT
},
226 {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
227 LANCE_ENABLE_AUTOSELECT
},
228 {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
229 LANCE_ENABLE_AUTOSELECT
},
230 {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
231 LANCE_ENABLE_AUTOSELECT
},
232 {0x2625, "PCnet-FAST III 79C973",/* 79C973 PCInet-FAST III. */
233 LANCE_ENABLE_AUTOSELECT
},
234 {0x2626, "PCnet/HomePNA 79C978",
235 LANCE_ENABLE_AUTOSELECT
|LANCE_SELECT_PHONELINE
},
236 {0x0, "PCnet (unknown)",
237 LANCE_ENABLE_AUTOSELECT
},
240 /* ############## for LANCE device ############## */
241 #define LANCE_ETH_ADDR 0x0
242 #define LANCE_DATA 0x10
243 #define LANCE_ADDR 0x12
244 #define LANCE_RESET 0x14
245 #define LANCE_BUS_IF 0x16
246 #define LANCE_TOTAL_SIZE 0x18
248 /* Use 2^4=16 {Rx,Tx} buffers */
249 #define LANCE_LOG_RX_BUFFERS 4
250 #define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
251 #define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
252 #define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
254 #define LANCE_LOG_TX_BUFFERS 4
255 #define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
256 #define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
257 #define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
259 /* for lance_interface */
260 struct lance_init_block
263 unsigned char phys_addr
[6];
264 unsigned long filter
[2];
273 unsigned char addr
[4];
275 short buf_length
; /* 2s complement */
283 unsigned char addr
[4];
285 short buf_length
; /* 2s complement */
289 struct lance_interface
291 struct lance_init_block init_block
;
292 struct lance_rx_head rx_ring
[RX_RING_SIZE
];
293 struct lance_tx_head tx_ring
[TX_RING_SIZE
];
294 unsigned char rbuf
[RX_RING_SIZE
][ETH_FRAME_LEN
];
295 unsigned char tbuf
[TX_RING_SIZE
][ETH_FRAME_LEN
];
298 /* =============== global variables =============== */
299 static struct lance_interface
*lp
;
300 static char lance
[sizeof(struct lance_interface
)+8];
301 static int rx_slot_nr
= 0; /* Rx-slot number */
302 static int tx_slot_nr
= 0; /* Tx-slot number */
303 static int cur_tx_slot_nr
= 0; /* Tx-slot number */
304 static char isstored
[TX_RING_SIZE
]; /* Tx-slot in-use */
305 static char *progname
;
308 /*===========================================================================*
310 *===========================================================================*/
311 void main( int argc
, char **argv
)
318 (progname
=strrchr(argv
[0],'/')) ? progname
++ : (progname
=argv
[0]);
320 env_setargs( argc
, argv
);
322 fkeys
= sfkeys
= 0; bit_set( sfkeys
, 7 );
325 if ( (r
= fkey_map(&fkeys
, &sfkeys
)) != OK
)
326 printf( "Error registering key\n" );
329 if((eth_tasknr
=getprocnr()) < 0)
330 panic("lance","couldn't get own proc nr", i
);
333 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v
, 0x0000L
, 0xFFFFL
);
334 eth_ign_proto
= htons((u16_t
) v
);
336 /* Try to notify inet that we are present (again) */
337 r
= _pm_findproc("inet", &tasknr
);
343 for (i
=0;i
<EC_PORT_NR_MAX
;++i
)
347 sys_irqenable(&ec
->ec_hook
);
350 if ((r
= receive(ANY
, &m
)) != OK
)
351 panic( "lance", "receive failed", r
);
353 for (i
=0;i
<EC_PORT_NR_MAX
;++i
)
357 sys_irqdisable(&ec
->ec_hook
);
363 case DEV_PING
: notify(m
.m_source
); continue;
364 case DL_WRITEV_S
: do_vwrite_s(&m
, FALSE
); break;
365 case DL_READV_S
: do_vread_s(&m
); break;
366 case DL_CONF
: do_init(&m
); break;
367 case DL_GETSTAT_S
: do_getstat_s(&m
); break;
368 case DL_STOP
: do_stop(&m
); break;
369 case DL_GETNAME
: do_getname(&m
); break;
370 case FKEY_PRESSED
: lance_dump(); break;
371 /*case HARD_STOP: lance_stop(); break;*/
374 sigset_t set
= m
.NOTIFY_ARG
;
375 if ( sigismember( &set
, SIGKSTOP
) )
380 for (i
=0;i
<EC_PORT_NR_MAX
;++i
)
383 if (ec
->mode
!= EC_ENABLED
)
391 /*if (ec->ec_int_pending)*/
393 ec
->ec_int_pending
= 0;
402 panic( "lance", "illegal message", m
.m_type
);
407 /*===========================================================================*
409 *===========================================================================*/
410 static void lance_dump()
414 unsigned short ioaddr
;
417 for (i
= 0, ec
= &ec_table
[0]; i
<EC_PORT_NR_MAX
; i
++, ec
++)
419 if (ec
->mode
== EC_DISABLED
)
420 printf("lance port %d is disabled\n", i
);
421 else if (ec
->mode
== EC_SINK
)
422 printf("lance port %d is in sink mode\n", i
);
424 if (ec
->mode
!= EC_ENABLED
)
427 printf("lance statistics of port %d:\n", i
);
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 out_word(ioaddr
+LANCE_ADDR
, 0x00);
453 isr
=in_word(ioaddr
+LANCE_DATA
);
454 printf("isr = 0x%x + 0x%x, flags = 0x%x\n", isr
,
455 in_word(ioaddr
+LANCE_DATA
), ec
->flags
);
457 printf("irq = %d\tioadr = %d\n", ec
->ec_irq
, ec
->ec_port
);
461 /*===========================================================================*
463 *===========================================================================*/
464 static void lance_stop()
469 for (i
= 0; i
<EC_PORT_NR_MAX
; i
++)
471 if (ec_table
[i
].mode
!= EC_ENABLED
)
473 mess
.m_type
= DL_STOP
;
478 /*printf("LANCE driver stopped.\n");*/
484 /*===========================================================================*
486 *===========================================================================*/
487 static void do_init(mp
)
497 if (port
< 0 || port
>= EC_PORT_NR_MAX
)
499 reply_mess
.m_type
= DL_CONF_REPLY
;
500 reply_mess
.m3_i1
= ENXIO
;
501 mess_reply(mp
, &reply_mess
);
505 strcpy(ec
->port_name
, "eth_card#0");
506 ec
->port_name
[9] += port
;
507 if (ec
->mode
== EC_DISABLED
)
509 /* This is the default, try to (re)locate the device. */
510 /* only try to enable if memory is correct for DMA */
511 if ( CORRECT_DMA_MEM() )
517 report( "LANCE", "DMA denied because address out of range", NO_NUM
);
520 if (ec
->mode
== EC_DISABLED
)
522 /* Probe failed, or the device is configured off. */
523 reply_mess
.m_type
= DL_CONF_REPLY
;
524 reply_mess
.m3_i1
= ENXIO
;
525 mess_reply(mp
, &reply_mess
);
528 if (ec
->mode
== EC_ENABLED
)
532 if (ec
->mode
== EC_SINK
)
534 ec
->mac_address
.ea_addr
[0] =
535 ec
->mac_address
.ea_addr
[1] =
536 ec
->mac_address
.ea_addr
[2] =
537 ec
->mac_address
.ea_addr
[3] =
538 ec
->mac_address
.ea_addr
[4] =
539 ec
->mac_address
.ea_addr
[5] = 0;
541 reply_mess
.m_type
= DL_CONF_REPLY
;
542 reply_mess
.m3_i1
= mp
->DL_PORT
;
543 reply_mess
.m3_i2
= EC_PORT_NR_MAX
;
544 *(ether_addr_t
*) reply_mess
.m3_ca1
= ec
->mac_address
;
545 mess_reply(mp
, &reply_mess
);
548 assert(ec
->mode
== EC_ENABLED
);
549 assert(ec
->flags
& ECF_ENABLED
);
551 ec
->flags
&= ~(ECF_PROMISC
| ECF_MULTI
| ECF_BROAD
);
553 if (mp
->DL_MODE
& DL_PROMISC_REQ
)
554 ec
->flags
|= ECF_PROMISC
| ECF_MULTI
| ECF_BROAD
;
555 if (mp
->DL_MODE
& DL_MULTI_REQ
)
556 ec
->flags
|= ECF_MULTI
;
557 if (mp
->DL_MODE
& DL_BROAD_REQ
)
558 ec
->flags
|= ECF_BROAD
;
560 ec
->client
= mp
->m_source
;
563 reply_mess
.m_type
= DL_CONF_REPLY
;
564 reply_mess
.m3_i1
= mp
->DL_PORT
;
565 reply_mess
.m3_i2
= EC_PORT_NR_MAX
;
566 *(ether_addr_t
*) reply_mess
.m3_ca1
= ec
->mac_address
;
568 mess_reply(mp
, &reply_mess
);
572 /*===========================================================================*
574 *===========================================================================*/
575 static void do_int(ec
)
578 if (ec
->flags
& (ECF_PACK_SEND
| ECF_PACK_RECV
))
583 /*===========================================================================*
585 *===========================================================================*/
586 static int ec_handler(hook
)
589 /* LANCE interrupt, send message and reenable interrupts. */
591 printf(">> ec_handler(): \n");
594 structof(ether_card_t
, ec_hook
, hook
)->ec_int_pending
= 1;
602 /*===========================================================================*
604 *===========================================================================*/
605 static void conf_hw(ec
)
608 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
613 ec
->mode
= EC_DISABLED
; /* Superfluous */
617 update_conf(ec
, ecp
);
618 if (ec
->mode
!= EC_ENABLED
)
621 if (!lance_probe(ec
))
623 printf("%s: No ethernet card found on PCI-BIOS info.\n",
625 ec
->mode
= EC_DISABLED
;
629 /* Allocate a memory segment, programmed I/O should set the
630 * memory segment (linmem) to zero.
632 if (ec
->ec_linmem
!= 0)
635 /*phys2seg(&ec->ec_memseg, &ec->ec_memoff, ec->ec_linmem);*/
638 /* XXX */ if (ec
->ec_linmem
== 0) ec
->ec_linmem
= 0xFFFF0000;
640 ec
->flags
= ECF_EMPTY
;
641 ec
->eth_stat
= empty_stat
;
645 /*===========================================================================*
647 *===========================================================================*/
648 static void update_conf(ec
, ecp
)
653 static char ec_fmt
[] = "x:d:x:x";
655 /* Get the default settings and modify them from the environment. */
658 switch (env_parse(ecp
->ec_envvar
, ec_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
)) {
660 ec
->mode
= EC_DISABLED
;
664 ec
->mode
= EC_ENABLED
; /* Might become disabled if
671 v
= ecp
->ec_irq
| DEI_DEFAULT
;
672 (void) env_parse(ecp
->ec_envvar
, ec_fmt
, 1, &v
, 0L,
673 (long) NR_IRQ_VECTORS
- 1);
677 (void) env_parse(ecp
->ec_envvar
, ec_fmt
, 2, &v
, 0L, 0xFFFFFL
);
681 (void) env_parse(ecp
->ec_envvar
, ec_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
686 /*===========================================================================*
688 *===========================================================================*/
689 static void ec_init(ec
)
694 /* General initialization */
695 ec
->flags
= ECF_EMPTY
;
696 /*disable_irq(ec->ec_irq);*/
697 lance_init_card(ec
); /* Get mac_address, etc ...*/
702 printf("%s: Ethernet address ", ec
->port_name
);
703 for (i
= 0; i
< 6; i
++)
704 printf("%x%c", ec
->mac_address
.ea_addr
[i
],
708 /* Finish the initialization */
709 ec
->flags
|= ECF_ENABLED
;
711 /* Set the interrupt handler */
712 /*put_irq_handler(&ec->ec_hook, ec->ec_irq, ec_handler);*/
713 ec
->ec_hook
= ec
->ec_irq
;
714 if ((r
=sys_irqsetpolicy(ec
->ec_irq
, 0, &ec
->ec_hook
)) != OK
)
715 printf("lance: error, couldn't set IRQ policy: %d\n", r
);
717 /* enable_irq(ec->ec_irq); */
719 /* enter_kdebug(">> ec_init():"); */
725 /*===========================================================================*
727 *===========================================================================*/
728 static void reply(ec
, err
, may_block
)
738 if (ec
->flags
& ECF_PACK_SEND
)
739 status
|= DL_PACK_SEND
;
740 if (ec
->flags
& ECF_PACK_RECV
)
741 status
|= DL_PACK_RECV
;
743 reply
.m_type
= DL_TASK_REPLY
;
744 reply
.DL_PORT
= ec
- ec_table
;
745 reply
.DL_PROC
= ec
->client
;
746 reply
.DL_STAT
= status
| ((u32_t
) err
<< 16);
747 reply
.DL_COUNT
= ec
->read_s
;
749 if ((r
=getuptime(&now
)) != OK
)
750 panic("lance", "getuptime() failed:", r
);
756 r
= send(ec
->client
, &reply
);
758 if (r
== ELOCKED
&& may_block
)
760 /* enter_kdebug(">> lance_task: ELOCKED!"); */
765 panic( "lance", "send failed:", r
);
768 ec
->flags
&= ~(ECF_PACK_SEND
| ECF_PACK_RECV
);
772 /*===========================================================================*
774 *===========================================================================*/
775 static void mess_reply(req
, reply_mess
)
779 if (send(req
->m_source
, reply_mess
) != OK
)
780 panic( "lance", "unable to mess_reply", NO_NUM
);
784 /*===========================================================================*
786 *===========================================================================*/
787 static void ec_confaddr(ec
)
792 static char eafmt
[]= "x:x:x:x:x:x";
795 /* User defined ethernet address? */
796 strcpy(eakey
, ec_conf
[ec
-ec_table
].ec_envvar
);
797 strcat(eakey
, "_EA");
799 for (i
= 0; i
< 6; i
++)
801 v
= ec
->mac_address
.ea_addr
[i
];
802 if (env_parse(eakey
, eafmt
, i
, &v
, 0x00L
, 0xFFL
) != EP_SET
)
804 ec
->mac_address
.ea_addr
[i
]= v
;
807 if (i
!= 0 && i
!= 6)
809 /* It's all or nothing; force a panic. */
810 (void) env_parse(eakey
, "?", 0, &v
, 0L, 0L);
815 /*===========================================================================*
817 *===========================================================================*/
818 static void ec_reinit(ec
)
822 unsigned short ioaddr
= ec
->ec_port
;
824 out_word(ioaddr
+LANCE_ADDR
, 0x0);
825 (void)in_word(ioaddr
+LANCE_ADDR
);
826 out_word(ioaddr
+LANCE_DATA
, 0x4); /* stop */
829 tx_slot_nr
= cur_tx_slot_nr
= 0;
830 for (i
=0; i
<TX_RING_SIZE
; i
++) {
831 lp
->tx_ring
[i
].u
.base
= 0;
835 /* re-init Rx-ring */
837 for (i
=0; i
<RX_RING_SIZE
; i
++)
839 lp
->rx_ring
[i
].buf_length
= -ETH_FRAME_LEN
;
840 lp
->rx_ring
[i
].u
.addr
[3] |= 0x80;
843 /* Set 'Receive Mode' */
844 if (ec
->flags
& ECF_PROMISC
)
846 out_word(ioaddr
+LANCE_ADDR
, 0xf);
847 out_word(ioaddr
+LANCE_DATA
, 0x8000);
851 if (ec
->flags
& (ECF_BROAD
| ECF_MULTI
))
853 out_word(ioaddr
+LANCE_ADDR
, 0xf);
854 out_word(ioaddr
+LANCE_DATA
, 0x0000);
858 out_word(ioaddr
+LANCE_ADDR
, 0xf);
859 out_word(ioaddr
+LANCE_DATA
, 0x4000);
863 out_word(ioaddr
+LANCE_ADDR
, 0x0);
864 (void)in_word(ioaddr
+LANCE_ADDR
);
865 out_word(ioaddr
+LANCE_DATA
, 0x142); /* start && enable interrupt */
870 /*===========================================================================*
872 *===========================================================================*/
873 static void ec_check_ints(ec
)
879 unsigned short ioaddr
= ec
->ec_port
;
881 if (!(ec
->flags
& ECF_ENABLED
))
882 panic( "lance", "got premature interrupt", NO_NUM
);
887 printf("ETH: Reading ISR...");
889 out_word(ioaddr
+LANCE_ADDR
, 0x00);
890 isr
=in_word(ioaddr
+LANCE_DATA
);
892 out_word( ioaddr
+LANCE_DATA
, isr
& ~0x004f);
893 out_word(ioaddr
+LANCE_DATA
, 0x7940);
895 printf("ISR=0x%x...",in_word(ioaddr
+LANCE_DATA
));
897 #define ISR_WINT 0x0200
898 #define ISR_RINT 0x0400
899 #define ISR_RERR 0x1000
900 #define ISR_WERR 0x4000
901 #define ISR_ERR 0x8000
902 #define ISR_RST 0x0000
904 if ((isr
& (ISR_WINT
|ISR_RINT
|ISR_RERR
|ISR_WERR
|ISR_ERR
)) == 0x0000)
917 ec
->eth_stat
.ets_recvErr
++;
919 if ((isr
& ISR_WERR
) || (isr
& ISR_WINT
))
926 ec
->eth_stat
.ets_sendErr
++;
933 /* status check: restart if needed. */
934 status
= lp
->tx_ring
[cur_tx_slot_nr
].u
.base
;
937 if (status
& 0x40000000)
939 status
= lp
->tx_ring
[cur_tx_slot_nr
].misc
;
940 ec
->eth_stat
.ets_sendErr
++;
942 ec
->eth_stat
.ets_transAb
++;
944 ec
->eth_stat
.ets_carrSense
++;
946 ec
->eth_stat
.ets_OWC
++;
949 ec
->eth_stat
.ets_fifoUnder
++;
955 if (status
& 0x18000000)
956 ec
->eth_stat
.ets_collision
++;
957 ec
->eth_stat
.ets_packetT
++;
960 /* transmit a packet on the next slot if it exists. */
962 if (isstored
[cur_tx_slot_nr
]==1)
964 /* free the tx-slot just transmitted */
965 isstored
[cur_tx_slot_nr
]=0;
966 cur_tx_slot_nr
= (++cur_tx_slot_nr
) & TX_RING_MOD_MASK
;
968 /* next tx-slot is ready? */
969 if (isstored
[cur_tx_slot_nr
]==1)
976 panic( "lance", "got premature WINT...", NO_NUM
);
980 lp
->tx_ring
[cur_tx_slot_nr
].u
.addr
[3] = 0x83;
981 out_word(ioaddr
+LANCE_ADDR
, 0x0000);
982 out_word(ioaddr
+LANCE_DATA
, 0x0048);
987 /* we set a buffered message in the slot if it exists. */
988 /* and transmit it, if needed. */
989 if (ec
->flags
& ECF_SEND_AVAIL
)
1002 ec
->flags
= ECF_STOPPED
;
1006 /* ??? cf. lance driver on linux */
1007 if (must_restart
== 1)
1010 printf("ETH: restarting...\n");
1012 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1013 (void)in_word(ioaddr
+LANCE_ADDR
);
1014 out_word(ioaddr
+LANCE_DATA
, 0x4); /* stop */
1015 out_word(ioaddr
+LANCE_DATA
, 0x2); /* start */
1019 if ((ec
->flags
& (ECF_READING
|ECF_STOPPED
)) == (ECF_READING
|ECF_STOPPED
))
1022 printf("ETH: resetting...\n");
1028 /*===========================================================================*
1030 *===========================================================================*/
1031 static void ec_reset(ec
)
1034 /* Stop/start the chip, and clear all RX,TX-slots */
1035 unsigned short ioaddr
= ec
->ec_port
;
1038 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1039 (void)in_word(ioaddr
+LANCE_ADDR
);
1040 out_word(ioaddr
+LANCE_DATA
, 0x4); /* stop */
1041 out_word(ioaddr
+LANCE_DATA
, 0x2); /* start */
1044 tx_slot_nr
= cur_tx_slot_nr
= 0;
1045 for (i
=0; i
<TX_RING_SIZE
; i
++) {
1046 lp
->tx_ring
[i
].u
.base
= 0;
1050 /* re-init Rx-ring */
1052 for (i
=0; i
<RX_RING_SIZE
; i
++)
1054 lp
->rx_ring
[i
].buf_length
= -ETH_FRAME_LEN
;
1055 lp
->rx_ring
[i
].u
.addr
[3] |= 0x80;
1058 /* store a buffered message on the slot if exists */
1060 ec
->flags
&= ~ECF_STOPPED
;
1063 /*===========================================================================*
1065 *===========================================================================*/
1066 static void ec_send(ec
)
1069 /* from ec_check_ints() or ec_reset(). */
1070 /* this function proccesses the buffered message. (slot/transmit) */
1071 if (!(ec
->flags
& ECF_SEND_AVAIL
))
1074 ec
->flags
&= ~ECF_SEND_AVAIL
;
1075 switch(ec
->sendmsg
.m_type
)
1077 case DL_WRITEV_S
: do_vwrite_s(&ec
->sendmsg
, TRUE
); break;
1079 panic( "lance", "wrong type:", ec
->sendmsg
.m_type
);
1084 /*===========================================================================*
1086 *===========================================================================*/
1087 static void do_vread_s(mp
)
1090 int port
, count
, size
;
1094 count
= mp
->DL_COUNT
;
1095 ec
= &ec_table
[port
];
1096 ec
->client
= mp
->DL_PROC
;
1098 get_userdata_s(mp
->DL_PROC
, (vir_bytes
) mp
->DL_GRANT
, 0,
1099 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
1100 sizeof(iovec_s_t
), ec
->read_iovec
.iod_iovec
);
1101 ec
->read_iovec
.iod_iovec_s
= count
;
1102 ec
->read_iovec
.iod_proc_nr
= mp
->DL_PROC
;
1103 ec
->read_iovec
.iod_grant
= (vir_bytes
) mp
->DL_GRANT
;
1104 ec
->read_iovec
.iod_iovec_offset
= 0;
1106 ec
->tmp_iovec
= ec
->read_iovec
;
1107 size
= calc_iovec_size(&ec
->tmp_iovec
);
1109 ec
->flags
|= ECF_READING
;
1113 if ((ec
->flags
& (ECF_READING
|ECF_STOPPED
)) == (ECF_READING
|ECF_STOPPED
))
1115 reply(ec
, OK
, FALSE
);
1118 /*===========================================================================*
1120 *===========================================================================*/
1121 static void ec_recv(ec
)
1125 int packet_processed
;
1127 unsigned short ioaddr
= ec
->ec_port
;
1129 if ((ec
->flags
& ECF_READING
)==0)
1131 if (!(ec
->flags
& ECF_ENABLED
))
1134 /* we check all the received slots until find a properly received packet */
1135 packet_processed
= FALSE
;
1136 while (!packet_processed
)
1138 status
= lp
->rx_ring
[rx_slot_nr
].u
.base
>> 24;
1139 if ( (status
& 0x80) == 0x00 )
1141 status
= lp
->rx_ring
[rx_slot_nr
].u
.base
>> 24;
1147 ec
->eth_stat
.ets_recvErr
++;
1149 ec
->eth_stat
.ets_fifoOver
++;
1151 ec
->eth_stat
.ets_CRCerr
++;
1153 ec
->eth_stat
.ets_OVW
++;
1155 ec
->eth_stat
.ets_frameAll
++;
1160 ec
->eth_stat
.ets_packetR
++;
1161 length
= lp
->rx_ring
[rx_slot_nr
].msg_length
;
1165 ec_nic2user(ec
, (int)(lp
->rbuf
[rx_slot_nr
]),
1166 &ec
->read_iovec
, 0, length
);
1168 ec
->read_s
= length
;
1169 ec
->flags
|= ECF_PACK_RECV
;
1170 ec
->flags
&= ~ECF_READING
;
1171 packet_processed
= TRUE
;
1173 /* set up this slot again, and we move to the next slot */
1174 lp
->rx_ring
[rx_slot_nr
].buf_length
= -ETH_FRAME_LEN
;
1175 lp
->rx_ring
[rx_slot_nr
].u
.addr
[3] |= 0x80;
1177 out_word(ioaddr
+LANCE_ADDR
, 0x00);
1178 out_word(ioaddr
+LANCE_DATA
, 0x7940);
1180 rx_slot_nr
= (++rx_slot_nr
) & RX_RING_MOD_MASK
;
1187 /*===========================================================================*
1189 *===========================================================================*/
1190 static void do_vwrite_s(mp
, from_int
)
1194 int port
, count
, check
;
1196 unsigned short ioaddr
;
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 */
1207 ec
->flags
|= ECF_SEND_AVAIL
;
1208 reply(ec
, OK
, FALSE
);
1212 /* convert the message to write_iovec */
1213 get_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
, 0,
1214 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
1215 sizeof(iovec_s_t
), ec
->write_iovec
.iod_iovec
);
1217 ec
->write_iovec
.iod_iovec_s
= count
;
1218 ec
->write_iovec
.iod_proc_nr
= mp
->DL_PROC
;
1219 ec
->write_iovec
.iod_grant
= mp
->DL_GRANT
;
1220 ec
->write_iovec
.iod_iovec_offset
= 0;
1222 ec
->tmp_iovec
= ec
->write_iovec
;
1223 ec
->write_s
= calc_iovec_size(&ec
->tmp_iovec
);
1225 /* copy write_iovec to the slot on DMA address */
1226 ec_user2nic(ec
, &ec
->write_iovec
, 0,
1227 (int)(lp
->tbuf
[tx_slot_nr
]), ec
->write_s
);
1228 /* set-up for transmitting, and transmit it if needed. */
1229 lp
->tx_ring
[tx_slot_nr
].buf_length
= -ec
->write_s
;
1230 lp
->tx_ring
[tx_slot_nr
].misc
= 0x0;
1231 lp
->tx_ring
[tx_slot_nr
].u
.base
1232 = virt_to_bus(lp
->tbuf
[tx_slot_nr
]) & 0xffffff;
1233 isstored
[tx_slot_nr
]=1;
1234 if (cur_tx_slot_nr
== tx_slot_nr
)
1238 tx_slot_nr
= (++tx_slot_nr
) & TX_RING_MOD_MASK
;
1242 ioaddr
= ec
->ec_port
;
1243 lp
->tx_ring
[cur_tx_slot_nr
].u
.addr
[3] = 0x83;
1244 out_word(ioaddr
+LANCE_ADDR
, 0x0000);
1245 out_word(ioaddr
+LANCE_DATA
, 0x0048);
1248 ec
->flags
|= ECF_PACK_SEND
;
1250 /* reply by calling do_int() if this function is called from interrupt. */
1253 reply(ec
, OK
, FALSE
);
1257 /*===========================================================================*
1259 *===========================================================================*/
1260 static void get_userdata_s(user_proc
, grant
, offset
, count
, loc_addr
)
1262 cp_grant_id_t grant
;
1268 cps
= sys_safecopyfrom(user_proc
, grant
, offset
,
1269 (vir_bytes
)loc_addr
, count
, D
);
1272 "get_userdata_s: sys_safecopyfrom failed: %d\n", cps
);
1275 /*===========================================================================*
1277 *===========================================================================*/
1278 static void ec_user2nic(ec
, iovp
, offset
, nic_addr
, count
)
1292 ec_next_iovec(iovp
);
1296 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1298 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1302 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1306 if ( (r
=sys_safecopyfrom(iovp
->iod_proc_nr
,
1307 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1308 nic_addr
, bytes
, D
)) != OK
)
1309 panic( __FILE__
, "ec_user2nic: sys_safecopyfrom failed", r
);
1317 /*===========================================================================*
1319 *===========================================================================*/
1320 static void ec_nic2user(ec
, nic_addr
, iovp
, offset
, count
)
1334 ec_next_iovec(iovp
);
1338 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1340 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1344 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1347 if ( (r
=sys_safecopyto( iovp
->iod_proc_nr
, iovp
->iod_iovec
[i
].iov_grant
,
1348 offset
, nic_addr
, bytes
, D
)) != OK
)
1349 panic( __FILE__
, "ec_nic2user: sys_safecopyto failed: ", r
);
1358 /*===========================================================================*
1360 *===========================================================================*/
1361 static int calc_iovec_size(iovp
)
1368 while (i
< iovp
->iod_iovec_s
)
1372 ec_next_iovec(iovp
);
1376 size
+= iovp
->iod_iovec
[i
].iov_size
;
1383 /*===========================================================================*
1385 *===========================================================================*/
1386 static void ec_next_iovec(iovp
)
1389 iovp
->iod_iovec_s
-= IOVEC_NR
;
1390 iovp
->iod_iovec_offset
+= IOVEC_NR
* sizeof(iovec_s_t
);
1392 get_userdata_s(iovp
->iod_proc_nr
, iovp
->iod_grant
,
1393 iovp
->iod_iovec_offset
,
1394 (iovp
->iod_iovec_s
> IOVEC_NR
?
1395 IOVEC_NR
: iovp
->iod_iovec_s
) * sizeof(iovec_s_t
),
1400 /*===========================================================================*
1402 *===========================================================================*/
1403 static void do_getstat_s(mp
)
1410 if (port
< 0 || port
>= EC_PORT_NR_MAX
)
1411 panic( "lance", "illegal port", port
);
1413 ec
= &ec_table
[port
];
1414 ec
->client
= mp
->DL_PROC
;
1416 put_userdata_s(mp
->DL_PROC
, mp
->DL_GRANT
,
1417 &ec
->eth_stat
, sizeof(ec
->eth_stat
));
1418 reply(ec
, OK
, FALSE
);
1421 /*===========================================================================*
1423 *===========================================================================*/
1424 static void put_userdata_s(user_proc
, grant
, loc_addr
, count
)
1426 cp_grant_id_t grant
;
1431 cps
= sys_safecopyto(user_proc
, grant
, 0,
1432 (vir_bytes
) loc_addr
, count
, D
);
1435 "put_userdata_s: sys_safecopyto failed: %d\n", cps
);
1438 /*===========================================================================*
1440 *===========================================================================*/
1441 static void do_stop(mp
)
1446 unsigned short ioaddr
;
1449 if (port
< 0 || port
>= EC_PORT_NR_MAX
)
1450 panic( "lance", "illegal port", port
);
1451 ec
= &ec_table
[port
];
1453 if (!(ec
->flags
& ECF_ENABLED
))
1456 ioaddr
= ec
->ec_port
;
1458 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1459 (void)in_word(ioaddr
+LANCE_ADDR
);
1460 out_word(ioaddr
+LANCE_DATA
, 0x4); /* stop */
1461 out_word(ioaddr
+LANCE_RESET
, in_word(ioaddr
+LANCE_RESET
)); /* reset */
1463 ec
->flags
= ECF_EMPTY
;
1466 static void getAddressing(devind
, ec
)
1470 unsigned int membase
, ioaddr
;
1473 for (reg
= PCI_BASE_ADDRESS_0
; reg
<= PCI_BASE_ADDRESS_5
; reg
+= 4)
1475 ioaddr
= pci_attr_r32(devind
, reg
);
1477 if ((ioaddr
& PCI_BASE_ADDRESS_IO_MASK
) == 0
1478 || (ioaddr
& PCI_BASE_ADDRESS_SPACE_IO
) == 0)
1480 /* Strip the I/O address out of the returned value */
1481 ioaddr
&= PCI_BASE_ADDRESS_IO_MASK
;
1482 /* Get the memory base address */
1483 membase
= pci_attr_r32(devind
, PCI_BASE_ADDRESS_1
);
1484 /* KK: Get the IRQ number */
1485 irq
= pci_attr_r8(devind
, PCI_INTERRUPT_PIN
);
1487 irq
= pci_attr_r8(devind
, PCI_INTERRUPT_LINE
);
1488 /* Get the ROM base address */
1489 /*pci_attr_r32(devind, PCI_ROM_ADDRESS, &romaddr);
1491 /* Take the first one or the one that matches in boot ROM address */
1492 /*if (pci_ioaddr == 0
1493 || romaddr == ((unsigned long) rom.rom_segment << 4)) {*/
1494 ec
->ec_linmem
= membase
;
1495 ec
->ec_port
= ioaddr
;
1501 /*===========================================================================*
1503 *===========================================================================*/
1504 static int lance_probe(ec
)
1507 unsigned short pci_cmd
, attached
= 0;
1508 unsigned short ioaddr
;
1509 int lance_version
, chip_version
;
1510 int devind
, just_one
, i
, r
;
1517 if ((ec
->ec_pcibus
| ec
->ec_pcidev
| ec
->ec_pcifunc
) != 0)
1519 /* Look for specific PCI device */
1520 r
= pci_find_dev(ec
->ec_pcibus
, ec
->ec_pcidev
,
1521 ec
->ec_pcifunc
, &devind
);
1524 printf("%s: no PCI found at %d.%d.%d\n",
1525 ec
->port_name
, ec
->ec_pcibus
,
1526 ec
->ec_pcidev
, ec
->ec_pcifunc
);
1529 pci_ids(devind
, &vid
, &did
);
1534 r
= pci_first_dev(&devind
, &vid
, &did
);
1542 for (i
= 0; pcitab
[i
].vid
!= 0; i
++)
1544 if (pcitab
[i
].vid
!= vid
)
1546 if (pcitab
[i
].did
!= did
)
1548 if (pcitab
[i
].checkclass
)
1551 "class check not implemented", NO_NUM
);
1555 if (pcitab
[i
].vid
!= 0)
1561 "%s: wrong PCI device (%04x/%04x) found at %d.%d.%d\n",
1562 ec
->port_name
, vid
, did
,
1564 ec
->ec_pcidev
, ec
->ec_pcifunc
);
1568 r
= pci_next_dev(&devind
, &vid
, &did
);
1573 dname
= pci_dev_name(vid
, did
);
1575 dname
= "unknown device";
1578 printf("%s: ", ec->port_name);
1579 printf("%s ", dname);
1580 printf("(%x/", vid);
1581 printf("%x) ", did);
1582 printf("at %s\n", pci_slot_name(devind));
1584 pci_reserve(devind
);
1586 /* for (i = 0; pci_dev_list[i].vendor != 0; i++) {
1587 if (pci_dev_list[i].suffix == 1)
1589 ec->ec_port = pci_dev_list[i].ioaddr;
1590 ec->ec_irq = pci_dev_list[i].irq;
1591 ec->ec_linmem = pci_dev_list[i].membase;
1592 ec->ec_bus = pci_dev_list[i].bus;
1593 ec->ec_dev = pci_dev_list[i].devfn;
1595 pci_dev_list[i].suffix = -1;
1603 getAddressing(devind
, ec
);
1605 /* ===== Bus Master ? ===== */
1606 /*pcibios_read_config_word(ec->ec_bus, ec->ec_devfn, PCI_COMMAND, &pci_cmd);*/
1607 pci_cmd
= pci_attr_r32(devind
, PCI_CR
);
1608 if (!(pci_cmd
& PCI_COMMAND_MASTER
)) {
1609 pci_cmd
|= PCI_COMMAND_MASTER
;
1610 /*pcibios_write_config_word(ec->ec_bus, ec->ec_devfn, PCI_COMMAND, pci_cmd);*/
1611 pci_attr_w32(devind
, PCI_CR
, pci_cmd
);
1614 /* ===== Probe Details ===== */
1615 ioaddr
= ec
->ec_port
;
1617 out_word(ioaddr
+LANCE_RESET
, in_word(ioaddr
+LANCE_RESET
)); /* Reset */
1618 out_word(ioaddr
+LANCE_ADDR
, 0x0); /* Sw to win 0 */
1619 if (in_word(ioaddr
+LANCE_DATA
) != 0x4)
1621 ec
->mode
=EC_DISABLED
;
1623 /* Probe Chip Version */
1624 out_word(ioaddr
+LANCE_ADDR
, 88); /* Get the version of the chip */
1625 if (in_word(ioaddr
+LANCE_ADDR
) != 88)
1629 chip_version
= in_word(ioaddr
+LANCE_DATA
);
1630 out_word(ioaddr
+LANCE_ADDR
, 89);
1631 chip_version
|= in_word(ioaddr
+LANCE_DATA
) << 16;
1632 if ((chip_version
& 0xfff) != 0x3)
1634 ec
->mode
=EC_DISABLED
;
1636 chip_version
= (chip_version
>> 12) & 0xffff;
1637 for (lance_version
= 1; chip_table
[lance_version
].id_number
!= 0;
1639 if (chip_table
[lance_version
].id_number
== chip_version
)
1644 printf("%s: %s at %X:%d\n",
1645 ec
->port_name
, chip_table
[lance_version
].name
,
1646 ec
->ec_port
, ec
->ec_irq
);
1649 return lance_version
;
1652 /*===========================================================================*
1654 *===========================================================================*/
1655 static void do_getname(mp
)
1660 strncpy(mp
->DL_NAME
, progname
, sizeof(mp
->DL_NAME
));
1661 mp
->DL_NAME
[sizeof(mp
->DL_NAME
)-1]= '\0';
1662 mp
->m_type
= DL_NAME_REPLY
;
1663 r
= send(mp
->m_source
, mp
);
1665 panic("LANCE", "do_getname: send failed", r
);
1668 /*===========================================================================*
1670 *===========================================================================*/
1671 static void lance_init_card(ec
)
1676 unsigned short ioaddr
= ec
->ec_port
;
1678 /* ============= setup init_block(cf. lance_probe1) ================ */
1679 /* make sure data structure is 8-byte aligned */
1680 l
= ((Address
)lance
+ 7) & ~7;
1681 lp
= (struct lance_interface
*)l
;
1682 lp
->init_block
.mode
= 0x3; /* disable Rx and Tx */
1683 lp
->init_block
.filter
[0] = lp
->init_block
.filter
[1] = 0x0;
1684 /* using multiple Rx/Tx buffer */
1685 lp
->init_block
.rx_ring
1686 = (virt_to_bus(&lp
->rx_ring
) & 0xffffff) | RX_RING_LEN_BITS
;
1687 lp
->init_block
.tx_ring
1688 = (virt_to_bus(&lp
->tx_ring
) & 0xffffff) | TX_RING_LEN_BITS
;
1690 l
= virt_to_bus(&lp
->init_block
);
1691 out_word(ioaddr
+LANCE_ADDR
, 0x1);
1692 (void)in_word(ioaddr
+LANCE_ADDR
);
1693 out_word(ioaddr
+LANCE_DATA
, (unsigned short)l
);
1694 out_word(ioaddr
+LANCE_ADDR
, 0x2);
1695 (void)in_word(ioaddr
+LANCE_ADDR
);
1696 out_word(ioaddr
+LANCE_DATA
, (unsigned short)(l
>> 16));
1697 out_word(ioaddr
+LANCE_ADDR
, 0x4);
1698 (void)in_word(ioaddr
+LANCE_ADDR
);
1699 out_word(ioaddr
+LANCE_DATA
, 0x915);
1700 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1701 (void)in_word(ioaddr
+LANCE_ADDR
);
1703 /* ============= Get MAC address (cf. lance_probe1) ================ */
1704 for (i
= 0; i
< 6; ++i
)
1705 ec
->mac_address
.ea_addr
[i
]=in_byte(ioaddr
+LANCE_ETH_ADDR
+i
);
1707 /* ============ (re)start init_block(cf. lance_reset) =============== */
1708 /* Reset the LANCE */
1709 (void)in_word(ioaddr
+LANCE_RESET
);
1711 /* ----- Re-initialize the LANCE ----- */
1712 /* Set station address */
1713 for (i
= 0; i
< 6; ++i
)
1714 lp
->init_block
.phys_addr
[i
] = ec
->mac_address
.ea_addr
[i
];
1715 /* Preset the receive ring headers */
1716 for (i
=0; i
<RX_RING_SIZE
; i
++) {
1717 lp
->rx_ring
[i
].buf_length
= -ETH_FRAME_LEN
;
1719 lp
->rx_ring
[i
].u
.base
= virt_to_bus(lp
->rbuf
[i
]) & 0xffffff;
1720 /* we set the top byte as the very last thing */
1721 lp
->rx_ring
[i
].u
.addr
[3] = 0x80;
1723 /* Preset the transmitting ring headers */
1724 for (i
=0; i
<TX_RING_SIZE
; i
++) {
1725 lp
->tx_ring
[i
].u
.base
= 0;
1728 lp
->init_block
.mode
= 0x0; /* enable Rx and Tx */
1730 l
= (Address
)virt_to_bus(&lp
->init_block
);
1731 out_word(ioaddr
+LANCE_ADDR
, 0x1);
1732 (void)in_word(ioaddr
+LANCE_ADDR
);
1733 out_word(ioaddr
+LANCE_DATA
, (short)l
);
1734 out_word(ioaddr
+LANCE_ADDR
, 0x2);
1735 (void)in_word(ioaddr
+LANCE_ADDR
);
1736 out_word(ioaddr
+LANCE_DATA
, (short)(l
>> 16));
1737 out_word(ioaddr
+LANCE_ADDR
, 0x4);
1738 (void)in_word(ioaddr
+LANCE_ADDR
);
1739 out_word(ioaddr
+LANCE_DATA
, 0x915);
1740 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1741 (void)in_word(ioaddr
+LANCE_ADDR
);
1743 /* ----- start when init done. ----- */
1744 out_word(ioaddr
+LANCE_DATA
, 0x4); /* stop */
1745 out_word(ioaddr
+LANCE_DATA
, 0x1); /* init */
1746 for (i
= 10000; i
> 0; --i
)
1747 if (in_word(ioaddr
+LANCE_DATA
) & 0x100)
1750 /* Set 'Multicast Table' */
1753 out_word(ioaddr
+LANCE_ADDR
, 0x8 + i
);
1754 out_word(ioaddr
+LANCE_DATA
, 0xffff);
1757 /* Set 'Receive Mode' */
1758 if (ec
->flags
& ECF_PROMISC
)
1760 out_word(ioaddr
+LANCE_ADDR
, 0xf);
1761 out_word(ioaddr
+LANCE_DATA
, 0x8000);
1765 if (ec
->flags
& (ECF_BROAD
| ECF_MULTI
))
1767 out_word(ioaddr
+LANCE_ADDR
, 0xf);
1768 out_word(ioaddr
+LANCE_DATA
, 0x0000);
1772 out_word(ioaddr
+LANCE_ADDR
, 0xf);
1773 out_word(ioaddr
+LANCE_DATA
, 0x4000);
1777 out_word(ioaddr
+LANCE_ADDR
, 0x0);
1778 (void)in_word(ioaddr
+LANCE_ADDR
);
1779 out_word(ioaddr
+LANCE_DATA
, 0x142); /* start && enable interrupt */