2
* Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
* * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
6
* * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
7
* * Any deviations from these conditions require written permission from the copyright holder in advance
12
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
13
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
* 2009 ported to HelenOS, Lukas Mejdrech
32
* NE1000 and NE2000 network interface initialization and probe functions implementation.
38
#include "dp8390_port.h"
43
Driver for the ne2000 ethernet cards. This file contains only the ne2000
44
specific code, the rest is in dp8390.c
46
Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
49
//#include "../drivers.h"
51
//#include <net/gen/ether.h>
52
//#include <net/gen/eth_io.h>
63
/** Number of bytes to transfer.
67
//#define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1)
69
/** Sleeps for the defined millicesonds.
70
* @param[in] millis The number of milliseconds to sleep.
72
#define milli_delay( millis ) usleep(( millis ) * 1000 )
74
/** Type definition of the testing function.
76
_PROTOTYPE( typedef int (*testf_t), (dpeth_t *dep, int pos, u8_t *pat) );
78
/** First data pattern.
80
u8_t pat0[]= { 0x00, 0x00, 0x00, 0x00 };
82
/** Second data pattern.
84
u8_t pat1[]= { 0xFF, 0xFF, 0xFF, 0xFF };
86
/** Third data pattern.
88
u8_t pat2[]= { 0xA5, 0x5A, 0x69, 0x96 };
90
/** Fourth data pattern.
92
u8_t pat3[]= { 0x96, 0x69, 0x5A, 0xA5 };
94
/** Tests 8 bit NE2000 network interface.
95
* @param[in,out] dep The network interface structure.
96
* @param[in] pos The starting position.
97
* @param[in] pat The data pattern to be written.
98
* @returns True on success.
99
* @returns FALSE otherwise.
101
static int test_8(dpeth_t *dep, int pos, u8_t *pat);
103
/** Tests 16 bit NE2000 network interface.
104
* @param[in,out] dep The network interface structure.
105
* @param[in] pos The starting position.
106
* @param[in] pat The data pattern to be written.
107
* @returns True on success.
108
* @returns FALSE otherwise.
110
static int test_16(dpeth_t *dep, int pos, u8_t *pat);
112
/** Stops the NE2000 network interface.
113
* @param[in,out] dep The network interface structure.
115
static void ne_stop(dpeth_t *dep);
116
//_PROTOTYPE( static void milli_delay, (unsigned long millis) );
118
/** Initializes the NE2000 network interface.
119
* @param[in,out] dep The network interface structure.
121
void ne_init(struct dpeth *dep);
123
/*===========================================================================*
125
*===========================================================================*/
134
dep->de_dp8390_port= dep->de_base_port + NE_DP8390;
136
/* We probe for an ne1000 or an ne2000 by testing whether the
137
* on board is reachable through the dp8390. Note that the
138
* ne1000 is an 8bit card and has a memory region distict from
142
for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++)
144
/* Reset the ethernet card */
145
byte= inb_ne(dep, NE_RESET);
147
outb_ne(dep, NE_RESET, byte);
150
/* Reset the dp8390 */
151
outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
152
for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
155
/* Check if the dp8390 is really there */
156
if ((inb_reg0(dep, DP_CR) & (CR_STP|CR_DM_ABORT)) !=
157
(CR_STP|CR_DM_ABORT))
162
/* Disable the receiver and init TCR and DCR. */
163
outb_reg0(dep, DP_RCR, RCR_MON);
164
outb_reg0(dep, DP_TCR, TCR_NORMAL);
167
outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
172
outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
179
loc2= NE2000_START + NE2000_SIZE - 4;
185
loc2= NE1000_START + NE1000_SIZE - 4;
188
if (f(dep, loc1, pat0) && f(dep, loc1, pat1) &&
189
f(dep, loc1, pat2) && f(dep, loc1, pat3) &&
190
f(dep, loc2, pat0) && f(dep, loc2, pat1) &&
191
f(dep, loc2, pat2) && f(dep, loc2, pat3))
193
/* We don't need a memory segment */
196
dep->de_initf= ne_init;
197
dep->de_stopf= ne_stop;
205
/*===========================================================================*
207
*===========================================================================*/
214
/* Setup a transfer to get the ethernet address. */
216
outb_reg0(dep, DP_RBCR0, 6*2);
218
outb_reg0(dep, DP_RBCR0, 6);
219
outb_reg0(dep, DP_RBCR1, 0);
220
outb_reg0(dep, DP_RSAR0, 0);
221
outb_reg0(dep, DP_RSAR1, 0);
222
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
228
word= inw_ne(dep, NE_DATA);
229
dep->de_address.ea_addr[i]= word;
233
dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA);
236
dep->de_data_port= dep->de_base_port + NE_DATA;
239
dep->de_ramsize= NE2000_SIZE;
240
dep->de_offset_page= NE2000_START / DP_PAGESIZE;
244
dep->de_ramsize= NE1000_SIZE;
245
dep->de_offset_page= NE1000_START / DP_PAGESIZE;
248
/* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
249
sendq_nr= dep->de_ramsize / 0x2000;
252
else if (sendq_nr > SENDQ_NR)
254
dep->de_sendq_nr= sendq_nr;
255
for (i= 0; i<sendq_nr; i++)
257
dep->de_sendq[i].sq_sendpage= dep->de_offset_page +
261
dep->de_startpage= dep->de_offset_page + i*SENDQ_PAGES;
262
dep->de_stoppage= dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE;
264
/* Can't override the default IRQ. */
265
dep->de_irq &= ~DEI_DEFAULT;
269
printf("%s: NE%d000 at %X:%d\n",
270
dep->de_name, dep->de_16bit ? 2 : 1,
271
dep->de_base_port, dep->de_irq);
275
printf("%s: Novell NE%d000 ethernet card at I/O address "
276
"0x%X, memory size 0x%X, irq %d\n",
277
dep->de_name, dep->de_16bit ? 2 : 1,
278
dep->de_base_port, dep->de_ramsize, dep->de_irq);
282
/*===========================================================================*
284
*===========================================================================*/
285
static int test_8(dep, pos, pat)
294
outb_reg0(dep, DP_ISR, 0xFF);
296
/* Setup a transfer to put the pattern. */
297
outb_reg0(dep, DP_RBCR0, 4);
298
outb_reg0(dep, DP_RBCR1, 0);
299
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
300
outb_reg0(dep, DP_RSAR1, pos >> 8);
301
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
304
outb_ne(dep, NE_DATA, pat[i]);
308
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
315
printf("%s: NE1000 remote DMA test failed\n",
321
outb_reg0(dep, DP_RBCR0, 4);
322
outb_reg0(dep, DP_RBCR1, 0);
323
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
324
outb_reg0(dep, DP_RSAR1, pos >> 8);
325
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
328
buf[i]= inb_ne(dep, NE_DATA);
330
r= (memcmp(buf, pat, 4) == 0);
334
/*===========================================================================*
336
*===========================================================================*/
337
static int test_16(dep, pos, pat)
346
outb_reg0(dep, DP_ISR, 0xFF);
348
/* Setup a transfer to put the pattern. */
349
outb_reg0(dep, DP_RBCR0, 4);
350
outb_reg0(dep, DP_RBCR1, 0);
351
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
352
outb_reg0(dep, DP_RSAR1, pos >> 8);
353
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
355
for (i= 0; i<4; i += 2)
357
outw_ne(dep, NE_DATA, *(u16_t *)(pat+i));
362
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
369
printf("%s: NE2000 remote DMA test failed\n",
375
outb_reg0(dep, DP_RBCR0, 4);
376
outb_reg0(dep, DP_RBCR1, 0);
377
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
378
outb_reg0(dep, DP_RSAR1, pos >> 8);
379
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
381
for (i= 0; i<4; i += 2)
383
*(u16_t *)(buf+i)= inw_ne(dep, NE_DATA);
386
r= (memcmp(buf, pat, 4) == 0);
390
/*===========================================================================*
392
*===========================================================================*/
393
static void ne_stop(dep)
398
/* Reset the ethernet card */
399
byte= inb_ne(dep, NE_RESET);
401
outb_ne(dep, NE_RESET, byte);
404
static void milli_delay(unsigned long millis)
406
tickdelay(MILLIS_TO_TICKS(millis));
409
#endif /* ENABLE_NE2000 */
412
* $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $