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 <minix/drivers.h>
16 #include <net/gen/ether.h>
17 #include <net/gen/eth_io.h>
25 extern u32_t system_hz
;
27 #define MILLIS_TO_TICKS(m) (((m)*system_hz/1000)+1)
29 static void el2_init(dpeth_t
*dep
);
30 static void el2_stop(dpeth_t
*dep
);
31 static void milli_delay(unsigned long millis
);
33 /*===========================================================================*
35 *===========================================================================*/
36 static void el2_init(dep
)
39 /* Initalize hardware and data structures. */
44 /* Map the address PROM to lower I/O address range */
45 cntr
= inb_el2(dep
, EL2_CNTR
);
46 outb_el2(dep
, EL2_CNTR
, cntr
| ECNTR_SAPROM
);
48 /* Read station address from PROM */
49 for (ix
= EL2_EA0
; ix
<= EL2_EA5
; ix
+= 1)
50 dep
->de_address
.ea_addr
[ix
] = inb_el2(dep
, ix
);
52 /* Map the 8390 back to lower I/O address range */
53 outb_el2(dep
, EL2_CNTR
, cntr
);
55 /* Enable memory, but turn off interrupts until we are ready */
56 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
58 dep
->de_data_port
= dep
->de_dp8390_port
= dep
->de_base_port
;
59 dep
->de_prog_IO
= 0; /* Programmed I/O not yet available */
61 /* Check width of data bus:
62 * 1. Write 0 to WTS bit. The board will drive it to 1 if it is a
65 * 3. See if it is a 16-bit card
68 outb_el2(dep
, DP_CR
, CR_PS_P0
|CR_DM_ABORT
|CR_STP
);
69 outb_el2(dep
, DP_DCR
, 0);
70 outb_el2(dep
, DP_CR
, CR_PS_P2
|CR_DM_ABORT
|CR_STP
);
71 dep
->de_16bit
= (inb_el2(dep
, DP_DCR
) & DCR_WTS
) != 0;
72 outb_el2(dep
, DP_CR
, CR_PS_P0
|CR_DM_ABORT
|CR_STP
);
74 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
75 sendq_nr
= (dep
->de_ramsize
- dep
->de_offset_page
) / 0x2000;
78 else if (sendq_nr
> SENDQ_NR
)
81 dep
->de_sendq_nr
= sendq_nr
;
82 for (ix
= 0; ix
< sendq_nr
; ix
++)
83 dep
->de_sendq
[ix
].sq_sendpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
85 dep
->de_startpage
= (ix
* SENDQ_PAGES
) + EL2_SM_START_PG
;
86 dep
->de_stoppage
= EL2_SM_STOP_PG
;
88 outb_el2(dep
, EL2_STARTPG
, dep
->de_startpage
);
89 outb_el2(dep
, EL2_STOPPG
, dep
->de_stoppage
);
91 /* Point the vector pointer registers somewhere ?harmless?. */
92 outb_el2(dep
, EL2_VP2
, 0xFF); /* Point at the ROM restart location */
93 outb_el2(dep
, EL2_VP1
, 0xFF); /* 0xFFFF:0000 (from original sources) */
94 outb_el2(dep
, EL2_VP0
, 0x00); /* - What for protected mode? */
96 /* Set interrupt level for 3c503 */
97 irq
= (dep
->de_irq
&= ~DEI_DEFAULT
); /* Strip the default flag. */
98 if (irq
== 9) irq
= 2;
99 if (irq
< 2 || irq
> 5) panic("bad 3c503 irq configuration: %d", irq
);
100 outb_el2(dep
, EL2_IDCFG
, (0x04 << irq
));
102 outb_el2(dep
, EL2_DRQCNT
, 0x08); /* Set burst size to 8 */
103 outb_el2(dep
, EL2_DMAAH
, EL2_SM_START_PG
); /* Put start of TX */
104 outb_el2(dep
, EL2_DMAAL
, 0x00); /* buffer in the GA DMA reg */
106 outb_el2(dep
, EL2_CFGR
, ECFGR_NORM
); /* Enable shared memory */
109 printf("%s: 3c503 at %X:%d:%lX\n",
110 dep
->de_name
, dep
->de_base_port
, dep
->de_irq
,
111 dep
->de_linmem
+ dep
->de_offset_page
);
113 printf("%s: 3Com Etherlink II %sat I/O address 0x%X, "
114 "memory address 0x%lX, irq %d\n",
115 dep
->de_name
, dep
->de_16bit
? "(16-bit) " : "",
117 dep
->de_linmem
+ dep
->de_offset_page
,
122 /*===========================================================================*
124 *===========================================================================*/
125 static void el2_stop(dep
)
128 /* Stops board by disabling interrupts. */
131 printf("%s: stopping Etherlink\n", dep
->de_name
);
133 outb_el2(dep
, EL2_CFGR
, ECFGR_IRQOFF
);
137 /*===========================================================================*
139 *===========================================================================*/
143 /* Probe for the presence of an EtherLink II card. Initialize memory
144 * addressing if card detected.
149 /* Thin ethernet or AUI? */
150 thin
= (dep
->de_linmem
& 1) ? ECNTR_AUI
: ECNTR_THIN
;
152 /* Location registers should have 1 bit set */
153 if (!(iobase
= inb_el2(dep
, EL2_IOBASE
))) return 0;
154 if (!((membase
= inb_el2(dep
, EL2_MEMBASE
)) & 0xF0)) return 0;
155 if ((iobase
& (iobase
- 1)) || (membase
& (membase
- 1))) return 0;
158 outb_el2(dep
, EL2_CNTR
, ECNTR_RESET
| thin
);
160 outb_el2(dep
, EL2_CNTR
, thin
);
163 /* Map the address PROM to lower I/O address range */
164 outb_el2(dep
, EL2_CNTR
, ECNTR_SAPROM
| thin
);
165 if (inb_el2(dep
, EL2_EA0
) != 0x02 || /* Etherlink II Station address */
166 inb_el2(dep
, EL2_EA1
) != 0x60 || /* MUST be 02:60:8c:xx:xx:xx */
167 inb_el2(dep
, EL2_EA2
) != 0x8C)
168 return 0; /* No Etherlink board at this address */
170 /* Map the 8390 back to lower I/O address range */
171 outb_el2(dep
, EL2_CNTR
, thin
);
173 /* Setup shared memory addressing for 3c503 */
174 dep
->de_linmem
= ((membase
& 0xC0) ? EL2_BASE_0D8000
: EL2_BASE_0C8000
) +
175 ((membase
& 0xA0) ? (EL2_BASE_0CC000
- EL2_BASE_0C8000
) : 0x0000);
176 dep
->de_offset_page
= (EL2_SM_START_PG
* DP_PAGESIZE
);
177 dep
->de_ramsize
= (EL2_SM_STOP_PG
- EL2_SM_START_PG
) * DP_PAGESIZE
;
179 /* (Bad kludge, something Philip needs to look into. -- kjb) */
180 dep
->de_linmem
-= dep
->de_offset_page
;
181 dep
->de_ramsize
+= dep
->de_offset_page
;
183 /* Board initialization and stop functions */
184 dep
->de_initf
= el2_init
;
185 dep
->de_stopf
= el2_stop
;
189 static void milli_delay(unsigned long millis
)
191 tickdelay(MILLIS_TO_TICKS(millis
));
194 #endif /* ENABLE_3C503 */
199 * $PchId: 3c503.c,v 1.3 2003/09/10 15:33:04 philip Exp $