add directory net
This commit is contained in:
1
net/tcpip/ne2000/111.source
Normal file
1
net/tcpip/ne2000/111.source
Normal file
@@ -0,0 +1 @@
|
||||
stammt von super.org:/pub/linux
|
||||
368
net/tcpip/ne2000/3c501.c
Normal file
368
net/tcpip/ne2000/3c501.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/* 3c501.c: A 3Com 3c501 ethernet driver for linux. */
|
||||
#include <linux/config.h>
|
||||
#ifdef ETHERLINK1
|
||||
/*
|
||||
Copyright (C) 1992 Donald Becker
|
||||
|
||||
This is alpha test code. No general redistribution is permitted.
|
||||
This is a device driver for the 3Com Etherlink 3c501.
|
||||
Do not purchase this card, even as a joke. It's performance is horrible,
|
||||
and it breaks in many ways.
|
||||
|
||||
The Author may be reached as becker@super.org or
|
||||
C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
|
||||
*/
|
||||
|
||||
/*
|
||||
Braindamage remaining:
|
||||
The 3c501 board.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/segment.h>
|
||||
/* This should be checked for necessity after testing. */
|
||||
#define REALLY_SLOW_IO
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "dev.h"
|
||||
#include "eth.h"
|
||||
#include "timer.h"
|
||||
#include "ip.h"
|
||||
#include "tcp.h"
|
||||
#include "sock.h"
|
||||
#include "arp.h"
|
||||
|
||||
/* These should be in <asm/io.h> someday, borrowed from blk_drv/hd.c. */
|
||||
|
||||
#define port_read_b(port,buf,nr) \
|
||||
__asm__("cld;rep;insb"::"d" (port),"D" (buf),"c" (nr):"cx","di")
|
||||
#define port_write_b(port,buf,nr) \
|
||||
__asm__("cld;rep;outsb"::"d" (port),"S" (buf),"c" (nr):"cx","si")
|
||||
|
||||
#define DEBUG 10 /* use 0 for production, 1 for devel., >2 for debug */
|
||||
|
||||
|
||||
/* Index to functions. */
|
||||
static void el_interrupt(int reg_ptr);
|
||||
static void el_send_packet(struct sk_buff *skb, struct device *dev);
|
||||
static void el_receive(struct device *dev);
|
||||
|
||||
#define EL_NAME "EtherLink 3c501"
|
||||
|
||||
static int el_debug = DEBUG; /* Anything above 5 is wordy death! */
|
||||
static int el_base;
|
||||
static struct device *eldev; /* Only for consistency checking. */
|
||||
|
||||
/* We could put everything in a struct to be malloc()ed per-board, but
|
||||
who would want more than one 3c501?. */
|
||||
static struct { /* This should be stored per-board */
|
||||
char *name;
|
||||
int exists:1; /* perhaps in dev->private. */
|
||||
int open:1;
|
||||
int txing:1; /* Transmit Active, don't confuse the 8390 */
|
||||
int in_interrupt:4;
|
||||
int overruns, rx_errors, tx_errors;
|
||||
} el_status = { "Etherlink I", 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static int collisions; /* Tx collisions this packet */
|
||||
static int tx_pkt_length; /* To reset GP after each collision. */
|
||||
static int runt_packets = 0; /* # of runt packets picked up so far. */
|
||||
/* static int rx_missed = 0; * # of packets we missed. */
|
||||
|
||||
static struct sigaction el_sigaction = { el_interrupt, 0, 0, NULL, };
|
||||
|
||||
#define RX_STATUS (el_base + 0x06)
|
||||
#define TX_STATUS (el_base + 0x07)
|
||||
#define GP_LOW (el_base + 0x08)
|
||||
#define GP_HIGH (el_base + 0x09)
|
||||
#define RX_LOW (el_base + 0x0A)
|
||||
#define RX_HIGH (el_base + 0x0B)
|
||||
#define SAPROM (el_base + 0x0C)
|
||||
#define AX_STATUS (el_base + 0x0E)
|
||||
#define DATAPORT (el_base + 0x0F)
|
||||
#define TX_RDY 0x08 /* In TX_STATUS */
|
||||
|
||||
/* Writes to the ax command register. */
|
||||
#define AX_OFF 0x40 /* Irq off, buffer access on */
|
||||
#define AX_SYS 0x41 /* Load the buffer */
|
||||
#define AX_XMIT 0x45 /* Transmit a packet */
|
||||
#define AX_RX 0x49 /* Receive a packet */
|
||||
#define AX_LOOP 0x4D /* Loopback */
|
||||
|
||||
/* Normal receive mode written to RX_STATUS. We must intr on short packets
|
||||
to avoid bogus rx lockups. */
|
||||
#define RX_NORM 0xA8
|
||||
/* TX_STATUS register. */
|
||||
#define TX_COLLISION 0x02
|
||||
|
||||
/* Open/initialize the board. */
|
||||
static int
|
||||
el_open(struct device *dev)
|
||||
{
|
||||
if ( ! el_status.exists) {
|
||||
printk(EL_NAME ": Opening a non-existent physical device\n");
|
||||
return 1; /* We should have a better error return. */
|
||||
}
|
||||
if (el_debug > 2)
|
||||
printk(EL_NAME ": Doing el_open(%s)...",
|
||||
dev == eldev ? dev->name : " on unknown dev");
|
||||
el_status.txing = 0;
|
||||
el_status.in_interrupt = 0;
|
||||
|
||||
|
||||
outb_p(AX_LOOP, AX_STATUS); /* Aux control, irq and loopback enabled */
|
||||
outb_p(0x00, RX_LOW); /* Set rx packet area to 0. */
|
||||
outb_p(RX_NORM, RX_STATUS); /* Set Rx commands. */
|
||||
outb_p(AX_RX, AX_STATUS); /* Aux control, irq and receive enabled */
|
||||
|
||||
el_status.open = 1;
|
||||
if (el_debug > 2)
|
||||
printk("finished el_open().\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
el_start_xmit(struct sk_buff *skb, struct device *dev)
|
||||
{
|
||||
int axsr;
|
||||
|
||||
if ( ! el_status.exists)
|
||||
return 0; /* We should have a better error return. */
|
||||
if (el_debug > 2)
|
||||
printk(EL_NAME": Doing el_start_xmit(<sk_buff%x>,%s).\n", skb,
|
||||
dev == eldev ? "EtherLink" : "unknown dev");
|
||||
cli();
|
||||
if (el_debug > 4) printk(EL_NAME": interrupts suspended...");
|
||||
axsr = inb_p(AX_STATUS);
|
||||
if (el_status.txing || axsr & 0x01) {
|
||||
if (jiffies - dev->trans_start < 30) {
|
||||
sti();
|
||||
if (el_debug > 2)
|
||||
printk(EL_NAME": transmit deferred, no timeout.\n");
|
||||
return 1;
|
||||
}
|
||||
printk (EL_NAME ": transmit timed out with tx status %#2x.\n",
|
||||
inb(TX_STATUS));
|
||||
}
|
||||
if (el_debug > 4) printk("doing sti()...");
|
||||
sti();
|
||||
if (el_debug > 4) printk("filling in hdr...");
|
||||
|
||||
/* This is new: it means some higher layer thinks we've missed an
|
||||
tx-done interrupt. */
|
||||
if (skb == NULL) {
|
||||
/* Alternative is ei_tx_intr(dev); */
|
||||
el_status.txing = 1;
|
||||
if (dev_tint(NULL, dev) == 0)
|
||||
el_status.txing = 0;
|
||||
return 0;
|
||||
}
|
||||
/* Fill in the ethernet header. */
|
||||
if (!skb->arp && dev->rebuild_header(skb+1, dev)) {
|
||||
skb->dev = dev;
|
||||
arp_queue (skb);
|
||||
if (el_debug > 1)
|
||||
printk(" Exiting from xmit_start() via rebuild header?\n");
|
||||
return 0;
|
||||
}
|
||||
dev->trans_start = jiffies;
|
||||
el_status.txing = 1;
|
||||
outb_p(0x0A, TX_STATUS); /* tx irq on done, collision */
|
||||
el_send_packet(skb, dev);
|
||||
if (skb->free)
|
||||
kfree_skb (skb, FREE_WRITE);
|
||||
if (el_debug > 3)
|
||||
printk(EL_NAME": Returning from el_start_xmit().\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The typical workload of the driver:
|
||||
Handle the ether interface interrupts. */
|
||||
static void
|
||||
el_interrupt(int reg_ptr)
|
||||
{
|
||||
int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
|
||||
int axsr; /* Aux. status reg. */
|
||||
int txsr; /* Tx. status reg. */
|
||||
int rxsr; /* Rx. status reg. */
|
||||
|
||||
if (eldev->irq != irq) {
|
||||
printk (EL_NAME ": irq %d for unknown device\n", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
el_status.in_interrupt++;
|
||||
sti(); /* Turn interrupts back on. */
|
||||
axsr = inb_p(AX_STATUS);
|
||||
txsr = inb_p(TX_STATUS);
|
||||
rxsr = inb_p(RX_STATUS);
|
||||
if (el_debug > 1)
|
||||
printk(EL_NAME": in el_interrupt(), axsr=%#2x, txsr=%#2x, rxsr=%#2x.\n",
|
||||
axsr, txsr, rxsr);
|
||||
if (el_status.in_interrupt > 1) {
|
||||
/* We should probably return here -- the 3c501 glitches the
|
||||
interrupt line when you write to the rx or tx command register. */
|
||||
printk(EL_NAME ": Reentering the interrupt driver!\n");
|
||||
}
|
||||
if (rxsr & 0x08)
|
||||
runt_packets++; /* Just reading rxstatus fixes this. */
|
||||
else if (rxsr & 0x20)
|
||||
el_receive(eldev);
|
||||
else if (txsr & TX_COLLISION) {
|
||||
if (++collisions > 16) {
|
||||
printk(EL_NAME": Transmit failed 16 times, ethernet jammed?\n");
|
||||
/* Turn receiving back on. */
|
||||
el_status.txing = 0;
|
||||
outb_p(0x00, RX_LOW);
|
||||
outb_p(AX_RX, AX_STATUS);
|
||||
} else { /* Retrigger xmit. */
|
||||
int gp_start = 0x800 - tx_pkt_length;
|
||||
outb_p(gp_start, GP_LOW);
|
||||
outb_p(gp_start>>8, GP_HIGH);
|
||||
outb_p(AX_XMIT, AX_STATUS);
|
||||
}
|
||||
} else if (txsr & TX_RDY) {
|
||||
if (dev_tint(NULL, eldev) == 0)
|
||||
el_status.txing = 0; /* We could turn off the tx... */
|
||||
}
|
||||
el_status.in_interrupt--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is stuffed into the dev struct to be called by dev.c:dev_tint(). */
|
||||
static void
|
||||
el_send_packet(struct sk_buff *skb, struct device *dev)
|
||||
{
|
||||
tx_pkt_length = skb->len;
|
||||
collisions = 0;
|
||||
if (el_debug > 3) printk(" el_send_packet(%d)...", tx_pkt_length);
|
||||
/* Should we check for tiny (or huge) lengths here? */
|
||||
if (tx_pkt_length) {
|
||||
int gp_start = 0x800 - tx_pkt_length;
|
||||
unsigned char *buf = (void *)(skb+1);
|
||||
outb_p(AX_OFF, AX_STATUS); /* irq disabled, rx off */
|
||||
outb_p(gp_start, GP_LOW);
|
||||
outb_p(gp_start>>8, GP_HIGH);
|
||||
/* After testing use port_write(), defined above. */
|
||||
for (; gp_start < 0x800; gp_start++)
|
||||
outb_p(*buf++, DATAPORT);
|
||||
outb_p(AX_XMIT, AX_STATUS); /* Trigger xmit. */
|
||||
}
|
||||
}
|
||||
|
||||
/* We have a good packet; well, not really "good", just mostly not broken.
|
||||
We must check everything to see if it is good. */
|
||||
static void
|
||||
el_receive(struct device *dev)
|
||||
{
|
||||
int state = 0, sksize, length;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (el_debug > 2)
|
||||
printk("in el_receive...");
|
||||
/* Painfully read it out of the local memory. */
|
||||
outb_p(AX_SYS, AX_STATUS);
|
||||
length = inb_p(RX_LOW) + (inb_p(RX_HIGH)<<8);
|
||||
if ((length < 60 || length > 1535)) {
|
||||
if (el_debug)
|
||||
printk(EL_NAME": bogus packet, length=%d\n", length);
|
||||
/* We should reset to receive... */
|
||||
return;
|
||||
}
|
||||
sksize = sizeof(struct sk_buff) + length;
|
||||
skb = kmalloc(sksize, GFP_ATOMIC);
|
||||
outb_p(0x00, GP_LOW);
|
||||
outb_p(0x00, GP_HIGH);
|
||||
if (skb != NULL) {
|
||||
unsigned char *buf = (void *)(skb+1);
|
||||
skb->mem_len = sksize;
|
||||
skb->mem_addr = skb;
|
||||
/* After testing use port_read(), defined above. */
|
||||
while (length-- > 0)
|
||||
*buf++ = inb_p(DATAPORT);
|
||||
state = dev_rint((void *)skb, length, IN_SKBUFF, dev);
|
||||
} else if (el_debug) {
|
||||
printk("Couldn't allocate a sk_buff of size %d.\n", sksize);
|
||||
}
|
||||
dev_rint(NULL, 0,0, dev); /* Inform upper level */
|
||||
if (el_debug > 2)
|
||||
printk("done.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
etherlink_init(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
eldev = dev; /* Store for debugging. */
|
||||
el_base = dev->base_addr;
|
||||
|
||||
printk("3c501 probe at %#3.3x: ", el_base);
|
||||
outb(0x00, GP_HIGH);
|
||||
for (i = 0; i < 6; i++) {
|
||||
outb(i, GP_LOW); /* Set station address prom addr */
|
||||
dev->dev_addr[i] = inb(SAPROM); /* Read Station address prom */
|
||||
printk(" %2.2x", dev->dev_addr[i]);
|
||||
}
|
||||
/* Check the first three octets of the S.A. for 3Com's code. */
|
||||
if (dev->dev_addr[0] != 0x02 || dev->dev_addr[1] != 0x60
|
||||
|| dev->dev_addr[2] != 0x8c) {
|
||||
printk(" Etherlink not found.\n", dev->base_addr);
|
||||
el_status.exists = 0;
|
||||
return;
|
||||
}
|
||||
el_status.exists = 1;
|
||||
printk(" Etherlink found.\n");
|
||||
|
||||
/* Initialize the rest of the device structure. Most of these should
|
||||
be in Space.c. */
|
||||
for (i = 0; i < DEV_NUMBUFFS; i++)
|
||||
dev->buffs[i] = NULL;
|
||||
|
||||
dev->hard_header = eth_hard_header;
|
||||
dev->add_arp = eth_add_arp;
|
||||
dev->queue_xmit = dev_queue_xmit;
|
||||
dev->rebuild_header = eth_rebuild_header;
|
||||
dev->type_trans = eth_type_trans;
|
||||
|
||||
dev->send_packet = &el_send_packet;
|
||||
dev->open = &el_open;
|
||||
dev->hard_start_xmit = &el_start_xmit;
|
||||
|
||||
dev->type = ETHER_TYPE;
|
||||
dev->hard_header_len = sizeof (struct enet_header);
|
||||
dev->mtu = 1500; /* eth_mtu */
|
||||
dev->addr_len = ETHER_ADDR_LEN;
|
||||
for (i = 0; i < dev->addr_len; i++) {
|
||||
dev->broadcast[i]=0xff;
|
||||
}
|
||||
/* Turn off interrupts. */
|
||||
|
||||
/* Snarf the assigned interrupt. */
|
||||
{ int irqval = irqaction (dev->irq, &el_sigaction);
|
||||
if (irqval) {
|
||||
printk (" unable to get IRQ%d, error=%d.\n", dev->irq, irqval);
|
||||
return; /* Return failure someday */
|
||||
}
|
||||
}
|
||||
outb(0x8C, 0x0e); /* setup Aux. control reg. */
|
||||
return;
|
||||
}
|
||||
#endif /* ETHERLINK1 */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -DMAX_16M -I/usr/linux-master/net/tcp -c -o 3c501.o 3c501.c"
|
||||
* End:
|
||||
*/
|
||||
1053
net/tcpip/ne2000/3c503.c
Normal file
1053
net/tcpip/ne2000/3c503.c
Normal file
File diff suppressed because it is too large
Load Diff
55
net/tcpip/ne2000/3c503reg.h
Normal file
55
net/tcpip/ne2000/3c503reg.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Definitions for the Etherlink 2. */
|
||||
#include "8390.h"
|
||||
#define EL2H (dev->base_addr + 0x400)
|
||||
#define EL2L (dev->base_addr)
|
||||
|
||||
/* 3Com 3c503 ASIC registers */
|
||||
#define E33G_STARTPG (EL2H+0) /* Start page, must match EN0_STARTPG */
|
||||
#define E33G_STOPPG (EL2H+1) /* Stop page, must match EN0_STOPPG */
|
||||
#define E33G_NBURST (EL2H+2) /* Size of DMA burst before relinquishing bus */
|
||||
#define E33G_IOBASE (EL2H+3) /* Bit coded: where I/O regs are jumpered. */
|
||||
/* (Which you have to know already to read it) */
|
||||
#define E33G_ROMBASE (EL2H+4) /* Bit coded: Where/whether EEPROM&DPRAM exist */
|
||||
#define E33G_GACFR (EL2H+5) /* Config/setup bits for the ASIC GA */
|
||||
#define E33G_CNTRL (EL2H+6) /* Board's main control register */
|
||||
#define E33G_STATUS (EL2H+7) /* Status on completions. */
|
||||
#define E33G_IDCFR (EL2H+8) /* Interrupt/DMA config register */
|
||||
/* (Which IRQ to assert, DMA chan to use) */
|
||||
#define E33G_DMAAH (EL2H+9) /* High byte of DMA address reg */
|
||||
#define E33G_DMAAL (EL2H+10) /* Low byte of DMA address reg */
|
||||
#define E33G_VP2 (EL2H+11) /* Vector pointer - for clearing RAM select */
|
||||
#define E33G_VP1 (EL2H+12) /* on a system reset, to re-enable EPROM. */
|
||||
#define E33G_VP0 (EL2H+13) /* 3Com says set this to Ctrl-Alt-Del handler */
|
||||
#define E33G_FIFOH (EL2H+14) /* FIFO for programmed I/O data moves ... */
|
||||
#define E33G_FIFOL (EL2H+15) /* .. low byte of above. */
|
||||
|
||||
/* Bits in E33G_CNTRL register: */
|
||||
|
||||
#define ECNTRL_RESET (0x01) /* Software reset of the ASIC and 8390 */
|
||||
#define ECNTRL_THIN (0x02) /* Onboard thin-net xcvr enable */
|
||||
#define ECNTRL_SAPROM (0x04) /* Map the station address prom */
|
||||
#define ECNTRL_DBLBFR (0x20) /* FIFO configuration bit */
|
||||
#define ECNTRL_OUTPUT (0x40) /* PC-to-3C503 direction if 1 */
|
||||
#define ECNTRL_INPUT (0x00) /* 3C503-to-PC direction if 0 */
|
||||
#define ECNTRL_START (0x80) /* Start the DMA logic */
|
||||
|
||||
/* Bits in E33G_STATUS register: */
|
||||
|
||||
#define ESTAT_DPRDY (0x80) /* Data port (of FIFO) ready */
|
||||
#define ESTAT_UFLW (0x40) /* Tried to read FIFO when it was empty */
|
||||
#define ESTAT_OFLW (0x20) /* Tried to write FIFO when it was full */
|
||||
#define ESTAT_DTC (0x10) /* Terminal Count from PC bus DMA logic */
|
||||
#define ESTAT_DIP (0x08) /* DMA In Progress */
|
||||
|
||||
/* Bits in E33G_GACFR register: */
|
||||
|
||||
#define EGACFR_NORM (0x49) /* Enable 8K shared mem, no DMA TC int */
|
||||
#define EGACFR_IRQOFF (0xc9) /* Above, and disable 8390 IRQ line */
|
||||
|
||||
/* Shared memory management parameters */
|
||||
|
||||
#define EL2SM_TSTART_PG (0x20) /* First page of TX buffer */
|
||||
#define EL2SM_RSTART_PG (0x26) /* Starting page of RX ring */
|
||||
#define EL2SM_RSTOP_PG (0x40) /* Last page +1 of RX ring */
|
||||
|
||||
/* End of 3C503 parameter definitions */
|
||||
90
net/tcpip/ne2000/8390.h
Normal file
90
net/tcpip/ne2000/8390.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Generic NS8390 register definitions. */
|
||||
/* This file was originally written for the 3c503 driver, but should be
|
||||
usable for most 8390-based network boards.
|
||||
Some of these names are from the clarkson packet drivers. */
|
||||
|
||||
/* Some generic ethernet register configurations. */
|
||||
#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
|
||||
#define E8390_RX_IRQ_MASK 0x5
|
||||
#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
|
||||
#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
|
||||
#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
|
||||
#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
|
||||
|
||||
/* Register accessed at EN_CMD, the 8390 base addr. */
|
||||
#define E8390_STOP 0x01 /* Stop the chip, software reset */
|
||||
#define E8390_START 0x02 /* Start the chip after stopping */
|
||||
#define E8390_TRANS 0x04 /* Transmit a frame */
|
||||
#define E8390_RREAD 0x08 /* Remote read */
|
||||
#define E8390_RWRITE 0x10 /* Remote write */
|
||||
#define E8390_NODMA 0x20 /* No remote DMA used on this card */
|
||||
#define E8390_PAGE0 0x00 /* Select page chip registers */
|
||||
#define E8390_PAGE1 0x40 /* using the two high-order bits */
|
||||
#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
|
||||
|
||||
/* Page 0 register offsets. */
|
||||
#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
|
||||
#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
|
||||
#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
|
||||
#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
|
||||
#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
|
||||
#define EN0_TSR 0x04 /* Transmit status reg RD */
|
||||
#define EN0_TPSR 0x04 /* Transmit starting page WR */
|
||||
#define EN0_NCR 0x05 /* Number of collision reg RD */
|
||||
#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
|
||||
#define EN0_FIFO 0x06 /* FIFO RD */
|
||||
#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
|
||||
#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
|
||||
#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
|
||||
#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
|
||||
#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
|
||||
#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
|
||||
#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
|
||||
#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
|
||||
#define EN0_RSR 0x0c /* rx status reg RD */
|
||||
#define EN0_RXCR 0x0c /* RX configuration reg WR */
|
||||
#define EN0_TXCR 0x0d /* TX configuration reg WR */
|
||||
#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
|
||||
#define EN0_DCFG 0x0e /* Data configuration reg WR */
|
||||
#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
|
||||
#define EN0_IMR 0x0f /* Interrupt mask reg WR */
|
||||
#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
|
||||
|
||||
/* Bits in EN0_ISR - Interrupt status register */
|
||||
#define ENISR_RX 0x01 /* Receiver, no error */
|
||||
#define ENISR_TX 0x02 /* Transmitter, no error */
|
||||
#define ENISR_RX_ERR 0x04 /* Receiver, with error */
|
||||
#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
|
||||
#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
|
||||
#define ENISR_COUNTERS 0x20 /* Counters need emptying */
|
||||
#define ENISR_RDC 0x40 /* remote dma complete */
|
||||
#define ENISR_RESET 0x80 /* Reset completed */
|
||||
#define ENISR_ALL 0x3f /* Interrupts we will enable */
|
||||
|
||||
/* Bits in EN0_DCFG - Data config register */
|
||||
#define ENDCFG_WTS 0x01 /* word transfer mode selection */
|
||||
|
||||
/* Page 1 register offsets. */
|
||||
#define EN1_PHYS 0x01 /* This board's physical enet addr RD WR */
|
||||
#define EN1_CURPAG 0x07 /* Current memory page RD WR */
|
||||
#define EN1_MULT 0x08 /* Multicast filter mask array (8 bytes) RD WR */
|
||||
|
||||
/* Bits in received packet status byte and EN0_RSR*/
|
||||
#define ENRSR_RXOK 0x01 /* Received a good packet */
|
||||
#define ENRSR_CRC 0x02 /* CRC error */
|
||||
#define ENRSR_FAE 0x04 /* frame alignment error */
|
||||
#define ENRSR_FO 0x08 /* FIFO overrun */
|
||||
#define ENRSR_MPA 0x10 /* missed pkt */
|
||||
#define ENRSR_PHY 0x20 /* physical/multicase address */
|
||||
#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
|
||||
#define ENRSR_DEF 0x80 /* deferring */
|
||||
|
||||
/* Transmitted packet status, EN0_TSR. */
|
||||
#define ENTSR_PTX 0x01 /* Packet transmitted without error */
|
||||
|
||||
/* The per-packet-header format. */
|
||||
struct e8390_pkt_hdr {
|
||||
unsigned char status; /* status */
|
||||
unsigned char next; /* pointer to next packet. */
|
||||
unsigned short count; /* header + packet lenght in bytes */
|
||||
};
|
||||
86
net/tcpip/ne2000/README
Normal file
86
net/tcpip/ne2000/README
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
Directory: ~ftp/pub/linux/
|
||||
|
||||
WARNING -- read the bugs section at the end of this file before getting
|
||||
the ethernet board driver!!!
|
||||
|
||||
Files:
|
||||
README This file, updated Tuesday Nov. 24, 1992 18:34.
|
||||
3c501.c The 3c501 ethernet driver source
|
||||
3c503.c The 3c503, 3c503/16, NE1000 and NE2000 ethernet driver source.
|
||||
3c503reg.h Definitions specific to the 3c503
|
||||
8390.h Generic definitions for the NS8390 chip.
|
||||
Space.c Added the table entries for the new ethernet drivers.
|
||||
This file is modified from the 0.98.4 release.
|
||||
|
||||
Image A pre-built Linux 0.98.4 kernel with MathEmu, no SCSI, mount
|
||||
patch, serial patch, CapsLck mapped to Cntrl, and the
|
||||
3c503 and NE2000 ethernet drivers. This kernel usually has
|
||||
massive ethernet debugging turned on (debugging the kernel
|
||||
and setting ei_debug = 0 and el_debug = 0 will turn it off)
|
||||
and this version may not really work. Also the address and
|
||||
IRQ settings are hard-coded for most ethercards. Making your
|
||||
own kernel is usually a much better choice.
|
||||
|
||||
linux-0.98.3-E If it exists, the last Image file that worked OK.
|
||||
|
||||
|
||||
Directions:
|
||||
|
||||
You might want to rename "3c503.c" to "ne2000.c".
|
||||
|
||||
Put the files (3c503.c, 3c503reg.h, 8390.h, and Space.c) into linux/net/tcp/.
|
||||
Space.c is the only tricky one -- it overwrites the old Space.c, and
|
||||
you'll need to edit it to add your IRQ and base address.
|
||||
|
||||
Next add 3c503.o to to linux/net/tcp/Makefile
|
||||
tcpip.o: ... 3c503.o
|
||||
|
||||
Edit linux/include/linux/config.h and/or config.site.h and insert the following
|
||||
(see below for other details).
|
||||
#undef CONFIG_DISTRIBUTION /* Use config.site.h instead. */
|
||||
#define EI8390 0x300 /* Then these should be in config.site.h */
|
||||
#define EI8390IRQ 5 /* Not used yet, edit Space.c instead. */
|
||||
#define EI_DEBUG 2
|
||||
|
||||
Make and install your new kernel.
|
||||
|
||||
To actually use this driver you must get the TCP/IP package and edit
|
||||
your /usr/etc/inet/rc.net file to config device "eth_if" instead of
|
||||
"eth0" (the WD8003).
|
||||
|
||||
BUGS
|
||||
None know right now. I haven't tested the NS8390 overrun code -- it
|
||||
worked OK the last time I had other bugs to trigger it, but I've
|
||||
changed it since.
|
||||
|
||||
Two errors in some versions of the 8390/83901/83902 may not
|
||||
be handled correctly: the first is a bug where the RX status bytes
|
||||
is missing from the header -- I try to recover first rather than
|
||||
resetting the chip (which I do afterwards).
|
||||
|
||||
The second is the 8390 problem with writes to the ethercard
|
||||
RAM: the first write may be corrupted if you don't do a read
|
||||
first -- I've never seen this corruption happen, but it may
|
||||
just be masked by higher level protocols.
|
||||
I have put in the read-first code, but it's a frequent
|
||||
source of problems... The timing is really tricky.
|
||||
|
||||
The 3c501 driver isn't complete. This card severely brain-damaged
|
||||
anyway -- you won't notice the performance diffence when it does work.
|
||||
|
||||
Please send me email if you do try out the drivers, even if you don't
|
||||
encounter bugs.
|
||||
|
||||
Important defines
|
||||
|
||||
EI_DEBUG Set to the desired numeric debugging level. Use 3 or
|
||||
greater when actively debugging a problem, '1' for a
|
||||
casual interest in what's going on, and '0' for normal
|
||||
use. (Most of the debugging stuff has been taken out recently,
|
||||
so this won't have much effect.)
|
||||
EI8390 Define (probably in config.site.h) this to the base address
|
||||
of your ethernet card. You will also have to set the base
|
||||
address and irq in net/tcp/Space.c.
|
||||
ETHERLINK1 Define this to the base address of a 3c501 card. You will
|
||||
also have to set the base address and irq in net/tcp/Space.c.
|
||||
113
net/tcpip/ne2000/Space.c
Normal file
113
net/tcpip/ne2000/Space.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Space.c */
|
||||
/* Holds initial configuration information for devices. */
|
||||
#include "dev.h"
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
#ifdef ETHERLINK1
|
||||
extern void etherlink_init(struct device *);
|
||||
|
||||
static struct device el_dev = {
|
||||
"if3c501",
|
||||
0, 0, 0, 0, /* memory rx_end, rx_start, end, start are autoconfiged. */
|
||||
ETHERLINK1, 9, 0,0,0,0,0, /* base i/o address, irq, and flags. */
|
||||
NULL, etherlink_init, 0, {NULL}, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, {0,}, {0,}, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef EI8390
|
||||
extern void ethif_init(struct device *);
|
||||
|
||||
static struct device el3c503_dev = {
|
||||
"eth_if",
|
||||
0, 0, 0, 0, /* memory rx_end, rx_start, end, start are autoconfiged. */
|
||||
0x300, 5, 0,0,0,0,0, /* base i/o address, irq, and flags. */
|
||||
#ifdef ETHERLINK1
|
||||
&el_dev,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
ethif_init, 0, {NULL}, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, 0, 0, 0, {0,}, {0,}, 0
|
||||
};
|
||||
#endif
|
||||
extern void wd8003_init(struct device *);
|
||||
|
||||
static struct device wd8003_dev =
|
||||
{
|
||||
"eth0",
|
||||
0xd2000, /* recv memory end. */
|
||||
0xd0600, /* recv memory start. */
|
||||
0xd2000, /* memory end. */
|
||||
0xd0000, /* memory start. */
|
||||
0x280, /* base i/o address. */
|
||||
5, /* irq */
|
||||
0,0,0,0,0, /* flags */
|
||||
#ifdef EI8390
|
||||
&el3c503_dev, /* next device */
|
||||
#elif defined(ETHERLINK1)
|
||||
&el_dev, /* next device */
|
||||
#else
|
||||
NULL, /* next device */
|
||||
#endif
|
||||
wd8003_init,
|
||||
/* wd8003_init should set up the rest. */
|
||||
0, /* trans start. */
|
||||
{NULL}, /* buffs */
|
||||
NULL, /* backlog */
|
||||
NULL, /* open */
|
||||
NULL, /* stop */
|
||||
NULL, /* hard_start_xmit */
|
||||
NULL, /* hard_header */
|
||||
NULL, /* add arp */
|
||||
NULL, /* queue xmit */
|
||||
NULL, /* rebuild header */
|
||||
NULL, /* type_trans */
|
||||
NULL, /* send_packet */
|
||||
NULL, /* private */
|
||||
0, /* type. */
|
||||
0, /* hard_header_len */
|
||||
0, /* mtu */
|
||||
{0,}, /* broadcast address */
|
||||
{0,}, /* device address */
|
||||
0 /* addr len */
|
||||
};
|
||||
|
||||
extern void loopback_init(struct device *dev);
|
||||
|
||||
static struct device loopback_dev =
|
||||
{
|
||||
"loopback",
|
||||
-1, /* recv memory end. */
|
||||
0x0, /* recv memory start. */
|
||||
-1, /* memory end. */
|
||||
0, /* memory start. */
|
||||
0, /* base i/o address. */
|
||||
0, /* irq */
|
||||
0,0,1,0,0, /* flags */
|
||||
&wd8003_dev, /* next device */
|
||||
loopback_init,
|
||||
/* loopback_init should set up the rest. */
|
||||
0, /* trans start. */
|
||||
{NULL}, /* buffs */
|
||||
NULL, /* backlog */
|
||||
NULL, /* open */
|
||||
NULL, /* stop */
|
||||
NULL, /* hard_start_xmit */
|
||||
NULL, /* hard_header */
|
||||
NULL, /* add arp */
|
||||
NULL, /* queue xmit */
|
||||
NULL, /* rebuild header */
|
||||
NULL, /* type_trans */
|
||||
NULL, /* send_packet */
|
||||
NULL, /* private */
|
||||
0, /* type. */
|
||||
0, /* hard_header_len */
|
||||
0, /* mtu */
|
||||
{0,}, /* broadcast address */
|
||||
{0,}, /* device address */
|
||||
0 /* addr len */
|
||||
};
|
||||
|
||||
struct device *dev_base = &loopback_dev;
|
||||
Reference in New Issue
Block a user