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 <minix/netdriver.h>
16 #if (ENABLE_3C503 == 1)
23 ** Function: Initalize hardware and data structures.
25 static void el2_init(dpeth_t
* dep
)
28 unsigned int sendq_nr
;
31 /* Map the address PROM to lower I/O address range */
32 cntr
= inb_el2(dep
, EL2_CNTR
);
33 outb_el2(dep
, EL2_CNTR
, cntr
| ECNTR_SAPROM
);
35 /* Read station address from PROM */
36 for (ix
= EL2_EA0
; ix
<= EL2_EA5
; ix
+= 1)
37 dep
->de_address
.na_addr
[ix
] = inb_el2(dep
, ix
);
39 /* Map the 8390 back to lower I/O address range */
40 outb_el2(dep
, EL2_CNTR
, cntr
);
42 /* Enable memory, but turn off interrupts until we are ready */
43 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
45 dep
->de_data_port
= dep
->de_dp8390_port
= dep
->de_base_port
;
46 dep
->de_prog_IO
= FALSE
; /* Programmed I/O not yet available */
48 /* Check width of data bus */
49 outb_el2(dep
, DP_CR
, CR_PS_P0
| CR_NO_DMA
| CR_STP
);
50 outb_el2(dep
, DP_DCR
, 0);
51 outb_el2(dep
, DP_CR
, CR_PS_P2
| CR_NO_DMA
| CR_STP
);
52 dep
->de_16bit
= (inb_el2(dep
, DP_DCR
) & DCR_WTS
) != 0;
53 outb_el2(dep
, DP_CR
, CR_PS_P0
| CR_NO_DMA
| CR_STP
);
55 /* Allocate one send buffer (1.5kb) per 8kb of on board memory. */
56 /* Only 8kb of 3c503/16 boards are used to avoid specific routines */
57 sendq_nr
= dep
->de_ramsize
/ 0x2000;
60 else if (sendq_nr
> SENDQ_NR
)
63 dep
->de_sendq_nr
= sendq_nr
;
64 for (ix
= 0; ix
< sendq_nr
; ix
++)
65 dep
->de_sendq
[ix
].sq_sendpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
67 dep
->de_startpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
68 dep
->de_stoppage
= EL2_SM_STOP_PG
;
70 outb_el2(dep
, EL2_STARTPG
, dep
->de_startpage
);
71 outb_el2(dep
, EL2_STOPPG
, dep
->de_stoppage
);
73 /* Point the vector pointer registers somewhere ?harmless?. */
74 outb_el2(dep
, EL2_VP2
, 0xFF); /* Point at the ROM restart location */
75 outb_el2(dep
, EL2_VP1
, 0xFF); /* 0xFFFF:0000 (from original sources) */
76 outb_el2(dep
, EL2_VP0
, 0x00); /* - What for protected mode? */
78 /* Set interrupt level for 3c503 */
79 irq
= (dep
->de_irq
&= ~DEI_DEFAULT
); /* Strip the default flag. */
80 if (irq
== 9) irq
= 2;
81 if (irq
< 2 || irq
> 5) panic("bad 3c503 irq configuration: %d", irq
);
82 outb_el2(dep
, EL2_IDCFG
, (0x04 << irq
));
84 outb_el2(dep
, EL2_DRQCNT
, 0x08); /* Set burst size to 8 */
85 outb_el2(dep
, EL2_DMAAH
, EL2_SM_START_PG
); /* Put start of TX */
86 outb_el2(dep
, EL2_DMAAL
, 0x00); /* buffer in the GA DMA reg */
88 outb_el2(dep
, EL2_CFGR
, ECFGR_NORM
); /* Enable shared memory */
90 ns_init(dep
); /* Initialize DP controller */
92 printf("%s: Etherlink II%s (%s) at %X:%d:%05lX - ",
93 netdriver_name(), dep
->de_16bit
? "/16" : "", "3c503",
94 dep
->de_base_port
, dep
->de_irq
,
95 dep
->de_linmem
+ dep
->de_offset_page
);
96 for (ix
= 0; ix
< SA_ADDR_LEN
; ix
+= 1)
97 printf("%02X%c", dep
->de_address
.na_addr
[ix
],
98 ix
< SA_ADDR_LEN
- 1 ? ':' : '\n');
103 ** Function: Stops board by disabling interrupts.
105 static void el2_stop(dpeth_t
* dep
)
108 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
109 sys_irqdisable(&dep
->de_hook
); /* disable interrupts */
114 ** Function: Probe for the presence of an EtherLink II card.
115 ** Initialize memory addressing if card detected.
117 int el2_probe(dpeth_t
* dep
)
122 /* Thin ethernet or AUI? */
123 thin
= (dep
->de_linmem
& 1) ? ECNTR_AUI
: ECNTR_THIN
;
125 /* Location registers should have 1 bit set */
126 if (!(iobase
= inb_el2(dep
, EL2_IOBASE
))) return FALSE
;
127 if (!((membase
= inb_el2(dep
, EL2_MEMBASE
)) & 0xF0)) return FALSE
;
128 if ((iobase
& (iobase
- 1)) || (membase
& (membase
- 1))) return FALSE
;
131 outb_el2(dep
, EL2_CNTR
, ECNTR_RESET
| thin
);
133 outb_el2(dep
, EL2_CNTR
, thin
);
136 /* Map the address PROM to lower I/O address range */
137 outb_el2(dep
, EL2_CNTR
, ECNTR_SAPROM
| thin
);
138 if (inb_el2(dep
, EL2_EA0
) != 0x02 || /* Etherlink II Station address */
139 inb_el2(dep
, EL2_EA1
) != 0x60 || /* MUST be 02:60:8c:xx:xx:xx */
140 inb_el2(dep
, EL2_EA2
) != 0x8C)
141 return FALSE
; /* No Etherlink board at this address */
143 /* Map the 8390 back to lower I/O address range */
144 outb_el2(dep
, EL2_CNTR
, thin
);
146 /* Setup shared memory addressing for 3c503 */
147 dep
->de_linmem
= ((membase
& 0xC0) ? EL2_BASE_0D8000
: EL2_BASE_0C8000
) +
148 ((membase
& 0xA0) ? (EL2_BASE_0CC000
- EL2_BASE_0C8000
) : 0x0000);
150 /* Shared memory starts at 0x2000 (8kb window) */
151 dep
->de_offset_page
= (EL2_SM_START_PG
* DP_PAGESIZE
);
152 dep
->de_linmem
-= dep
->de_offset_page
;
153 dep
->de_ramsize
= (EL2_SM_STOP_PG
- EL2_SM_START_PG
) * DP_PAGESIZE
;
155 /* Board initialization and stop functions */
156 dep
->de_initf
= el2_init
;
157 dep
->de_stopf
= el2_stop
;
160 #endif /* ENABLE_3C503 */