2 * 3c503.c A shared memory driver for Etherlink II board.
4 * Created: Dec. 20, 1996 by G. Falzoni <falzoni@marina.scn.de>
6 * Inspired by the TNET package by M. Ostrowski, the driver for Linux
7 * by D. Becker, the Crynwr 3c503 packet driver, and the Amoeba driver.
9 * It works in shared memory mode and should be used with the
10 * device driver for NS 8390 based cards of Minix. Programmed
11 * I/O could be used as well but would result in poor performance.
14 #include "../drivers.h"
16 #include <net/gen/ether.h>
17 #include <net/gen/eth_io.h>
25 #define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1)
27 _PROTOTYPE(static void el2_init
, (dpeth_t
*dep
));
28 _PROTOTYPE(static void el2_stop
, (dpeth_t
*dep
));
29 _PROTOTYPE( static void milli_delay
, (unsigned long millis
) );
31 /*===========================================================================*
33 *===========================================================================*/
34 static void el2_init(dep
)
37 /* Initalize hardware and data structures. */
42 /* Map the address PROM to lower I/O address range */
43 cntr
= inb_el2(dep
, EL2_CNTR
);
44 outb_el2(dep
, EL2_CNTR
, cntr
| ECNTR_SAPROM
);
46 /* Read station address from PROM */
47 for (ix
= EL2_EA0
; ix
<= EL2_EA5
; ix
+= 1)
48 dep
->de_address
.ea_addr
[ix
] = inb_el2(dep
, ix
);
50 /* Map the 8390 back to lower I/O address range */
51 outb_el2(dep
, EL2_CNTR
, cntr
);
53 /* Enable memory, but turn off interrupts until we are ready */
54 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
56 dep
->de_data_port
= dep
->de_dp8390_port
= dep
->de_base_port
;
57 dep
->de_prog_IO
= 0; /* Programmed I/O not yet available */
59 /* Check width of data bus:
60 * 1. Write 0 to WTS bit. The board will drive it to 1 if it is a
63 * 3. See if it is a 16-bit card
66 outb_el2(dep
, DP_CR
, CR_PS_P0
|CR_DM_ABORT
|CR_STP
);
67 outb_el2(dep
, DP_DCR
, 0);
68 outb_el2(dep
, DP_CR
, CR_PS_P2
|CR_DM_ABORT
|CR_STP
);
69 dep
->de_16bit
= (inb_el2(dep
, DP_DCR
) & DCR_WTS
) != 0;
70 outb_el2(dep
, DP_CR
, CR_PS_P0
|CR_DM_ABORT
|CR_STP
);
72 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
73 sendq_nr
= (dep
->de_ramsize
- dep
->de_offset_page
) / 0x2000;
76 else if (sendq_nr
> SENDQ_NR
)
79 dep
->de_sendq_nr
= sendq_nr
;
80 for (ix
= 0; ix
< sendq_nr
; ix
++)
81 dep
->de_sendq
[ix
].sq_sendpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
83 dep
->de_startpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
84 dep
->de_stoppage
= EL2_SM_STOP_PG
;
86 outb_el2(dep
, EL2_STARTPG
, dep
->de_startpage
);
87 outb_el2(dep
, EL2_STOPPG
, dep
->de_stoppage
);
89 /* Point the vector pointer registers somewhere ?harmless?. */
90 outb_el2(dep
, EL2_VP2
, 0xFF); /* Point at the ROM restart location */
91 outb_el2(dep
, EL2_VP1
, 0xFF); /* 0xFFFF:0000 (from original sources) */
92 outb_el2(dep
, EL2_VP0
, 0x00); /* - What for protected mode? */
94 /* Set interrupt level for 3c503 */
95 irq
= (dep
->de_irq
&= ~DEI_DEFAULT
); /* Strip the default flag. */
96 if (irq
== 9) irq
= 2;
97 if (irq
< 2 || irq
> 5) panic("", "bad 3c503 irq configuration", irq
);
98 outb_el2(dep
, EL2_IDCFG
, (0x04 << irq
));
100 outb_el2(dep
, EL2_DRQCNT
, 0x08); /* Set burst size to 8 */
101 outb_el2(dep
, EL2_DMAAH
, EL2_SM_START_PG
); /* Put start of TX */
102 outb_el2(dep
, EL2_DMAAL
, 0x00); /* buffer in the GA DMA reg */
104 outb_el2(dep
, EL2_CFGR
, ECFGR_NORM
); /* Enable shared memory */
107 printf("%s: 3c503 at %X:%d:%lX\n",
108 dep
->de_name
, dep
->de_base_port
, dep
->de_irq
,
109 dep
->de_linmem
+ dep
->de_offset_page
);
111 printf("%s: 3Com Etherlink II %sat I/O address 0x%X, "
112 "memory address 0x%lX, irq %d\n",
113 dep
->de_name
, dep
->de_16bit
? "(16-bit) " : "",
115 dep
->de_linmem
+ dep
->de_offset_page
,
120 /*===========================================================================*
122 *===========================================================================*/
123 static void el2_stop(dep
)
126 /* Stops board by disabling interrupts. */
129 printf("%s: stopping Etherlink\n", dep
->de_name
);
131 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
135 /*===========================================================================*
137 *===========================================================================*/
141 /* Probe for the presence of an EtherLink II card. Initialize memory
142 * addressing if card detected.
147 /* Thin ethernet or AUI? */
148 thin
= (dep
->de_linmem
& 1) ? ECNTR_AUI
: ECNTR_THIN
;
150 /* Location registers should have 1 bit set */
151 if (!(iobase
= inb_el2(dep
, EL2_IOBASE
))) return 0;
152 if (!((membase
= inb_el2(dep
, EL2_MEMBASE
)) & 0xF0)) return 0;
153 if ((iobase
& (iobase
- 1)) || (membase
& (membase
- 1))) return 0;
156 outb_el2(dep
, EL2_CNTR
, ECNTR_RESET
| thin
);
158 outb_el2(dep
, EL2_CNTR
, thin
);
161 /* Map the address PROM to lower I/O address range */
162 outb_el2(dep
, EL2_CNTR
, ECNTR_SAPROM
| thin
);
163 if (inb_el2(dep
, EL2_EA0
) != 0x02 || /* Etherlink II Station address */
164 inb_el2(dep
, EL2_EA1
) != 0x60 || /* MUST be 02:60:8c:xx:xx:xx */
165 inb_el2(dep
, EL2_EA2
) != 0x8C)
166 return 0; /* No Etherlink board at this address */
168 /* Map the 8390 back to lower I/O address range */
169 outb_el2(dep
, EL2_CNTR
, thin
);
171 /* Setup shared memory addressing for 3c503 */
172 dep
->de_linmem
= ((membase
& 0xC0) ? EL2_BASE_0D8000
: EL2_BASE_0C8000
) +
173 ((membase
& 0xA0) ? (EL2_BASE_0CC000
- EL2_BASE_0C8000
) : 0x0000);
174 dep
->de_offset_page
= (EL2_SM_START_PG
* DP_PAGESIZE
);
175 dep
->de_ramsize
= (EL2_SM_STOP_PG
- EL2_SM_START_PG
) * DP_PAGESIZE
;
177 /* (Bad kludge, something Philip needs to look into. -- kjb) */
178 dep
->de_linmem
-= dep
->de_offset_page
;
179 dep
->de_ramsize
+= dep
->de_offset_page
;
181 /* Board initialization and stop functions */
182 dep
->de_initf
= el2_init
;
183 dep
->de_stopf
= el2_stop
;
187 static void milli_delay(unsigned long millis
)
189 tickdelay(MILLIS_TO_TICKS(millis
));
192 #endif /* ENABLE_3C503 */
197 * $PchId: 3c503.c,v 1.3 2003/09/10 15:33:04 philip Exp $