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_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>
47 #include <net/gen/ether.h>
48 #include <net/gen/eth_io.h>
51 #include <minix/syslib.h>
52 #include <minix/endpoint.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
;
65 typedef struct ec_conf
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. */
89 { PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD_LANCE
, 0 }, /* AMD LANCE */
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
,
116 _PROTOTYPE( static void ec_nic2user
,
117 (ether_card_t
*ec
, int nic_addr
,
118 iovec_dat_t
*iovp
, vir_bytes offset
,
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
));
144 #define Address unsigned long
146 #define virt_to_bus(x) (vir2phys((unsigned long)x))
147 unsigned long vir2phys( unsigned long x
)
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
);
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
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
221 unsigned char phys_addr
[6];
222 unsigned long filter
[2];
231 unsigned char addr
[4];
233 short buf_length
; /* 2s complement */
241 unsigned char addr
[4];
243 short buf_length
; /* 2s complement */
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
) );
272 EXTERN
char **env_argv
;
274 /*===========================================================================*
276 *===========================================================================*/
277 void main( int argc
, char **argv
)
283 /* SEF local startup. */
284 env_setargs(argc
, argv
);
289 for (i
=0;i
<EC_PORT_NR_MAX
;++i
)
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
)
303 sys_irqdisable(&ec
->ec_hook
);
306 if (is_notify(m
.m_type
)) {
307 switch(_ENDPOINT_P(m
.m_source
)) {
312 for (i
=0;i
<EC_PORT_NR_MAX
;++i
)
315 if (ec
->mode
!= EC_ENABLED
)
320 ec
->ec_int_pending
= 0;
330 if (getsigset(&set
) != 0) break;
332 if (sigismember(&set
, SIGTERM
))
338 panic( "lance", "illegal notify source", m
.m_source
);
341 /* get next message */
348 do_vwrite_s(&m
, FALSE
);
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. */
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. */
399 (progname
=strrchr(env_argv
[0],'/')) ? progname
++ : (progname
=env_argv
[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
);
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
);
417 printf("lance: ds_retrieve_label_num failed for 'inet': %d\n", r
);
422 /*===========================================================================*
424 *===========================================================================*/
425 static void lance_dump()
429 unsigned short ioaddr
;
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
)
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
,
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 /*===========================================================================*
489 *===========================================================================*/
490 static void lance_stop()
495 for (i
= 0; i
<EC_PORT_NR_MAX
; i
++)
497 if (ec_table
[i
].mode
!= EC_ENABLED
)
499 mess
.m_type
= DL_STOP
;
505 printf("LANCE driver stopped.\n");
512 /*===========================================================================*
514 *===========================================================================*/
515 static void do_init(mp
)
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
);
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
);
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() )
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
);
562 if (ec
->mode
== EC_ENABLED
)
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;
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
);
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
;
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 /*===========================================================================*
609 *===========================================================================*/
610 static void do_int(ec
)
613 if (ec
->flags
& (ECF_PACK_SEND
| ECF_PACK_RECV
))
618 /*===========================================================================*
620 *===========================================================================*/
621 static void conf_hw(ec
)
624 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
629 ec
->mode
= EC_DISABLED
; /* Superfluous */
633 update_conf(ec
, ecp
);
634 if (ec
->mode
!= EC_ENABLED
)
637 if (!lance_probe(ec
))
639 printf("%s: No ethernet card found on PCI-BIOS info.\n",
641 ec
->mode
= EC_DISABLED
;
645 /* XXX */ if (ec
->ec_linmem
== 0) ec
->ec_linmem
= 0xFFFF0000;
647 ec
->flags
= ECF_EMPTY
;
648 ec
->eth_stat
= empty_stat
;
652 /*===========================================================================*
654 *===========================================================================*/
655 static void update_conf(ec
, ecp
)
660 static char ec_fmt
[] = "x:d:x:x";
662 /* Get the default settings and modify them from the environment. */
665 switch (env_parse(ecp
->ec_envvar
, ec_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
))
668 ec
->mode
= EC_DISABLED
;
673 ec
->mode
= EC_ENABLED
; /* Might become disabled if
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);
686 (void) env_parse(ecp
->ec_envvar
, ec_fmt
, 2, &v
, 0L, 0xFFFFFL
);
690 (void) env_parse(ecp
->ec_envvar
, ec_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
695 /*===========================================================================*
697 *===========================================================================*/
698 static void ec_init(ec
)
703 /* General initialization */
704 ec
->flags
= ECF_EMPTY
;
705 lance_init_card(ec
); /* Get mac_address, etc ...*/
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
],
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
);
728 /*===========================================================================*
730 *===========================================================================*/
731 static void reply(ec
, err
, may_block
)
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
);
756 r
= send(ec
->client
, &reply
);
757 if (r
== ELOCKED
&& may_block
)
762 panic( "lance", "send failed:", r
);
765 ec
->flags
&= ~(ECF_PACK_SEND
| ECF_PACK_RECV
);
769 /*===========================================================================*
771 *===========================================================================*/
772 static void mess_reply(req
, reply_mess
)
776 if (send(req
->m_source
, reply_mess
) != OK
)
777 panic( "lance", "unable to mess_reply", NO_NUM
);
781 /*===========================================================================*
783 *===========================================================================*/
784 static void ec_confaddr(ec
)
789 static char eafmt
[]= "x:x:x:x:x:x";
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
)
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 /*===========================================================================*
814 *===========================================================================*/
815 static void ec_reinit(ec
)
819 unsigned short ioaddr
= ec
->ec_port
;
822 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STOP
);
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;
832 /* re-init Rx-ring */
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
);
847 if (ec
->flags
& (ECF_BROAD
| ECF_MULTI
))
849 write_csr(ioaddr
, LANCE_CSR15
, 0x0000);
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
);
864 /*===========================================================================*
866 *===========================================================================*/
867 static void ec_check_ints(ec
)
870 int must_restart
= 0;
873 unsigned short ioaddr
= ec
->ec_port
;
875 if (!(ec
->flags
& ECF_ENABLED
))
876 panic( "lance", "got premature interrupt", NO_NUM
);
881 printf("ETH: Reading ISR...");
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)
904 if (isr
& LANCE_CSR0_MISS
)
907 printf("RX Missed Frame\n");
909 ec
->eth_stat
.ets_recvErr
++;
911 if ((isr
& LANCE_CSR0_BABL
) || (isr
& LANCE_CSR0_TINT
))
913 if (isr
& LANCE_CSR0_BABL
)
916 printf("TX Timeout\n");
918 ec
->eth_stat
.ets_sendErr
++;
920 if (isr
& LANCE_CSR0_TINT
)
925 /* status check: restart if needed. */
926 status
= lp
->tx_ring
[cur_tx_slot_nr
].u
.base
;
929 if (status
& 0x40000000)
931 status
= lp
->tx_ring
[cur_tx_slot_nr
].misc
;
932 ec
->eth_stat
.ets_sendErr
++;
934 ec
->eth_stat
.ets_transAb
++;
936 ec
->eth_stat
.ets_carrSense
++;
938 ec
->eth_stat
.ets_OWC
++;
941 ec
->eth_stat
.ets_fifoUnder
++;
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. */
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)
968 panic( "lance", "got premature TX INT...", NO_NUM
);
972 lp
->tx_ring
[cur_tx_slot_nr
].u
.addr
[3] = 0x83;
973 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_IENA
|LANCE_CSR0_TDMD
);
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
)
983 if (isr
& LANCE_CSR0_RINT
)
993 ec
->flags
= ECF_STOPPED
;
1000 /* ??? cf. lance driver on linux */
1001 if (must_restart
== 1)
1004 printf("ETH: restarting...\n");
1007 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STOP
);
1009 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STRT
);
1013 if ((ec
->flags
& (ECF_READING
|ECF_STOPPED
)) == (ECF_READING
|ECF_STOPPED
))
1016 printf("ETH: resetting...\n");
1022 /*===========================================================================*
1024 *===========================================================================*/
1025 static void ec_reset(ec
)
1028 /* Stop/start the chip, and clear all RX,TX-slots */
1029 unsigned short ioaddr
= ec
->ec_port
;
1033 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STOP
);
1035 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STRT
);
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;
1045 /* re-init Rx-ring */
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 */
1055 ec
->flags
&= ~ECF_STOPPED
;
1058 /*===========================================================================*
1060 *===========================================================================*/
1061 static void ec_send(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
))
1069 ec
->flags
&= ~ECF_SEND_AVAIL
;
1070 switch(ec
->sendmsg
.m_type
)
1072 case DL_WRITEV_S
: do_vwrite_s(&ec
->sendmsg
, TRUE
); break;
1074 panic( "lance", "wrong type:", ec
->sendmsg
.m_type
);
1079 /*===========================================================================*
1081 *===========================================================================*/
1082 static void do_vread_s(mp
)
1085 int port
, count
, size
, r
;
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
);
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
;
1112 if ((ec
->flags
& (ECF_READING
|ECF_STOPPED
)) == (ECF_READING
|ECF_STOPPED
))
1114 reply(ec
, OK
, FALSE
);
1117 /*===========================================================================*
1119 *===========================================================================*/
1120 static void ec_recv(ec
)
1124 int packet_processed
;
1126 unsigned short ioaddr
= ec
->ec_port
;
1128 if ((ec
->flags
& ECF_READING
)==0)
1130 if (!(ec
->flags
& ECF_ENABLED
))
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;
1146 ec
->eth_stat
.ets_recvErr
++;
1148 ec
->eth_stat
.ets_fifoOver
++;
1150 ec
->eth_stat
.ets_CRCerr
++;
1152 ec
->eth_stat
.ets_OVW
++;
1154 ec
->eth_stat
.ets_frameAll
++;
1159 ec
->eth_stat
.ets_packetR
++;
1160 length
= lp
->rx_ring
[rx_slot_nr
].msg_length
;
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
;
1187 /*===========================================================================*
1189 *===========================================================================*/
1190 static void do_vwrite_s(mp
, from_int
)
1194 int port
, count
, check
, r
;
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 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
);
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
)
1242 tx_slot_nr
= (++tx_slot_nr
) & TX_RING_MOD_MASK
;
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. */
1256 reply(ec
, OK
, FALSE
);
1260 /*===========================================================================*
1262 *===========================================================================*/
1263 static void ec_user2nic(ec
, iovp
, offset
, nic_addr
, count
)
1277 ec_next_iovec(iovp
);
1281 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1283 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1287 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
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
);
1302 /*===========================================================================*
1304 *===========================================================================*/
1305 static void ec_nic2user(ec
, nic_addr
, iovp
, offset
, count
)
1319 ec_next_iovec(iovp
);
1323 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1325 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1329 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
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
);
1343 /*===========================================================================*
1345 *===========================================================================*/
1346 static int calc_iovec_size(iovp
)
1353 while (i
< iovp
->iod_iovec_s
)
1357 ec_next_iovec(iovp
);
1361 size
+= iovp
->iod_iovec
[i
].iov_size
;
1368 /*===========================================================================*
1370 *===========================================================================*/
1371 static void ec_next_iovec(iovp
)
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
);
1387 "ec_next_iovec: sys_safecopyfrom failed: %d\n", r
);
1391 /*===========================================================================*
1393 *===========================================================================*/
1394 static void do_getstat_s(mp
)
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
);
1412 "do_getstat_s: sys_safecopyto failed: %d\n", r
);
1414 mp
->m_type
= DL_STAT_REPLY
;
1417 r
= send(mp
->m_source
, mp
);
1419 panic(__FILE__
, "do_getstat_s: send failed: %d\n", r
);
1422 /*===========================================================================*
1424 *===========================================================================*/
1425 static void do_stop(mp
)
1430 unsigned short ioaddr
;
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
))
1440 ioaddr
= ec
->ec_port
;
1443 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STOP
);
1446 in_word(ioaddr
+LANCE_RESET
);
1448 ec
->flags
= ECF_EMPTY
;
1451 /*===========================================================================*
1453 *===========================================================================*/
1454 static void getAddressing(devind
, ec
)
1458 unsigned int membase
, ioaddr
;
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)
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
);
1475 irq
= pci_attr_r8(devind
, PCI_INTERRUPT_LINE
);
1477 ec
->ec_linmem
= membase
;
1478 ec
->ec_port
= ioaddr
;
1483 /*===========================================================================*
1485 *===========================================================================*/
1486 static int lance_probe(ec
)
1489 unsigned short pci_cmd
;
1490 unsigned short ioaddr
;
1491 int lance_version
, chip_version
;
1492 int devind
, just_one
, i
, r
;
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
);
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
);
1509 pci_ids(devind
, &vid
, &did
);
1514 r
= pci_first_dev(&devind
, &vid
, &did
);
1522 for (i
= 0; pcitab
[i
].vid
!= 0; i
++)
1524 if (pcitab
[i
].vid
!= vid
)
1526 if (pcitab
[i
].did
!= did
)
1528 if (pcitab
[i
].checkclass
)
1531 "class check not implemented", NO_NUM
);
1535 if (pcitab
[i
].vid
!= 0)
1541 "%s: wrong PCI device (%04x/%04x) found at %d.%d.%d\n",
1542 ec
->port_name
, vid
, did
,
1544 ec
->ec_pcidev
, ec
->ec_pcifunc
);
1548 r
= pci_next_dev(&devind
, &vid
, &did
);
1553 dname
= pci_dev_name(vid
, did
);
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
;
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)
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;
1596 if (chip_table
[lance_version
].id_number
== chip_version
)
1601 printf("%s: %s at %X:%d\n",
1602 ec
->port_name
, chip_table
[lance_version
].name
,
1603 ec
->ec_port
, ec
->ec_irq
);
1606 return lance_version
;
1609 /*===========================================================================*
1611 *===========================================================================*/
1612 static void do_getname(mp
)
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
);
1622 panic("LANCE", "do_getname: send failed", r
);
1625 /*===========================================================================*
1627 *===========================================================================*/
1628 static void lance_init_card(ec
)
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
;
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;
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. ----- */
1695 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_STOP
);
1697 write_csr(ioaddr
, LANCE_CSR0
, LANCE_CSR0_INIT
);
1699 for (i
= 10000; i
> 0; --i
)
1700 if (read_csr(ioaddr
, LANCE_CSR0
) & LANCE_CSR0_IDON
)
1703 /* Set 'Multicast Table' */
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
);
1716 if (ec
->flags
& (ECF_BROAD
| ECF_MULTI
))
1718 write_csr(ioaddr
, LANCE_CSR15
, 0x0000);
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
);
1733 /*===========================================================================*
1735 *===========================================================================*/
1736 static u8_t
in_byte(port_t port
)
1741 r
= sys_inb(port
, &value
);
1743 panic("lance","sys_inb failed", r
);
1747 /*===========================================================================*
1749 *===========================================================================*/
1750 static u16_t
in_word(port_t port
)
1755 r
= sys_inw(port
, &value
);
1757 panic("lance","sys_inw failed", r
);
1761 /*===========================================================================*
1763 *===========================================================================*/
1764 static void out_byte(port_t port
, u8_t value
)
1768 r
= sys_outb(port
, value
);
1770 panic("lance","sys_outb failed", r
);
1773 /*===========================================================================*
1775 *===========================================================================*/
1776 static void out_word(port_t port
, u16_t value
)
1780 r
= sys_outw(port
, value
);
1782 panic("lance","sys_outw failed", r
);
1785 /*===========================================================================*
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 /*===========================================================================*
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
);