source: mainline/uspace/srv/hw/netif/dp8390/ne2000.c@ 95ff5c4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 95ff5c4 was 8f5e2527, checked in by Martin Decky <martin@…>, 15 years ago

remove unnecessary clutter

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/** @addtogroup ne2k
2 * @{
3 */
4
5/** @file
6 * NE1000 and NE2000 network interface initialization and probe functions implementation.
7 */
8
9#include <stdio.h>
10#include <unistd.h>
11
12#include "dp8390_port.h"
13
14#include "local.h"
15#include "dp8390.h"
16#include "ne2000.h"
17
18/** Number of bytes to transfer.
19 */
20#define N 100
21
22/** Sleeps for the defined millicesonds.
23 * @param[in] millis The number of milliseconds to sleep.
24 */
25#define milli_delay(millis) usleep((millis) * 1000)
26
27/** Type definition of the testing function.
28 */
29_PROTOTYPE(typedef int (*testf_t), (dpeth_t *dep, int pos, u8_t *pat) );
30
31/** First data pattern.
32 */
33u8_t pat0[]= {0x00, 0x00, 0x00, 0x00};
34
35/** Second data pattern.
36 */
37u8_t pat1[]= {0xFF, 0xFF, 0xFF, 0xFF};
38
39/** Third data pattern.
40 */
41u8_t pat2[]= {0xA5, 0x5A, 0x69, 0x96};
42
43/** Fourth data pattern.
44 */
45u8_t pat3[]= {0x96, 0x69, 0x5A, 0xA5};
46
47/** Tests 8 bit NE2000 network interface.
48 * @param[in,out] dep The network interface structure.
49 * @param[in] pos The starting position.
50 * @param[in] pat The data pattern to be written.
51 * @returns True on success.
52 * @returns FALSE otherwise.
53 */
54static int test_8(dpeth_t *dep, int pos, u8_t *pat);
55
56/** Tests 16 bit NE2000 network interface.
57 * @param[in,out] dep The network interface structure.
58 * @param[in] pos The starting position.
59 * @param[in] pat The data pattern to be written.
60 * @returns True on success.
61 * @returns FALSE otherwise.
62 */
63static int test_16(dpeth_t *dep, int pos, u8_t *pat);
64
65/** Stops the NE2000 network interface.
66 * @param[in,out] dep The network interface structure.
67 */
68static void ne_stop(dpeth_t *dep);
69
70/** Initializes the NE2000 network interface.
71 * @param[in,out] dep The network interface structure.
72 */
73void ne_init(struct dpeth *dep);
74
75/*===========================================================================*
76 * ne_probe *
77 *===========================================================================*/
78int ne_probe(dep)
79dpeth_t *dep;
80{
81 int byte;
82 int i;
83 int loc1, loc2;
84 testf_t f;
85
86 dep->de_dp8390_port= dep->de_base_port + NE_DP8390;
87
88 /* We probe for an ne1000 or an ne2000 by testing whether the
89 * on board is reachable through the dp8390. Note that the
90 * ne1000 is an 8bit card and has a memory region distict from
91 * the 16bit ne2000
92 */
93
94 for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++)
95 {
96 /* Reset the ethernet card */
97 byte= inb_ne(dep, NE_RESET);
98 milli_delay(2);
99 outb_ne(dep, NE_RESET, byte);
100 milli_delay(2);
101
102 /* Reset the dp8390 */
103 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
104 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
105 ; /* Do nothing */
106
107 /* Check if the dp8390 is really there */
108 if ((inb_reg0(dep, DP_CR) &(CR_STP|CR_DM_ABORT)) !=
109 (CR_STP|CR_DM_ABORT))
110 {
111 return 0;
112 }
113
114 /* Disable the receiver and init TCR and DCR. */
115 outb_reg0(dep, DP_RCR, RCR_MON);
116 outb_reg0(dep, DP_TCR, TCR_NORMAL);
117 if (dep->de_16bit)
118 {
119 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
120 DCR_BMS);
121 }
122 else
123 {
124 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
125 DCR_BMS);
126 }
127
128 if (dep->de_16bit)
129 {
130 loc1= NE2000_START;
131 loc2= NE2000_START + NE2000_SIZE - 4;
132 f= test_16;
133 }
134 else
135 {
136 loc1= NE1000_START;
137 loc2= NE1000_START + NE1000_SIZE - 4;
138 f= test_8;
139 }
140 if (f(dep, loc1, pat0) && f(dep, loc1, pat1) &&
141 f(dep, loc1, pat2) && f(dep, loc1, pat3) &&
142 f(dep, loc2, pat0) && f(dep, loc2, pat1) &&
143 f(dep, loc2, pat2) && f(dep, loc2, pat3))
144 {
145 /* We don't need a memory segment */
146 dep->de_linmem= 0;
147 if (!dep->de_pci)
148 dep->de_initf= ne_init;
149 dep->de_stopf= ne_stop;
150 return 1;
151 }
152 }
153 return 0;
154}
155
156/*===========================================================================*
157 * ne_init *
158 *===========================================================================*/
159void ne_init(dep)
160dpeth_t *dep;
161{
162 int i;
163 int word, sendq_nr;
164
165 /* Setup a transfer to get the ethernet address. */
166 if (dep->de_16bit)
167 outb_reg0(dep, DP_RBCR0, 6*2);
168 else
169 outb_reg0(dep, DP_RBCR0, 6);
170 outb_reg0(dep, DP_RBCR1, 0);
171 outb_reg0(dep, DP_RSAR0, 0);
172 outb_reg0(dep, DP_RSAR1, 0);
173 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
174
175 for (i= 0; i<6; i++)
176 {
177 if (dep->de_16bit)
178 {
179 word= inw_ne(dep, NE_DATA);
180 dep->de_address.ea_addr[i]= word;
181 }
182 else
183 {
184 dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA);
185 }
186 }
187 dep->de_data_port= dep->de_base_port + NE_DATA;
188 if (dep->de_16bit)
189 {
190 dep->de_ramsize= NE2000_SIZE;
191 dep->de_offset_page= NE2000_START / DP_PAGESIZE;
192 }
193 else
194 {
195 dep->de_ramsize= NE1000_SIZE;
196 dep->de_offset_page= NE1000_START / DP_PAGESIZE;
197 }
198
199 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
200 sendq_nr= dep->de_ramsize / 0x2000;
201 if (sendq_nr < 1)
202 sendq_nr= 1;
203 else if (sendq_nr > SENDQ_NR)
204 sendq_nr= SENDQ_NR;
205 dep->de_sendq_nr= sendq_nr;
206 for (i= 0; i<sendq_nr; i++)
207 {
208 dep->de_sendq[i].sq_sendpage= dep->de_offset_page +
209 i*SENDQ_PAGES;
210 }
211
212 dep->de_startpage= dep->de_offset_page + i*SENDQ_PAGES;
213 dep->de_stoppage= dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE;
214
215 /* Can't override the default IRQ. */
216 dep->de_irq &= ~DEI_DEFAULT;
217
218 if (!debug)
219 {
220 printf("%s: NE%d000 at %#lx:%d\n",
221 dep->de_name, dep->de_16bit ? 2 : 1,
222 dep->de_base_port, dep->de_irq);
223 }
224 else
225 {
226 printf("%s: Novell NE%d000 ethernet card at I/O address "
227 "%#lx, memory size %#lx, irq %d\n",
228 dep->de_name, dep->de_16bit ? 2 : 1,
229 dep->de_base_port, dep->de_ramsize, dep->de_irq);
230 }
231}
232
233/*===========================================================================*
234 * test_8 *
235 *===========================================================================*/
236static int test_8(dep, pos, pat)
237dpeth_t *dep;
238int pos;
239u8_t *pat;
240{
241 u8_t buf[4];
242 int i;
243 int r;
244
245 outb_reg0(dep, DP_ISR, 0xFF);
246
247 /* Setup a transfer to put the pattern. */
248 outb_reg0(dep, DP_RBCR0, 4);
249 outb_reg0(dep, DP_RBCR1, 0);
250 outb_reg0(dep, DP_RSAR0, pos &0xFF);
251 outb_reg0(dep, DP_RSAR1, pos >> 8);
252 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
253
254 for (i= 0; i<4; i++)
255 outb_ne(dep, NE_DATA, pat[i]);
256
257 for (i= 0; i<N; i++)
258 {
259 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
260 break;
261 }
262 if (i == N)
263 {
264 if (debug)
265 {
266 printf("%s: NE1000 remote DMA test failed\n",
267 dep->de_name);
268 }
269 return 0;
270 }
271
272 outb_reg0(dep, DP_RBCR0, 4);
273 outb_reg0(dep, DP_RBCR1, 0);
274 outb_reg0(dep, DP_RSAR0, pos &0xFF);
275 outb_reg0(dep, DP_RSAR1, pos >> 8);
276 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
277
278 for (i= 0; i<4; i++)
279 buf[i]= inb_ne(dep, NE_DATA);
280
281 r= (memcmp(buf, pat, 4) == 0);
282 return r;
283}
284
285/*===========================================================================*
286 * test_16 *
287 *===========================================================================*/
288static int test_16(dep, pos, pat)
289dpeth_t *dep;
290int pos;
291u8_t *pat;
292{
293 u8_t buf[4];
294 int i;
295 int r;
296
297 outb_reg0(dep, DP_ISR, 0xFF);
298
299 /* Setup a transfer to put the pattern. */
300 outb_reg0(dep, DP_RBCR0, 4);
301 outb_reg0(dep, DP_RBCR1, 0);
302 outb_reg0(dep, DP_RSAR0, pos &0xFF);
303 outb_reg0(dep, DP_RSAR1, pos >> 8);
304 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
305
306 for (i= 0; i<4; i += 2)
307 {
308 outw_ne(dep, NE_DATA, *(u16_t *)(pat+i));
309 }
310
311 for (i= 0; i<N; i++)
312 {
313 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
314 break;
315 }
316 if (i == N)
317 {
318 if (debug)
319 {
320 printf("%s: NE2000 remote DMA test failed\n",
321 dep->de_name);
322 }
323 return 0;
324 }
325
326 outb_reg0(dep, DP_RBCR0, 4);
327 outb_reg0(dep, DP_RBCR1, 0);
328 outb_reg0(dep, DP_RSAR0, pos &0xFF);
329 outb_reg0(dep, DP_RSAR1, pos >> 8);
330 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
331
332 for (i= 0; i<4; i += 2)
333 {
334 *(u16_t *)(buf+i)= inw_ne(dep, NE_DATA);
335 }
336
337 r= (memcmp(buf, pat, 4) == 0);
338 return r;
339}
340
341/*===========================================================================*
342 * ne_stop *
343 *===========================================================================*/
344static void ne_stop(dep)
345dpeth_t *dep;
346{
347 int byte;
348
349 /* Reset the ethernet card */
350 byte= inb_ne(dep, NE_RESET);
351 milli_delay(2);
352 outb_ne(dep, NE_RESET, byte);
353}
354
355/** @}
356 */
Note: See TracBrowser for help on using the repository browser.