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>
11 #include <minix/netdriver.h>
21 extern u32_t system_hz
;
23 #define MILLIS_TO_TICKS(m) (((m)*system_hz/1000)+1)
25 typedef int(*testf_t
) (dpeth_t
*dep
, int pos
, u8_t
*pat
);
27 static u8_t pat0
[]= { 0x00, 0x00, 0x00, 0x00 };
28 static u8_t pat1
[]= { 0xFF, 0xFF, 0xFF, 0xFF };
29 static u8_t pat2
[]= { 0xA5, 0x5A, 0x69, 0x96 };
30 static u8_t pat3
[]= { 0x96, 0x69, 0x5A, 0xA5 };
32 static int test_8(dpeth_t
*dep
, int pos
, u8_t
*pat
);
33 static int test_16(dpeth_t
*dep
, int pos
, u8_t
*pat
);
34 static void ne_stop(dpeth_t
*dep
);
36 /*===========================================================================*
38 *===========================================================================*/
39 int ne_probe(dpeth_t
*dep
)
46 dep
->de_dp8390_port
= dep
->de_base_port
+ NE_DP8390
;
48 /* We probe for an ne1000 or an ne2000 by testing whether the
49 * on board is reachable through the dp8390. Note that the
50 * ne1000 is an 8bit card and has a memory region distict from
54 for (dep
->de_16bit
= 0; dep
->de_16bit
< 2; dep
->de_16bit
++)
56 /* Reset the ethernet card */
57 byte
= inb_ne(dep
, NE_RESET
);
59 outb_ne(dep
, NE_RESET
, byte
);
62 /* Reset the dp8390 */
63 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
64 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RST
) == 0); i
++)
67 /* Check if the dp8390 is really there */
68 if ((inb_reg0(dep
, DP_CR
) & (CR_STP
|CR_DM_ABORT
)) !=
74 /* Disable the receiver and init TCR and DCR. */
75 outb_reg0(dep
, DP_RCR
, RCR_MON
);
76 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
79 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
|
84 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
|
91 loc2
= NE2000_START
+ NE2000_SIZE
- 4;
97 loc2
= NE1000_START
+ NE1000_SIZE
- 4;
100 if (f(dep
, loc1
, pat0
) && f(dep
, loc1
, pat1
) &&
101 f(dep
, loc1
, pat2
) && f(dep
, loc1
, pat3
) &&
102 f(dep
, loc2
, pat0
) && f(dep
, loc2
, pat1
) &&
103 f(dep
, loc2
, pat2
) && f(dep
, loc2
, pat3
))
105 /* We don't need a memory segment */
108 dep
->de_initf
= ne_init
;
109 dep
->de_stopf
= ne_stop
;
117 /*===========================================================================*
119 *===========================================================================*/
126 /* Setup a transfer to get the ethernet address. */
128 outb_reg0(dep
, DP_RBCR0
, 6*2);
130 outb_reg0(dep
, DP_RBCR0
, 6);
131 outb_reg0(dep
, DP_RBCR1
, 0);
132 outb_reg0(dep
, DP_RSAR0
, 0);
133 outb_reg0(dep
, DP_RSAR1
, 0);
134 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
140 word
= inw_ne(dep
, NE_DATA
);
141 dep
->de_address
.na_addr
[i
]= word
;
145 dep
->de_address
.na_addr
[i
] = inb_ne(dep
, NE_DATA
);
148 dep
->de_data_port
= dep
->de_base_port
+ NE_DATA
;
151 dep
->de_ramsize
= NE2000_SIZE
;
152 dep
->de_offset_page
= NE2000_START
/ DP_PAGESIZE
;
156 dep
->de_ramsize
= NE1000_SIZE
;
157 dep
->de_offset_page
= NE1000_START
/ DP_PAGESIZE
;
160 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
161 sendq_nr
= dep
->de_ramsize
/ 0x2000;
164 else if (sendq_nr
> SENDQ_NR
)
166 dep
->de_sendq_nr
= sendq_nr
;
167 for (i
= 0; i
<sendq_nr
; i
++)
169 dep
->de_sendq
[i
].sq_sendpage
= dep
->de_offset_page
+
173 dep
->de_startpage
= dep
->de_offset_page
+ i
*SENDQ_PAGES
;
174 dep
->de_stoppage
= dep
->de_offset_page
+ dep
->de_ramsize
/ DP_PAGESIZE
;
176 /* Can't override the default IRQ. */
177 dep
->de_irq
&= ~DEI_DEFAULT
;
181 printf("%s: NE%d000 at %X:%d\n",
182 netdriver_name(), dep
->de_16bit
? 2 : 1,
183 dep
->de_base_port
, dep
->de_irq
);
187 printf("%s: Novell NE%d000 ethernet card at I/O address "
188 "0x%X, memory size 0x%X, irq %d\n",
189 netdriver_name(), dep
->de_16bit
? 2 : 1,
190 dep
->de_base_port
, dep
->de_ramsize
, dep
->de_irq
);
194 /*===========================================================================*
196 *===========================================================================*/
197 static int test_8(dep
, pos
, pat
)
206 outb_reg0(dep
, DP_ISR
, 0xFF);
208 /* Setup a transfer to put the pattern. */
209 outb_reg0(dep
, DP_RBCR0
, 4);
210 outb_reg0(dep
, DP_RBCR1
, 0);
211 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
212 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
213 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
216 outb_ne(dep
, NE_DATA
, pat
[i
]);
220 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
227 printf("%s: NE1000 remote DMA test failed\n",
233 outb_reg0(dep
, DP_RBCR0
, 4);
234 outb_reg0(dep
, DP_RBCR1
, 0);
235 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
236 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
237 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
240 buf
[i
]= inb_ne(dep
, NE_DATA
);
242 r
= (memcmp(buf
, pat
, 4) == 0);
246 /*===========================================================================*
248 *===========================================================================*/
249 static int test_16(dep
, pos
, pat
)
258 outb_reg0(dep
, DP_ISR
, 0xFF);
260 /* Setup a transfer to put the pattern. */
261 outb_reg0(dep
, DP_RBCR0
, 4);
262 outb_reg0(dep
, DP_RBCR1
, 0);
263 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
264 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
265 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
267 for (i
= 0; i
<4; i
+= 2)
269 outw_ne(dep
, NE_DATA
, *(u16_t
*)(pat
+i
));
274 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
281 printf("%s: NE2000 remote DMA test failed\n",
287 outb_reg0(dep
, DP_RBCR0
, 4);
288 outb_reg0(dep
, DP_RBCR1
, 0);
289 outb_reg0(dep
, DP_RSAR0
, pos
& 0xFF);
290 outb_reg0(dep
, DP_RSAR1
, pos
>> 8);
291 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
293 for (i
= 0; i
<4; i
+= 2)
295 *(u16_t
*)(buf
+i
)= inw_ne(dep
, NE_DATA
);
298 r
= (memcmp(buf
, pat
, 4) == 0);
302 /*===========================================================================*
304 *===========================================================================*/
305 static void ne_stop(dep
)
310 /* Reset the ethernet card */
311 byte
= inb_ne(dep
, NE_RESET
);
313 outb_ne(dep
, NE_RESET
, byte
);
316 #endif /* ENABLE_NE2000 */
319 * $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $