add directory Linux-0.97

This commit is contained in:
gohigh
2024-02-19 00:21:05 -05:00
parent cf5dadaed5
commit 265896c4ae
91 changed files with 2648 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
*** linux/kernel/sys_call.S Fri May 15 08:56:45 1992
--- linux/kernel/sys_call.S.~1~ Sun May 10 13:59:58 1992
***************
*** 87,97 ****
.globl _double_fault,_coprocessor_segment_overrun
.globl _invalid_TSS,_segment_not_present,_stack_segment
.globl _general_protection,_irq13,_reserved
.globl _alignment_check,_page_fault
.globl _keyboard_interrupt,_hd_interrupt
! .globl _IRQ3_interrupt,_IRQ4_interrupt,_irq5_interrupt
#define SAVE_ALL \
cld; \
push %gs; \
push %fs; \
--- 87,97 ----
.globl _double_fault,_coprocessor_segment_overrun
.globl _invalid_TSS,_segment_not_present,_stack_segment
.globl _general_protection,_irq13,_reserved
.globl _alignment_check,_page_fault
.globl _keyboard_interrupt,_hd_interrupt
! .globl _IRQ3_interrupt,_IRQ4_interrupt
#define SAVE_ALL \
cld; \
push %gs; \
push %fs; \
***************
*** 265,285 ****
pushl $-1
SAVE_ALL
ACK_FIRST(0x10)
sti
call _do_IRQ4
- cli
- UNBLK_FIRST(0x10)
- jmp ret_from_sys_call
-
- .align 2
- _irq5_interrupt:
- pushl $-1
- SAVE_ALL
- ACK_FIRST(0x10)
- sti
- call _wd8003_interrupt
cli
UNBLK_FIRST(0x10)
jmp ret_from_sys_call
.align 2
--- 265,274 ----
*** linux/init/main.c Fri May 15 09:01:02 1992
--- linux/init/main.c.~1~ Sat May 2 19:29:31 1992
***************
*** 173,183 ****
sched_init();
buffer_init(buffer_memory_end);
hd_init();
floppy_init();
sock_init();
- wd8003_init();
sti();
#ifdef CONFIG_SCSI
scsi_dev_init();
#endif
move_to_user_mode();
--- 173,182 ----

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
#define ETHERMTU 2048
#define ETHER_MIN_LEN 64
#define ETHER_ADDR_LEN 6
/* this must be a power of 2 */
#define ETH_BUFF_SIZE 0x2000
/* some ioctls. */
#define ETH_START 0
#define ETH_STOP 1
typedef void * (*callback)(void *);
#define ETHERTYPE_ARP 0x806
#define ETHERTYPE_IP 0x800
#define NET16(x) (((x)<<8)|(x)&0xff)
struct enet_header
{
unsigned char saddr[ETHER_ADDR_LEN];
unsigned char daddr[ETHER_ADDR_LEN];
unsigned short type;
};
#define ETHER_HEADER sizeof(enet_header)

View File

@@ -0,0 +1,789 @@
/* we.c an wd8003 ethernet driver for linux. */
/*
Copyright (C) 1992 Ross Biro
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
/* The bsd386 version was used as an example in order to write this
code */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/tty.h>
#include <sys/types.h>
/* #include <linux/driver.h>*/
#include <linux/eth.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/memory.h>
#include <errno.h>
#include <fcntl.h>
#include "wereg.h"
static unsigned char interrupt_mask;
/* format of status byte.
bit
0 start
1 open
2 transmitter in use */
#define START 1
#define OPEN 2
#define TRS_BUSY 4
static unsigned int status;
struct driver {
struct task_struct **d_rwait;
struct task_struct **d_wwait;
} builtin_dev;
static unsigned char we_addr[ETHER_ADDR_LEN];
static struct driver *mdev;
static int recv_errors=0;
static int trans_errors=0;
static int spackets=0;
static int collisions=0;
static struct task_struct *wwait_ptr=NULL;
static struct task_struct *rwait_ptr=NULL;
extern void irq5_interrupt(void);
static inline int
min(int a, int b)
{
if (a<b) return (a);
return (b);
}
static inline int
max(int a, int b)
{
if (a>b) return (a);
return (b);
}
struct bufhead
{
long len;
};
struct buf
{
short head, tail;
unsigned char *memory;
};
static unsigned char rbuf_c[ETH_BUFF_SIZE];
static unsigned char wbuf_c[ETH_BUFF_SIZE];
static struct buf Buf[]=
{
{0,0,rbuf_c},
{0,0,wbuf_c}
};
static struct buf *rbuf = Buf;
static struct buf *wbuf = Buf+1;
static inline int
buf_free(struct buf *b)
{
if (b->head >= b->tail)
return(ETH_BUFF_SIZE-b->head +b->tail);
else
return (b->tail-b->head);
}
static inline void
clear_buf(struct buf *b)
{
b->head=0;
b->tail=0;
}
static inline int
copy_to_buf(struct buf *b, void *vptr, long len,
void *end_buff, callback split)
{
struct bufhead *head;
long end;
long bend;
long total=0;
unsigned char *ptr;
/* check to see if there is enough space. */
if (len+3*sizeof(*head) >=
buf_free(b))
{
return(0);
}
head = (struct bufhead *)(b->memory + b->head);
head->len = len;
b->head += sizeof (*head);
ptr = vptr;
while (len > 0)
{
end = ETH_BUFF_SIZE - b->head;
bend = (unsigned long)end_buff - (unsigned long)ptr;
if (bend <= 0)
{
ptr =split(ptr);
bend = (unsigned long)end_buff - (unsigned long)ptr;
}
/* copy up to the end of a buffer. */
end = min(end,bend);
end = min (end,len);
if (end < 0)
{
printk ("copy_to_buf end=%d\n",end);
end=0;
}
(void) memcpy (b->memory+b->head, ptr,end);
ptr += end;
len -= end;
b->head+=end;
total += end;
if (b->head >= ETH_BUFF_SIZE)
b->head = 0;
}
if (b->head >= ETH_BUFF_SIZE-2*sizeof(*head))
b->head = 0;
return (total);
}
static inline int
copy_to_buf_fs(struct buf *b, void *vptr, unsigned long len)
{
struct bufhead *head;
unsigned long end;
unsigned char *ptr;
/* check to see if there is enough space. */
if (len+3*sizeof(*head) >=
buf_free(b))
{
printk ("copy_to_buf_fs failed %d\n",len);
return(0);
}
head = (struct bufhead *)(b->memory + b->head);
head->len = len;
b->head += sizeof (*head);
end = ETH_BUFF_SIZE - b->head;
ptr = vptr;
/* copy up to the end of the buffer. */
end = min(end,len);
memcpy_fromfs (b->memory+b->head, ptr,end);
ptr += end;
len -= end;
b->head+=end;
if (b->head >= ETH_BUFF_SIZE)
b->head = 0;
/* now copy the rest. */
memcpy_fromfs (b->memory+b->head, ptr, len);
b->head += len;
if (b->head >= ETH_BUFF_SIZE-2*sizeof(*head))
b->head = 0;
return (end + len);
}
static inline int
copy_from_buf(struct buf *b, void *vptr, long len)
{
struct bufhead *head;
long end;
unsigned char *ptr;
/* check to see if there is anything in the buffer. */
if (b->head == b->tail)
return(0);
head = (struct bufhead *)(b->memory + b->tail);
b->tail += sizeof (*head);
len = min (head->len,len);
end = ETH_BUFF_SIZE - b->tail;
ptr = vptr;
/* copy up to the end of the buffer. */
end = min(end,len);
if (end < 0)
{
printk ("copy from buf end = %d\n",end);
end = 0;
}
(void) memcpy (ptr, b->memory+b->tail, end);
ptr += end;
len -= end;
b->tail+=end;
if (b->tail >= ETH_BUFF_SIZE)
b->tail = 0;
/* now copy the rest. */
(void )memcpy (ptr, b->memory+b->tail, len);
/* now forget about any leftover stuff. */
b->tail += head->len - end;
if (b->tail >= ETH_BUFF_SIZE)
b->tail-=ETH_BUFF_SIZE;
if (b->tail >= ETH_BUFF_SIZE-2*sizeof(*head))
b->tail = 0;
return (end + len);
}
static inline int
copy_from_buf_fs(struct buf *b, void *vptr, unsigned long len)
{
struct bufhead *head;
unsigned long end;
unsigned char *ptr;
/* check to see if there is anything in the buffer. */
if (b->head == b->tail)
return(0);
head = (struct bufhead *)(b->memory + b->tail);
b->tail += sizeof (*head);
len = min (head->len,len);
end = ETH_BUFF_SIZE - b->tail;
ptr = vptr;
/* copy up to the end of the buffer. */
end = min(end,len);
memcpy_tofs (ptr, b->memory+b->tail, end);
ptr += end;
len -= end;
b->tail+=end;
if (b->tail >= ETH_BUFF_SIZE)
b->tail = 0;
/* now copy the rest. */
if (len != 0)
{
memcpy_tofs (ptr,b->memory+b->tail, len);
}
/* now forget about any leftover stuff. */
b->tail += head->len - end;
if (b->tail >= ETH_BUFF_SIZE)
b->tail-=ETH_BUFF_SIZE;
if (b->tail >= ETH_BUFF_SIZE-2*sizeof(*head))
b->tail = 0;
return (end + len);
}
void
wd_stop(void)
{
unsigned char cmd;
cli();
cmd = inb_p(WD_COMM);
cmd |= CSTOP;
cmd &= ~(CSTART|CPAGE);
outb_p(cmd, WD_COMM);
outb(0,WD_IMR);
sti();
interrupt_mask = 0;
status &= ~START;
}
static inline void
wd_start(void)
{
unsigned char cmd;
interrupt_mask=RECV_MASK;
cli();
cmd = inb_p(WD_COMM);
cmd &= ~(CSTOP|CPAGE);
cmd |= CSTART;
outb_p(cmd, WD_COMM);
outb(interrupt_mask,WD_IMR);
sti();
status |= START;
}
int wd8003_close(struct inode *inode, struct file *filep)
{
int minor;
minor = MINOR(inode->i_rdev);
if (minor != 0) return (-ENODEV);
wd_stop();
status = 0;
return (0);
}
int
wd8003_open(struct inode *inode, struct file *filep)
{
unsigned char cmd;
int i;
int minor;
minor = MINOR(inode->i_rdev);
if (minor != 0) return (-ENODEV);
if (status & OPEN) return (-EBUSY);
/* clear the buffs. */
clear_buf(rbuf);
clear_buf(wbuf);
/* we probably don't want to be interrupted here. */
cli();
/* This section of code is mostly copied from the bsd driver which is
mostly copied from somewhere else. */
cmd=inb_p(WD_COMM);
cmd|=CSTOP;
cmd &= ~(CSTART|CPAGE);
outb_p(cmd, WD_COMM);
outb_p(0, WD_IMR);
sti();
outb_p(WD_DCONFIG,WD_DCR);
/*Zero the remote byte count. */
outb_p(0, WD_RBY0);
outb_p(0, WD_RBY1);
outb_p(WD_MCONFIG,WD_RCC);
outb_p(WD_TCONFIG,WD_TRC);
/* Set the transmit page */
outb_p(0,WD_TRPG);
outb_p(WD_TXBS,WD_PSTRT);
outb_p(WD_MAX_PAGES,WD_PSTOP);
outb_p(WD_TXBS,WD_BNDR);
/* clear interrupt status. */
outb_p(0xff,WD_ISR);
/* we don't want no stinking interrupts. */
outb_p(0 ,WD_IMR);
cmd|=1<<CPAGE_SHIFT;
outb_p(cmd,WD_COMM);
/* set the either address. */
for (i=0; i < ETHER_ADDR_LEN; i++)
{
outb_p(we_addr[i],WD_PAR0+i);
}
/* set the multicast address. */
for (i=0; i < ETHER_ADDR_LEN; i++)
{
outb_p(0xff,WD_MAR0+i);
}
outb_p(WD_TXBS,WD_CUR);
cmd&=~(CPAGE|CRDMA);
cmd|= 4<<CRDMA_SHIFT;
outb_p(cmd, WD_COMM);
outb_p(WD_RCONFIG,WD_RCC);
status = OPEN;
wd_start();
return (0);
}
static void *
wd_callback(void *ptr)
{
if (ptr >= (void *)WD_BUFFEND)
return ((void *)(WD_MEM + (WD_TXBS<<8)));
return (ptr);
}
/*This routine just copies the stuff from the ring into the
buffer. It remove the ring headers, and makes sure that
everything fits. */
static inline int
wdget(struct wd_ring *ring)
{
unsigned char *fptr;
unsigned long len;
int i;
fptr = (unsigned char *)(ring +1);
len = ring->count-4;
for (i =0; i < ETHER_ADDR_LEN; i++)
if (fptr[i] != we_addr[i])
{
return (0);
}
if (copy_to_buf (rbuf, fptr, len,(void *) WD_BUFFEND, wd_callback)
!= len) return (1);
return (0);
}
/* wd_strans attempts to start a transmission. It is
only called when the transmit buffer is free. */
static inline void
wd_strans(void)
{
unsigned long len;
unsigned char cmd;
len = copy_from_buf(wbuf,(void *)WD_MEM,WD_TXBS<<8);
/* see if there is anything to send. */
if (len == 0)
{
interrupt_mask &= ~TRANS_MASK;
status &= ~(TRS_BUSY);
return;
}
status |= TRS_BUSY;
/* now we need to set up the card info. */
len=max(len, ETHER_MIN_LEN);
cmd=inb_p(WD_COMM);
outb_p(len&0xff,WD_TB0);
outb_p(len>>8,WD_TB1);
cmd |= CTRANS;
outb(cmd,WD_COMM);
interrupt_mask |= TRANS_MASK;
}
int
rw_wd8003(int rw, unsigned minor, char *buf, int count, unsigned short flags )
{
unsigned long len=0;
unsigned char cmd;
if (minor != 0) return (-ENODEV);
if (rw == READ)
{
while (len == 0)
{
verify_area(buf, count);
len = copy_from_buf_fs(rbuf,buf, count);
if (len == 0)
{
clear_buf(rbuf);
if ( flags & O_NONBLOCK)
{
return (-EAGAIN);
}
interruptible_sleep_on(mdev->d_rwait);
}
}
}
else
{
while (len == 0)
{
verify_area(buf, count);
len = copy_to_buf_fs(wbuf,buf, count);
if (len == 0)
{
clear_buf(wbuf);
if ( flags & O_NONBLOCK)
{
return (-EAGAIN);
}
interruptible_sleep_on(mdev->d_wwait);
}
}
/* see if we need to start the transmission. */
if (!(status & TRS_BUSY))
{
cli();
cmd = inb_p(WD_COMM);
cmd &= ~(CPAGE);
outb_p(cmd, WD_COMM);
outb_p(0, WD_IMR);
sti();
wd_strans();
outb_p(interrupt_mask,WD_IMR);
}
}
return (len);
}
static int
wd8003_read (struct inode *inode, struct file *file, char *buf, int count)
{
return (rw_wd8003(READ, MINOR(inode->i_rdev), buf, count, file->f_flags));
}
static int
wd8003_write (struct inode *inode, struct file *file, char *buf, int count)
{
return (rw_wd8003(WRITE, MINOR(inode->i_rdev), buf, count, file->f_flags));
}
/* This routine handles the packet recieved interrupt. */
/* It is called with interrupts enabled, but with
the wd card configured not to return interrupts. */
/* It is enterred with page one selected, and it must
leave that way. */
/* I think there might be an infinite loop here, so I'm putting
in a maximum number of packets we can look at at once.
Someone with good docs can try to fix this one. */
static inline void
wd_rcv(void)
{
unsigned char bnd;
unsigned char cur;
unsigned char cmd;
struct wd_ring *ring;
int count = 0;
cmd=inb_p(WD_COMM);
bnd=inb_p(WD_BNDR);
cmd |= 1<< CPAGE_SHIFT;
outb_p (cmd, WD_COMM);
cur=inb(WD_CUR);
while (bnd != cur)
{
count++;
if (count > 10)
{
bnd=cur;
break;
}
ring = (struct wd_ring *)(WD_MEM + (bnd << 8));
if (ring->count > 34 && ring->count <= ETHERMTU+104)
{
if (wdget(ring))
{
/* we have a buffer overflow. */
/* reset the bndry and the current. */
cmd |= CSTOP;
outb_p(cmd,WD_COMM);
outb_p(WD_MCONFIG,WD_RCC);
outb_p(WD_TXBS,WD_BNDR);
cmd |= 1 <<CPAGE_SHIFT;
outb_p(cmd, WD_COMM);
outb_p(WD_TXBS,WD_CUR);
cmd &= ~(CSTOP|CPAGE);
cmd |= CSTART;
outb_p(cmd, WD_COMM);
outb_p(WD_RCONFIG,WD_RCC);
return;
}
wake_up(mdev->d_rwait);
}
else
{
bnd=cur;
break;
}
/* compute a new boundary. */
if (ring->next >= WD_MAX_PAGES)
{
bnd= ring->next - WD_MAX_PAGES + WD_TXBS;
}
else
{
bnd=ring->next;
if (bnd <= WD_TXBS)
{
bnd += WD_TXBS;
}
}
/* tell the card about the new boundary. */
cmd &=~(CPAGE);
outb_p(cmd,WD_COMM);
if (bnd != WD_TXBS)
outb_p(bnd-1,WD_BNDR);
else
outb_p(WD_MAX_PAGES-1,WD_BNDR);
cmd |= 1<< CPAGE_SHIFT;
outb_p(cmd,WD_COMM);
/* update our copy of cur. */
cur = inb_p(WD_CUR);
}
/* we have to make sure we reset the i/o page. */
cmd &= ~(CPAGE);
outb_p(cmd,WD_COMM);
if (bnd != WD_TXBS)
outb_p(bnd-1, WD_BNDR);
else
outb_p(WD_MAX_PAGES-1, WD_BNDR);
}
/* This get's the transmit interrupts.
It assume command page 0 is set, and
returns with command page 0 set. */
static inline void
wd_trs(void)
{
/*update the stats. */
spackets++;
collisions += inb(WD_TB0);
/* attempt to start a transmission. */
wd_strans();
/* wakeup anything that was sleeping on writes. */
if (*(mdev->d_wwait)) wake_up(mdev->d_wwait);
}
/* Currently this routine sometimes gets stuck in an infinite
loop. So I'm putting in a counter. When the routine
has looped 10 times, I'm just resetting everything,
then leaving. Someone who has real docs can fix this. */
void
wd8003_interrupt(void)
{
unsigned char cmd;
unsigned char isr;
int count=0;
/* Acknowledge the interrupt. */
outb_p(0x20,0x20);
/* now we can be interrupted, but since we have
done nothing yet it doesn't matter. */
/*we don't want to be interrupted after we
read the command byte. */
cli();
cmd=inb_p(WD_COMM);
cmd&=~(CPAGE);
outb_p(cmd,WD_COMM);
isr=inb(WD_ISR);
do {
outb_p(0,WD_IMR);
/* we have turned the wd8003 interrupts off, so we can reenable
them at the processor level. */
sti();
/* From now on other devices will be able to interrupt us, so
some care is probably required. */
count++;
if (count > 10)
{
printk ("wd8003:Warning loop broken\n");
/* we are caught in a loop, reset everything that we can think
of and return. This needs to be fixed. */
cmd |= CSTOP;
outb_p(cmd,WD_COMM);
outb_p(WD_IMEM|0x80,WD_CTL);
outb_p(WD_IMEM,WD_CTL);
outb_p(WD_MCONFIG,WD_RCC);
outb_p(WD_TXBS,WD_BNDR);
cmd |= 1 <<CPAGE_SHIFT;
outb_p(cmd, WD_COMM);
outb_p(WD_TXBS,WD_CUR);
cmd &= ~(CSTOP|CPAGE);
cmd |= CSTART;
outb_p(cmd, WD_COMM);
outb_p(WD_RCONFIG,WD_RCC);
outb_p (0,WD_ISR);
outb_p(interrupt_mask,WD_IMR);
return;
}
/* see what to do about the interrupt. */
if (isr & IRCV) /* got a packet. */
wd_rcv();
if (isr & ITRS) /* finished sending a packet. */
wd_trs();
if (isr & IRCE) /* recieve error */
{
/* reading these registers might clear the error condition. */
collisions += inb(WD_TB0);
(void) inb(WD_RCC);
(void) inb(WD_DCR);
recv_errors++;
}
if (isr & ITRE) /* transmit error. */
{
collisions += inb(WD_TB0);
trans_errors++;
}
/* acknowledge the intterupt. */
outb_p(isr, WD_ISR);
/* Now we will try to reenable onboard interrupts. */
cli();
outb_p(interrupt_mask,WD_IMR);
isr=inb_p(WD_ISR)&interrupt_mask;
} while (isr != 0);
sti();
}
int
wd8003_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned int arg)
{
int dev;
dev=MINOR(inode->i_rdev);
if (dev != 0) return (-ENODEV);
switch (cmd)
{
case ETH_START:
wd_start();
return (0);
case ETH_STOP:
wd_stop();
return(0);
default:
return (-EINVAL);
}
}
static struct file_operations wd_fops =
{
NULL,
wd8003_read,
wd8003_write,
NULL,
NULL,
wd8003_ioctl,
wd8003_open,
wd8003_close
};
void
wd8003_init(struct driver *dev)
{
unsigned char csum;
int i;
chrdev_fops[10]=&wd_fops;
mdev = &builtin_dev;
mdev->d_rwait = &rwait_ptr;
mdev->d_wwait = &wwait_ptr;
csum = 0;
for (i = 0; i < 8; i++)
{
csum += inb_p(WD_ROM+i);
}
if (csum != WD_CHECK)
{
printk ("Warning no WD8003 board installed.\n");
/* make sure no one can attempt to open the device. */
status = OPEN;
return;
}
/* mapin the interface memory. */
outb(WD_IMEM,WD_CTL);
/* clear the interface memory */
for (i = 0; i < WD_MEMSIZE; i++)
{
((unsigned char *)WD_MEM)[i] = 0;
if (((unsigned char *)WD_MEM)[i] != 0)
{
printk ("WD Memory error.\n");
status = OPEN;
}
}
/* print the initialization message, and the
ethernet address. */
printk ("WD8003 ethernet Address ");
for (i = 0; i <ETHER_ADDR_LEN; i++)
{
we_addr[i]=inb_p(WD_ROM+i);
printk ("%2.2X ",we_addr[i]);
}
printk ("\n");
status = 0;
set_trap_gate (0x25, irq5_interrupt);
outb(inb_p(0x21)&0xDF, 0x21);
}

View File

@@ -0,0 +1,131 @@
/* wereg.h */
/*
Copyright (C) 1992 Ross Biro
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
/* This is based on if_wereg.h from bsd386 */
struct wd_ring
{
unsigned char status; /* status */
/* format of status
bit
0 packet ok
1 crc error
2 frame alignment error
3 fifo overrun
*/
#define STRECVD 0xf1
unsigned char next; /* pointer to next packet. */
unsigned short count; /*packet lenght in bytes + 4 */
};
/* Format of command register.
bits
0 stop
1 start
2 transmit packet
3-5 Remote DMA command
6-7 Page Select */
#define CSTOP 0x1
#define CSTART 0x2
#define CTRANS 0x4
#define CRDMA 0x38
#define CRDMA_SHIFT 3
#define CPAGE 0xc0
#define CPAGE_SHIFT 6
/* interrupt status defenitions
bits
0 Recv.
1 Transmit
2 RcvErr
3 Transmit Err
4 Overwrite warning
5 Counter overflow
6 Remote DMA complete
7 Reset Status */
#define IRCV 0x1
#define ITRS 0x2
#define IRCE 0x4
#define ITRE 0x8
/* transmit status format
bits
0 Packet transmitted ok.
1 Non Deferred transmition
2 Transmit collied
3 Transmit aborted
4 Carrier Sense Lost
5 Fifo Underrun
6 CD Heartbeat
7 Out of Window Collision */
#define TROK 0x1
#define TRAB 0x4
/* Some ID stuff */
#define WD_ID1 0x03
#define WD_ID2 0x05
#define WD_CHECK 0xff
#define WD_PAGE 256 /* page size in bytes. */
#define WD_TXBS 6 /* size of transmit buffer in pages. */
#define WD_MAX_PAGES 32 /* Number of pages off ram on card (8k) */
#define WD_NIC 16 /* i/o base offset to NIC */
/* Some configuration stuff. */
/* where the memory is mapped in. */
#define WD_MEM 0xd0000
#define WD_BUFFEND 0xd4000
#define WD_MEMSIZE (WD_BUFFEND-WD_MEM)
#define WD_BASE 0x280
#define TRANS_MASK 0xa
#define RECV_MASK 0x5
#define WD_DCONFIG 0x48
#define WD_RCONFIG 0x4
#define WD_MCONFIG 0x20
#define WD_TCONFIG 0x0
#define WD_IMEM (((WD_MEM>>13) & 0x3f)|0x40)
/* WD registers. */
#define WD_ROM (WD_BASE+8)
#define WD_CTL (WD_BASE+0)
/* WD NIC register offsets */
#define WD_COMM (WD_BASE+WD_NIC+0x00) /* command register */
#define WD_PSTRT (WD_BASE+WD_NIC+0x01) /* page start register */
#define WD_PSTOP (WD_BASE+WD_NIC+0x02) /* page stop register */
#define WD_BNDR (WD_BASE+WD_NIC+0x03) /* Boundary Pointer */
#define WD_TRST (WD_BASE+WD_NIC+0x04) /* Transmit Status */
#define WD_TRPG (WD_BASE+WD_NIC+0x04) /* Transmit Page */
#define WD_TB0 (WD_BASE+WD_NIC+0x05) /* Transmit byte count, low */
#define WD_TB1 (WD_BASE+WD_NIC+0x06) /* Transmit byte count, high */
#define WD_ISR (WD_BASE+WD_NIC+0x07) /* Interrupt status register */
#define WD_RBY0 (WD_BASE+WD_NIC+0x0a) /* remote byte count low. */
#define WD_RBY1 (WD_BASE+WD_NIC+0x0b) /* remote byte count high. */
#define WD_RCC (WD_BASE+WD_NIC+0x0c) /* receive configuration */
#define WD_TRC (WD_BASE+WD_NIC+0x0d) /* transmit configuration */
#define WD_DCR (WD_BASE+WD_NIC+0x0e) /* data configuration */
#define WD_IMR (WD_BASE+WD_NIC+0x0f) /* Interrupt Mask register. */
#define WD_PAR0 (WD_BASE+WD_NIC+0x01)
#define WD_CUR (WD_BASE+WD_NIC+0x07)
#define WD_MAR0 (WD_BASE+WD_NIC+0x08)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.