2 ** File: 3c503.c Dec. 20, 1996
4 ** Author: Giovanni Falzoni <gfalzoni@inwind.it>
6 ** Driver for the Etherlink II boards. Works in shared memory mode.
7 ** Programmed I/O could be used as well but would result in poor
8 ** performances. This file contains only the board specific code,
9 ** the rest is in 8390.c Code specific for ISA bus only
12 #include <minix/drivers.h>
13 #include <net/gen/ether.h>
14 #include <net/gen/eth_io.h>
17 #if (ENABLE_3C503 == 1)
23 ** Name: void el2_init(dpeth_t *dep);
24 ** Function: Initalize hardware and data structures.
26 static void el2_init(dpeth_t
* dep
)
32 /* Map the address PROM to lower I/O address range */
33 cntr
= inb_el2(dep
, EL2_CNTR
);
34 outb_el2(dep
, EL2_CNTR
, cntr
| ECNTR_SAPROM
);
36 /* Read station address from PROM */
37 for (ix
= EL2_EA0
; ix
<= EL2_EA5
; ix
+= 1)
38 dep
->de_address
.ea_addr
[ix
] = inb_el2(dep
, ix
);
40 /* Map the 8390 back to lower I/O address range */
41 outb_el2(dep
, EL2_CNTR
, cntr
);
43 /* Enable memory, but turn off interrupts until we are ready */
44 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
46 dep
->de_data_port
= dep
->de_dp8390_port
= dep
->de_base_port
;
47 dep
->de_prog_IO
= FALSE
; /* Programmed I/O not yet available */
49 /* Check width of data bus */
50 outb_el2(dep
, DP_CR
, CR_PS_P0
| CR_NO_DMA
| CR_STP
);
51 outb_el2(dep
, DP_DCR
, 0);
52 outb_el2(dep
, DP_CR
, CR_PS_P2
| CR_NO_DMA
| CR_STP
);
53 dep
->de_16bit
= (inb_el2(dep
, DP_DCR
) & DCR_WTS
) != 0;
54 outb_el2(dep
, DP_CR
, CR_PS_P0
| CR_NO_DMA
| CR_STP
);
56 /* Allocate one send buffer (1.5kb) per 8kb of on board memory. */
57 /* Only 8kb of 3c503/16 boards are used to avoid specific routines */
58 sendq_nr
= dep
->de_ramsize
/ 0x2000;
61 else if (sendq_nr
> SENDQ_NR
)
64 dep
->de_sendq_nr
= sendq_nr
;
65 for (ix
= 0; ix
< sendq_nr
; ix
++)
66 dep
->de_sendq
[ix
].sq_sendpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
68 dep
->de_startpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
69 dep
->de_stoppage
= EL2_SM_STOP_PG
;
71 outb_el2(dep
, EL2_STARTPG
, dep
->de_startpage
);
72 outb_el2(dep
, EL2_STOPPG
, dep
->de_stoppage
);
74 /* Point the vector pointer registers somewhere ?harmless?. */
75 outb_el2(dep
, EL2_VP2
, 0xFF); /* Point at the ROM restart location */
76 outb_el2(dep
, EL2_VP1
, 0xFF); /* 0xFFFF:0000 (from original sources) */
77 outb_el2(dep
, EL2_VP0
, 0x00); /* - What for protected mode? */
79 /* Set interrupt level for 3c503 */
80 irq
= (dep
->de_irq
&= ~DEI_DEFAULT
); /* Strip the default flag. */
81 if (irq
== 9) irq
= 2;
82 if (irq
< 2 || irq
> 5) panic("bad 3c503 irq configuration: %d", irq
);
83 outb_el2(dep
, EL2_IDCFG
, (0x04 << irq
));
85 outb_el2(dep
, EL2_DRQCNT
, 0x08); /* Set burst size to 8 */
86 outb_el2(dep
, EL2_DMAAH
, EL2_SM_START_PG
); /* Put start of TX */
87 outb_el2(dep
, EL2_DMAAL
, 0x00); /* buffer in the GA DMA reg */
89 outb_el2(dep
, EL2_CFGR
, ECFGR_NORM
); /* Enable shared memory */
91 ns_init(dep
); /* Initialize DP controller */
93 printf("%s: Etherlink II%s (%s) at %X:%d:%05lX - ",
94 dep
->de_name
, dep
->de_16bit
? "/16" : "", "3c503",
95 dep
->de_base_port
, dep
->de_irq
,
96 dep
->de_linmem
+ dep
->de_offset_page
);
97 for (ix
= 0; ix
< SA_ADDR_LEN
; ix
+= 1)
98 printf("%02X%c", dep
->de_address
.ea_addr
[ix
],
99 ix
< SA_ADDR_LEN
- 1 ? ':' : '\n');
104 ** Name: void el2_stop(dpeth_t *dep);
105 ** Function: Stops board by disabling interrupts.
107 static void el2_stop(dpeth_t
* dep
)
110 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
111 sys_irqdisable(&dep
->de_hook
); /* disable interrupts */
116 ** Name: void el2_probe(dpeth_t *dep);
117 ** Function: Probe for the presence of an EtherLink II card.
118 ** Initialize memory addressing if card detected.
120 int el2_probe(dpeth_t
* dep
)
125 /* Thin ethernet or AUI? */
126 thin
= (dep
->de_linmem
& 1) ? ECNTR_AUI
: ECNTR_THIN
;
128 /* Location registers should have 1 bit set */
129 if (!(iobase
= inb_el2(dep
, EL2_IOBASE
))) return FALSE
;
130 if (!((membase
= inb_el2(dep
, EL2_MEMBASE
)) & 0xF0)) return FALSE
;
131 if ((iobase
& (iobase
- 1)) || (membase
& (membase
- 1))) return FALSE
;
134 outb_el2(dep
, EL2_CNTR
, ECNTR_RESET
| thin
);
136 outb_el2(dep
, EL2_CNTR
, thin
);
139 /* Map the address PROM to lower I/O address range */
140 outb_el2(dep
, EL2_CNTR
, ECNTR_SAPROM
| thin
);
141 if (inb_el2(dep
, EL2_EA0
) != 0x02 || /* Etherlink II Station address */
142 inb_el2(dep
, EL2_EA1
) != 0x60 || /* MUST be 02:60:8c:xx:xx:xx */
143 inb_el2(dep
, EL2_EA2
) != 0x8C)
144 return FALSE
; /* No Etherlink board at this address */
146 /* Map the 8390 back to lower I/O address range */
147 outb_el2(dep
, EL2_CNTR
, thin
);
149 /* Setup shared memory addressing for 3c503 */
150 dep
->de_linmem
= ((membase
& 0xC0) ? EL2_BASE_0D8000
: EL2_BASE_0C8000
) +
151 ((membase
& 0xA0) ? (EL2_BASE_0CC000
- EL2_BASE_0C8000
) : 0x0000);
153 /* Shared memory starts at 0x2000 (8kb window) */
154 dep
->de_offset_page
= (EL2_SM_START_PG
* DP_PAGESIZE
);
155 dep
->de_linmem
-= dep
->de_offset_page
;
156 dep
->de_ramsize
= (EL2_SM_STOP_PG
- EL2_SM_START_PG
) * DP_PAGESIZE
;
158 /* Board initialization and stop functions */
159 dep
->de_initf
= el2_init
;
160 dep
->de_stopf
= el2_stop
;
163 #endif /* ENABLE_3C503 */