4 Driver for the ne2000 ethernet cards. This file contains only the ne2000
5 specific code, the rest is in dp8390.c
7 Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
10 #include <minix/drivers.h>
12 #include <net/gen/ether.h>
13 #include <net/gen/eth_io.h>
26 extern u32_t system_hz
;
28 #define MILLIS_TO_TICKS(m) (((m)*system_hz/1000)+1)
30 typedef int(*testf_t
) (dpeth_t
*dep
, int pos
, u8_t
*pat
);
32 static u8_t pat0
[]= { 0x00, 0x00, 0x00, 0x00 };
33 static u8_t pat1
[]= { 0xFF, 0xFF, 0xFF, 0xFF };
34 static u8_t pat2
[]= { 0xA5, 0x5A, 0x69, 0x96 };
35 static u8_t pat3
[]= { 0x96, 0x69, 0x5A, 0xA5 };
37 static int test_8(dpeth_t
*dep
, int pos
, u8_t
*pat
);
38 static int test_16(dpeth_t
*dep
, int pos
, u8_t
*pat
);
39 static void ne_stop(dpeth_t
*dep
);
40 static void milli_delay(unsigned long millis
);
42 /*===========================================================================*
44 *===========================================================================*/
45 int ne_probe(dpeth_t
*dep
)
52 dep
->de_dp8390_port
= dep
->de_base_port
+ NE_DP8390
;
54 /* We probe for an ne1000 or an ne2000 by testing whether the
55 * on board is reachable through the dp8390. Note that the
56 * ne1000 is an 8bit card and has a memory region distict from
60 for (dep
->de_16bit
= 0; dep
->de_16bit
< 2; dep
->de_16bit
++)
62 /* Reset the ethernet card */
63 byte
= inb_ne(dep
, NE_RESET
);
65 outb_ne(dep
, NE_RESET
, byte
);
68 /* Reset the dp8390 */
69 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
70 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RST
) == 0); i
++)
73 /* Check if the dp8390 is really there */
74 if ((inb_reg0(dep
, DP_CR
) & (CR_STP
|CR_DM_ABORT
)) !=
80 /* Disable the receiver and init TCR and DCR. */
81 outb_reg0(dep
, DP_RCR
, RCR_MON
);
82 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
85 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
|
90 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
|
97 loc2
= NE2000_START
+ NE2000_SIZE
- 4;
103 loc2
= NE1000_START
+ NE1000_SIZE
- 4;
106 if (f(dep
, loc1
, pat0
) && f(dep
, loc1
, pat1
) &&
107 f(dep
, loc1
, pat2
) && f(dep
, loc1
, pat3
) &&
108 f(dep
, loc2
, pat0
) && f(dep
, loc2
, pat1
) &&
109 f(dep
, loc2
, pat2
) && f(dep
, loc2
, pat3
))
111 /* We don't need a memory segment */
114 dep
->de_initf
= ne_init
;
115 dep
->de_stopf
= ne_stop
;
123 /*===========================================================================*
125 *===========================================================================*/
132 /* Setup a transfer to get the ethernet address. */
134 outb_reg0(dep
, DP_RBCR0
, 6*2);
136 outb_reg0(dep
, DP_RBCR0
, 6);
137 outb_reg0(dep
, DP_RBCR1
, 0);
138 outb_reg0(dep
, DP_RSAR0
, 0);
139 outb_reg0(dep
, DP_RSAR1
, 0);
140 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
146 word
= inw_ne(dep
, NE_DATA
);
147 dep
->de_address
.ea_addr
[i
]= word
;
151 dep
->de_address
.ea_addr
[i
] = inb_ne(dep
, NE_DATA
);
154 dep
->de_data_port
= dep
->de_base_port
+ NE_DATA
;
157 dep
->de_ramsize
= NE2000_SIZE
;
158 dep
->de_offset_page
= NE2000_START
/ DP_PAGESIZE
;
162 dep
->de_ramsize
= NE1000_SIZE
;
163 dep
->de_offset_page
= NE1000_START
/ DP_PAGESIZE
;
166 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
167 sendq_nr
= dep
->de_ramsize
/ 0x2000;
170 else if (sendq_nr
> SENDQ_NR
)
172 dep
->de_sendq_nr
= sendq_nr
;
173 for (i
= 0; i
<sendq_nr
; i
++)
175 dep
->de_sendq
[i
].sq_sendpage
= dep
->de_offset_page
+
179 dep
->de_startpage
= dep
->de_offset_page
+ i
*SENDQ_PAGES
;
180 dep
->de_stoppage
= dep
->de_offset_page
+ dep
->de_ramsize
/ DP_PAGESIZE
;
182 /* Can't override the default IRQ. */
183 dep
->de_irq
&= ~DEI_DEFAULT
;
187 printf("%s: NE%d000 at %X:%d\n",
188 dep
->de_name
, dep
->de_16bit
? 2 : 1,
189 dep
->de_base_port
, dep
->de_irq
);
193 printf("%s: Novell NE%d000 ethernet card at I/O address "
194 "0x%X, memory size 0x%X, irq %d\n",
195 dep
->de_name
, dep
->de_16bit
? 2 : 1,
196 dep
->de_base_port
, dep
->de_ramsize
, dep
->de_irq
);
200 /*===========================================================================*
202 *===========================================================================*/
203 static int test_8(dep
, pos
, pat
)
212 outb_reg0(dep
, DP_ISR
, 0xFF);
214 /* Setup a transfer to put the pattern. */
215 outb_reg0(dep
, DP_RBCR0
, 4);
216 outb_reg0(dep
, DP_RBCR1
, 0);
217 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
218 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
219 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
222 outb_ne(dep
, NE_DATA
, pat
[i
]);
226 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
233 printf("%s: NE1000 remote DMA test failed\n",
239 outb_reg0(dep
, DP_RBCR0
, 4);
240 outb_reg0(dep
, DP_RBCR1
, 0);
241 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
242 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
243 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
246 buf
[i
]= inb_ne(dep
, NE_DATA
);
248 r
= (memcmp(buf
, pat
, 4) == 0);
252 /*===========================================================================*
254 *===========================================================================*/
255 static int test_16(dep
, pos
, pat
)
264 outb_reg0(dep
, DP_ISR
, 0xFF);
266 /* Setup a transfer to put the pattern. */
267 outb_reg0(dep
, DP_RBCR0
, 4);
268 outb_reg0(dep
, DP_RBCR1
, 0);
269 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
270 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
271 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
273 for (i
= 0; i
<4; i
+= 2)
275 outw_ne(dep
, NE_DATA
, *(u16_t
*)(pat
+i
));
280 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
287 printf("%s: NE2000 remote DMA test failed\n",
293 outb_reg0(dep
, DP_RBCR0
, 4);
294 outb_reg0(dep
, DP_RBCR1
, 0);
295 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
296 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
297 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
299 for (i
= 0; i
<4; i
+= 2)
301 *(u16_t
*)(buf
+i
)= inw_ne(dep
, NE_DATA
);
304 r
= (memcmp(buf
, pat
, 4) == 0);
308 /*===========================================================================*
310 *===========================================================================*/
311 static void ne_stop(dep
)
316 /* Reset the ethernet card */
317 byte
= inb_ne(dep
, NE_RESET
);
319 outb_ne(dep
, NE_RESET
, byte
);
322 static void milli_delay(unsigned long millis
)
324 tickdelay(MILLIS_TO_TICKS(millis
));
327 #endif /* ENABLE_NE2000 */
330 * $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $