sbin/newfs_msdos: sync with NetBSD-8
[minix3.git] / minix / drivers / net / dp8390 / ne2000.c
blob65c541b7374984cfed4e013c023a80c0ed2664aa
1 /*
2 ne2000.c
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>
8 */
10 #include <minix/drivers.h>
11 #include <minix/netdriver.h>
13 #include "local.h"
14 #include "dp8390.h"
15 #include "ne2000.h"
17 #if ENABLE_NE2000
19 #define N 100
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 /*===========================================================================*
37 * ne_probe *
38 *===========================================================================*/
39 int ne_probe(dpeth_t *dep)
41 int byte;
42 int i;
43 int loc1, loc2;
44 testf_t f;
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
51 * the 16bit ne2000
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);
58 micro_delay(2000);
59 outb_ne(dep, NE_RESET, byte);
60 micro_delay(2000);
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++)
65 ; /* Do nothing */
67 /* Check if the dp8390 is really there */
68 if ((inb_reg0(dep, DP_CR) & (CR_STP|CR_DM_ABORT)) !=
69 (CR_STP|CR_DM_ABORT))
71 return 0;
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);
77 if (dep->de_16bit)
79 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
80 DCR_BMS);
82 else
84 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
85 DCR_BMS);
88 if (dep->de_16bit)
90 loc1= NE2000_START;
91 loc2= NE2000_START + NE2000_SIZE - 4;
92 f= test_16;
94 else
96 loc1= NE1000_START;
97 loc2= NE1000_START + NE1000_SIZE - 4;
98 f= test_8;
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 */
106 dep->de_linmem= 0;
107 if (!dep->de_pci)
108 dep->de_initf= ne_init;
109 dep->de_stopf= ne_stop;
110 dep->de_prog_IO= 1;
111 return 1;
114 return 0;
117 /*===========================================================================*
118 * ne_init *
119 *===========================================================================*/
120 void ne_init(dep)
121 dpeth_t *dep;
123 int i;
124 int word, sendq_nr;
126 /* Setup a transfer to get the ethernet address. */
127 if (dep->de_16bit)
128 outb_reg0(dep, DP_RBCR0, 6*2);
129 else
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);
136 for (i= 0; i<6; i++)
138 if (dep->de_16bit)
140 word= inw_ne(dep, NE_DATA);
141 dep->de_address.na_addr[i]= word;
143 else
145 dep->de_address.na_addr[i] = inb_ne(dep, NE_DATA);
148 dep->de_data_port= dep->de_base_port + NE_DATA;
149 if (dep->de_16bit)
151 dep->de_ramsize= NE2000_SIZE;
152 dep->de_offset_page= NE2000_START / DP_PAGESIZE;
154 else
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;
162 if (sendq_nr < 1)
163 sendq_nr= 1;
164 else if (sendq_nr > SENDQ_NR)
165 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 +
170 i*SENDQ_PAGES;
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;
179 if (!debug)
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);
185 else
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 /*===========================================================================*
195 * test_8 *
196 *===========================================================================*/
197 static int test_8(dep, pos, pat)
198 dpeth_t *dep;
199 int pos;
200 u8_t *pat;
202 u8_t buf[4];
203 int i;
204 int r;
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);
215 for (i= 0; i<4; i++)
216 outb_ne(dep, NE_DATA, pat[i]);
218 for (i= 0; i<N; i++)
220 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
221 break;
223 if (i == N)
225 if (debug)
227 printf("%s: NE1000 remote DMA test failed\n",
228 netdriver_name());
230 return 0;
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);
239 for (i= 0; i<4; i++)
240 buf[i]= inb_ne(dep, NE_DATA);
242 r= (memcmp(buf, pat, 4) == 0);
243 return r;
246 /*===========================================================================*
247 * test_16 *
248 *===========================================================================*/
249 static int test_16(dep, pos, pat)
250 dpeth_t *dep;
251 int pos;
252 u8_t *pat;
254 u8_t buf[4];
255 int i;
256 int r;
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));
272 for (i= 0; i<N; i++)
274 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
275 break;
277 if (i == N)
279 if (debug)
281 printf("%s: NE2000 remote DMA test failed\n",
282 netdriver_name());
284 return 0;
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);
299 return r;
302 /*===========================================================================*
303 * ne_stop *
304 *===========================================================================*/
305 static void ne_stop(dep)
306 dpeth_t *dep;
308 int byte;
310 /* Reset the ethernet card */
311 byte= inb_ne(dep, NE_RESET);
312 micro_delay(2000);
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 $